This patch adjusts std_malloc() to handle small
allocations (smaller than 16-bytes) more efficiently.
More specifically instead of allocating whole page
for each such request, adjusted std_malloc() uses memory
pool adequate to requested size and thus saves almost
entire page (4K) of memory.

Fixes #1011

Signed-off-by: Waldemar Kozaczuk <[email protected]>
---
 core/mempool.cc           |  5 +++--
 modules/tests/Makefile    |  2 +-
 tests/tst-small-malloc.cc | 45 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+), 3 deletions(-)
 create mode 100644 tests/tst-small-malloc.cc

diff --git a/core/mempool.cc b/core/mempool.cc
index 1ac3f676..deb7a0bb 100644
--- a/core/mempool.cc
+++ b/core/mempool.cc
@@ -1546,8 +1546,9 @@ static inline void* std_malloc(size_t size, size_t 
alignment)
     if ((ssize_t)size < 0)
         return libc_error_ptr<void *>(ENOMEM);
     void *ret;
-    if (size <= memory::pool::max_object_size && alignment <= size && 
smp_allocator) {
-        size = std::max(size, memory::pool::min_object_size);
+    size_t minimum_size = std::max(size, memory::pool::min_object_size);
+    if (size <= memory::pool::max_object_size && alignment <= minimum_size && 
smp_allocator) {
+        size = minimum_size;
         unsigned n = ilog2_roundup(size);
         ret = memory::malloc_pools[n].alloc();
         ret = translate_mem_area(mmu::mem_area::main, mmu::mem_area::mempool,
diff --git a/modules/tests/Makefile b/modules/tests/Makefile
index b7042a1f..ece5f846 100644
--- a/modules/tests/Makefile
+++ b/modules/tests/Makefile
@@ -116,7 +116,7 @@ tests := tst-pthread.so misc-ramdisk.so tst-vblk.so 
tst-bsd-evh.so \
        tst-ifaddrs.so tst-pthread-affinity-inherit.so tst-sem-timed-wait.so \
        tst-ttyname.so tst-pthread-barrier.so tst-feexcept.so tst-math.so \
        tst-sigaltstack.so tst-fread.so tst-tcp-cork.so tst-tcp-v6.so \
-       tst-calloc.so tst-crypt.so tst-non-fpic.so
+       tst-calloc.so tst-crypt.so tst-non-fpic.so tst-small-malloc.so
 
 #      libstatic-thread-variable.so tst-static-thread-variable.so \
 
diff --git a/tests/tst-small-malloc.cc b/tests/tst-small-malloc.cc
new file mode 100644
index 00000000..b0c97c03
--- /dev/null
+++ b/tests/tst-small-malloc.cc
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2018 Waldemar Kozaczuk
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <cassert>
+#include <osv/trace-count.hh>
+
+int main() {
+    tracepoint_counter *memory_malloc_mempool_counter = nullptr,
+            *memory_malloc_page_counter = nullptr;
+
+    for (auto & tp : tracepoint_base::tp_list) {
+        if ("memory_malloc_mempool" == std::string(tp.name)) {
+            memory_malloc_mempool_counter = new tracepoint_counter(tp);
+        }
+        if ("memory_malloc_page" == std::string(tp.name)) {
+            memory_malloc_page_counter = new tracepoint_counter(tp);
+        }
+    }
+    assert(memory_malloc_mempool_counter != nullptr);
+    assert(memory_malloc_page_counter != nullptr);
+
+    auto memory_malloc_mempool_counter_now = 
memory_malloc_mempool_counter->read();
+    auto memory_malloc_page_counter_now = memory_malloc_page_counter->read();
+
+    const int allocation_count = 1024;
+    for( int i = 0; i < allocation_count; i++) {
+        void *addr = malloc(7);
+        assert(addr);
+        free(addr);
+
+        addr = malloc(17);
+        assert(addr);
+        free(addr);
+    }
+
+    // Verify all allocations above were handled by malloc_pool
+    assert(memory_malloc_mempool_counter->read() - 
memory_malloc_mempool_counter_now >= 2 * allocation_count);
+    // Verify that NO allocations were handled by alloc_page
+    assert(memory_malloc_page_counter->read() - memory_malloc_page_counter_now 
== 0);
+}
\ No newline at end of file
-- 
2.19.1

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to