From 0d859004994ad13f3a18646cc768a64cea8f1218 Mon Sep 17 00:00:00 2001
From: Konstantin Osipov <kostja@tarantool.org>
Date: Fri, 17 Apr 2015 15:48:51 +0300
Subject: [PATCH] =?UTF-8?q?small=20allocator:=20accept=20patches=20from=20?=
 =?UTF-8?q?J=C3=B6rg=20Richter?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Accept patches from Jörg Richter which fix a bug and implement
a todo item in the small allocator, and change slab_alloc_minimal to
16, to work well out of the box with small tuples.
---
 src/box/lua/load_cfg.lua    |  2 +-
 src/ipc.cc                  |  4 ++--
 src/lib/small/slab_arena.c  | 25 ++++++++++++++++++-------
 src/lib/small/small.c       |  1 +
 test/app/float_value.result |  2 +-
 test/app/init_script.result |  2 +-
 test/box/admin.result       |  2 +-
 test/box/cfg.result         |  4 ++--
 test/wal_off/oom.result     | 12 ++++++------
 9 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua
index dd93c9a6c2..5bc522f857 100644
--- a/src/box/lua/load_cfg.lua
+++ b/src/box/lua/load_cfg.lua
@@ -29,7 +29,7 @@ local default_sophia_cfg = {
 local default_cfg = {
     listen              = nil,
     slab_alloc_arena    = 1.0,
-    slab_alloc_minimal  = 64,
+    slab_alloc_minimal  = 16,
     slab_alloc_maximal  = 1024 * 1024,
     slab_alloc_factor   = 1.1,
     work_dir            = nil,
diff --git a/src/ipc.cc b/src/ipc.cc
index b2bb737a77..637f64435f 100644
--- a/src/ipc.cc
+++ b/src/ipc.cc
@@ -177,11 +177,11 @@ ipc_channel_shutdown(struct ipc_channel *ch)
 	ch->readonly = true;
 
 	struct fiber *f;
-	while(!rlist_empty(&ch->readers)) {
+	while (!rlist_empty(&ch->readers)) {
 		f = rlist_first_entry(&ch->readers, struct fiber, state);
 		ipc_channel_close_waiter(ch, f);
 	}
-	while(!rlist_empty(&ch->writers)) {
+	while (!rlist_empty(&ch->writers)) {
 		f = rlist_first_entry(&ch->writers, struct fiber, state);
 		ipc_channel_close_waiter(ch, f);
 	}
diff --git a/src/lib/small/slab_arena.c b/src/lib/small/slab_arena.c
index f9e28236ca..a233e538fc 100644
--- a/src/lib/small/slab_arena.c
+++ b/src/lib/small/slab_arena.c
@@ -61,17 +61,28 @@ mmap_checked(size_t size, size_t align, int flags)
 	/* The size must be a multiple of alignment */
 	assert((size & (align - 1)) == 0);
 	/*
-	 * mmap twice the requested amount to be able to align
-	 * the mapped address.
-	 * @todo all mappings except the first are likely to
-	 * be aligned already. Find out if trying to map
-	 * optimistically exactly the requested amount and fall
-	 * back to double-size mapping is a viable strategy.
+	 * All mappings except the first are likely to
+	 * be aligned already.  Be optimistic by trying
+	 * to map exactly the requested amount.
 	 */
-	void *map = mmap(NULL, size + align, PROT_READ | PROT_WRITE,
+	void *map = mmap(NULL, size, PROT_READ | PROT_WRITE,
 			 flags | MAP_ANONYMOUS, -1, 0);
 	if (map == MAP_FAILED)
 		return NULL;
+	if (((intptr_t) map & (align - 1)) == 0)
+		return map;
+	munmap_checked(map, size);
+
+	/*
+	 * mmap twice the requested amount to be able to align
+	 * the mapped address.  This can lead to virtual memory
+	 * fragmentation depending on the kernels allocation
+	 * strategy.
+	 */
+	map = mmap(NULL, size + align, PROT_READ | PROT_WRITE,
+		   flags | MAP_ANONYMOUS, -1, 0);
+	if (map == MAP_FAILED)
+		return NULL;
 
 	/* Align the mapped address around slab size. */
 	size_t offset = (intptr_t) map & (align - 1);
diff --git a/src/lib/small/small.c b/src/lib/small/small.c
index b065d52470..240f6239d6 100644
--- a/src/lib/small/small.c
+++ b/src/lib/small/small.c
@@ -141,6 +141,7 @@ small_alloc_create(struct small_alloc *alloc, struct slab_cache *cache,
 	factor_tree_new(&alloc->factor_pools);
 	(void) factor_pool_create(alloc, NULL, alloc->objsize_max);
 
+	lifo_init(&alloc->delayed);
 	alloc->is_delayed_free_mode = false;
 }
 
diff --git a/test/app/float_value.result b/test/app/float_value.result
index f592757013..4fd16c37bd 100644
--- a/test/app/float_value.result
+++ b/test/app/float_value.result
@@ -10,7 +10,7 @@ box.cfg
 9	logger_nonblock:true
 10	snap_dir:.
 11	coredump:false
-12	slab_alloc_minimal:64
+12	slab_alloc_minimal:16
 13	sophia_dir:.
 14	wal_mode:write
 15	wal_dir:.
diff --git a/test/app/init_script.result b/test/app/init_script.result
index 03ef3f3517..dc7f846591 100644
--- a/test/app/init_script.result
+++ b/test/app/init_script.result
@@ -14,7 +14,7 @@ box.cfg
 9	logger_nonblock:true
 10	snap_dir:.
 11	coredump:false
-12	slab_alloc_minimal:64
+12	slab_alloc_minimal:16
 13	sophia_dir:.
 14	wal_mode:write
 15	rows_per_wal:500000
diff --git a/test/box/admin.result b/test/box/admin.result
index 30217aee9a..7c3ef8b360 100644
--- a/test/box/admin.result
+++ b/test/box/admin.result
@@ -34,7 +34,7 @@ box.cfg
   logger_nonblock: true
   snap_dir: .
   coredump: false
-  slab_alloc_minimal: 64
+  slab_alloc_minimal: 16
   sophia_dir: .
   wal_mode: write
   wal_dir: .
diff --git a/test/box/cfg.result b/test/box/cfg.result
index bab6b13c6f..a6849cc41c 100644
--- a/test/box/cfg.result
+++ b/test/box/cfg.result
@@ -20,7 +20,7 @@ t
   - 'logger_nonblock: true'
   - 'snap_dir: .'
   - 'coredump: false'
-  - 'slab_alloc_minimal: 64'
+  - 'slab_alloc_minimal: 16'
   - 'sophia_dir: .'
   - 'wal_mode: write'
   - 'wal_dir: .'
@@ -54,7 +54,7 @@ t
   - 'logger_nonblock: true'
   - 'snap_dir: .'
   - 'coredump: false'
-  - 'slab_alloc_minimal: 64'
+  - 'slab_alloc_minimal: 16'
   - 'sophia_dir: .'
   - 'wal_mode: write'
   - 'wal_dir: .'
diff --git a/test/wal_off/oom.result b/test/wal_off/oom.result
index 4619a92beb..f547528c4d 100644
--- a/test/wal_off/oom.result
+++ b/test/wal_off/oom.result
@@ -15,11 +15,11 @@ while true do
     i = i + 1
 end;
 ---
-- error: Failed to allocate 24643 bytes in slab allocator for tuple
+- error: Failed to allocate 25031 bytes in slab allocator for tuple
 ...
 space:len();
 ---
-- 6155
+- 6252
 ...
 i = 1;
 ---
@@ -29,11 +29,11 @@ while true do
     i = i + 1
 end;
 ---
-- error: Failed to allocate 5187 bytes in slab allocator for tuple
+- error: Failed to allocate 4167 bytes in slab allocator for tuple
 ...
 space:len();
 ---
-- 7446
+- 7288
 ...
 i = 1;
 ---
@@ -43,12 +43,12 @@ while true do
     i = i + 1
 end;
 ---
-- error: Failed to allocate 2751 bytes in slab allocator for tuple
+- error: Failed to allocate 2123 bytes in slab allocator for tuple
 ...
 --# setopt delimiter ''
 space:len()
 ---
-- 8128
+- 7813
 ...
 space.index['primary']:get{0}
 ---
-- 
GitLab