diff --git a/src/box/memtx_bitset.cc b/src/box/memtx_bitset.cc
index 4c4b956332d3a44394301b7a2737cc96278c6aa3..56ad38dc2b4d9ec191355fb16ba97b7f742a428e 100644
--- a/src/box/memtx_bitset.cc
+++ b/src/box/memtx_bitset.cc
@@ -194,7 +194,7 @@ MemtxBitset::MemtxBitset(struct key_def *key_def)
 	if (!m_id_to_tuple)
 		panic_syserror("bitset_index_create");
 	matras_create(m_id_to_tuple, MEMTX_EXTENT_SIZE, sizeof(struct tuple *),
-		      memtx_index_extent_alloc, memtx_index_extent_free);
+		      memtx_index_extent_alloc, memtx_index_extent_free, NULL);
 
 	m_tuple_to_id = mh_bitset_index_new();
 	if (!m_tuple_to_id)
diff --git a/src/box/memtx_engine.cc b/src/box/memtx_engine.cc
index f5afe5f0a7cab52704004a982e687b58acec2641..47d33f85220cadea7491fb90e13404f0d9597243 100644
--- a/src/box/memtx_engine.cc
+++ b/src/box/memtx_engine.cc
@@ -1252,8 +1252,9 @@ memtx_index_arena_init()
  * Allocate a block of size MEMTX_EXTENT_SIZE for memtx index
  */
 void *
-memtx_index_extent_alloc()
+memtx_index_extent_alloc(void *ctx)
 {
+	(void)ctx;
 	if (memtx_index_reserved_extents) {
 		assert(memtx_index_num_reserved_extents > 0);
 		memtx_index_num_reserved_extents--;
@@ -1274,8 +1275,9 @@ memtx_index_extent_alloc()
  * Free a block previously allocated by memtx_index_extent_alloc
  */
 void
-memtx_index_extent_free(void *extent)
+memtx_index_extent_free(void *ctx, void *extent)
 {
+	(void)ctx;
 	return mempool_free(&memtx_index_extent_pool, extent);
 }
 
diff --git a/src/box/memtx_engine.h b/src/box/memtx_engine.h
index a7f0ff7fd9f368010a0b069347f8d06056179d3a..08ab15eca349eb50bccaf2447eea8ad94087eb2d 100644
--- a/src/box/memtx_engine.h
+++ b/src/box/memtx_engine.h
@@ -89,13 +89,13 @@ memtx_index_arena_init();
  * Allocate a block of size MEMTX_EXTENT_SIZE for memtx index
  */
 void *
-memtx_index_extent_alloc();
+memtx_index_extent_alloc(void *ctx);
 
 /**
  * Free a block previously allocated by memtx_index_extent_alloc
  */
 void
-memtx_index_extent_free(void *extent);
+memtx_index_extent_free(void *ctx, void *extent);
 
 /**
  * Reserve num extents in pool.
diff --git a/src/box/memtx_hash.cc b/src/box/memtx_hash.cc
index 5c56fa84943d02eef5726e5b61c7f13712ac8c14..5587023cae3666522e2c837a5ef9d455b2bcbbbc 100644
--- a/src/box/memtx_hash.cc
+++ b/src/box/memtx_hash.cc
@@ -221,7 +221,7 @@ MemtxHash::MemtxHash(struct key_def *key_def)
 	}
 	light_index_create(hash_table, HASH_INDEX_EXTENT_SIZE,
 			   memtx_index_extent_alloc, memtx_index_extent_free,
-			   this->key_def);
+			   NULL, this->key_def);
 }
 
 MemtxHash::~MemtxHash()
diff --git a/src/box/memtx_rtree.cc b/src/box/memtx_rtree.cc
index 5a3c9c98d432a81d5875bcdab69b542dc6987df4..07b62175eb5f1c74fe641895eb585fc96ce845cf 100644
--- a/src/box/memtx_rtree.cc
+++ b/src/box/memtx_rtree.cc
@@ -167,7 +167,7 @@ MemtxRTree::MemtxRTree(struct key_def *key_def)
 	enum rtree_distance_type distance_type =
 		(enum rtree_distance_type)(int)key_def->opts.distance;
 	rtree_init(&m_tree, m_dimension, MEMTX_EXTENT_SIZE,
-		   memtx_index_extent_alloc, memtx_index_extent_free,
+		   memtx_index_extent_alloc, memtx_index_extent_free, NULL,
 		   distance_type);
 }
 
diff --git a/src/box/memtx_tree.cc b/src/box/memtx_tree.cc
index 904e1d37ac3a1c02bc1537c99c959fbf64a79fe8..29bba8f736c73479170037f75ad3c233b4a479d5 100644
--- a/src/box/memtx_tree.cc
+++ b/src/box/memtx_tree.cc
@@ -190,7 +190,7 @@ MemtxTree::MemtxTree(struct key_def *key_def_arg)
 	memtx_index_arena_init();
 	bps_tree_index_create(&tree, key_def,
 			      memtx_index_extent_alloc,
-			      memtx_index_extent_free);
+			      memtx_index_extent_free, NULL);
 }
 
 MemtxTree::~MemtxTree()
diff --git a/src/lib/salad/bps_tree.h b/src/lib/salad/bps_tree.h
index 1aa64d50618f0afedd44cc3b6b0a6cdb330dfa7f..f13fdb12def000edb1fd0d798a696ece804d2693 100644
--- a/src/lib/salad/bps_tree.h
+++ b/src/lib/salad/bps_tree.h
@@ -132,7 +132,8 @@
  * typedef void *(*bps_tree_extent_alloc_f)();
  * typedef void (*bps_tree_extent_free_f)(void *);
  * // base:
- * void bps_tree_create(tree, arg, extent_alloc_func, extent_free_func);
+ * void bps_tree_create(tree, arg, extent_alloc_func, extent_free_func,
+ *                      alloc_ctx);
  * void bps_tree_destroy(tree);
  * int bps_tree_build(tree, sorted_array, array_size);
  * bps_tree_elem_t *bps_tree_find(tree, key);
@@ -534,12 +535,12 @@ struct bps_tree_iterator {
  * BPS-tree properly handles with NULL result but could leak memory
  *  in case of exception.
  */
-typedef void *(*bps_tree_extent_alloc_f)();
+typedef void *(*bps_tree_extent_alloc_f)(void *ctx);
 
 /**
  * Pointer to function frees extent (of size BPS_TREE_EXTENT_SIZE)
  */
-typedef void (*bps_tree_extent_free_f)(void *);
+typedef void (*bps_tree_extent_free_f)(void *ctx, void *extent);
 
 /**
  * @brief Tree construction. Fills struct bps_tree members.
@@ -548,12 +549,14 @@ typedef void (*bps_tree_extent_free_f)(void *);
  * @param extent_alloc_func - pointer to function that allocates extents,
  *  see bps_tree_extent_alloc_f description for details
  * @param extent_free_func - pointer to function that allocates extents,
+ * @param alloc_ctx - argument passed to extent allocator
  *  see bps_tree_extent_free_f description for details
  */
 void
 bps_tree_create(struct bps_tree *tree, bps_tree_arg_t arg,
 		bps_tree_extent_alloc_f extent_alloc_func,
-		bps_tree_extent_free_f extent_free_func);
+		bps_tree_extent_free_f extent_free_func,
+		void *alloc_ctx);
 
 /**
  * @brief Fills a new (asserted) tree with values from sorted array.
@@ -965,12 +968,14 @@ struct bps_leaf_path_elem {
  * @param extent_alloc_func - pointer to function that allocates extents,
  *  see bps_tree_extent_alloc_f description for details
  * @param extent_free_func - pointer to function that allocates extents,
+ * @param alloc_ctx - argument passed to extent allocator
  *  see bps_tree_extent_free_f description for details
  */
 inline void
 bps_tree_create(struct bps_tree *tree, bps_tree_arg_t arg,
 		bps_tree_extent_alloc_f extent_alloc_func,
-		bps_tree_extent_free_f extent_free_func)
+		bps_tree_extent_free_f extent_free_func,
+		void *alloc_ctx)
 {
 	tree->root_id = (bps_tree_block_id_t)(-1);
 	tree->first_id = (bps_tree_block_id_t)(-1);
@@ -985,7 +990,7 @@ bps_tree_create(struct bps_tree *tree, bps_tree_arg_t arg,
 
 	matras_create(&tree->matras,
 		      BPS_TREE_EXTENT_SIZE, BPS_TREE_BLOCK_SIZE,
-		      extent_alloc_func, extent_free_func);
+		      extent_alloc_func, extent_free_func, alloc_ctx);
 
 #ifdef BPS_TREE_DEBUG_BRANCH_VISIT
 	/* Bit masks of different branches visits */
diff --git a/src/lib/salad/light.h b/src/lib/salad/light.h
index 05f11a42629f7db51ad6acefcd07c71eeb88c5af..c9f450ad630ca888f8d27be425b2972eb7354ca4 100644
--- a/src/lib/salad/light.h
+++ b/src/lib/salad/light.h
@@ -163,8 +163,8 @@ struct LIGHT(iterator) {
 /**
  * Type of functions for memory allocation and deallocation
  */
-typedef void *(*LIGHT(extent_alloc_t))();
-typedef void (*LIGHT(extent_free_t))(void *);
+typedef void *(*LIGHT(extent_alloc_t))(void *ctx);
+typedef void (*LIGHT(extent_free_t))(void *ctx, void *extent);
 
 /**
  * Special result of light_find that means that nothing was found
@@ -180,6 +180,7 @@ static const uint32_t LIGHT(end) = 0xFFFFFFFF;
  * @param extent_size - size of allocating memory blocks
  * @param extent_alloc_func - memory blocks allocation function
  * @param extent_free_func - memory blocks allocation function
+ * @param alloc_ctx - argument passed to memory block allocator
  * @param arg - optional parameter to save for comparing function
  */
 void
@@ -331,13 +332,14 @@ LIGHT(itr_destroy)(struct LIGHT(core) *ht, struct LIGHT(iterator) *itr);
  * @param extent_size - size of allocating memory blocks
  * @param extent_alloc_func - memory blocks allocation function
  * @param extent_free_func - memory blocks allocation function
+ * @param alloc_ctx - argument passed to memory block allocator
  * @param arg - optional parameter to save for comparing function
  */
 inline void
 LIGHT(create)(struct LIGHT(core) *ht, size_t extent_size,
 	      LIGHT(extent_alloc_t) extent_alloc_func,
 	      LIGHT(extent_free_t) extent_free_func,
-	      LIGHT_CMP_ARG_TYPE arg)
+	      void *alloc_ctx, LIGHT_CMP_ARG_TYPE arg)
 {
 	assert((ht->GROW_INCREMENT & (ht->GROW_INCREMENT - 1)) == 0);
 	assert(sizeof(LIGHT_DATA_TYPE) >= sizeof(uint32_t));
@@ -347,7 +349,7 @@ LIGHT(create)(struct LIGHT(core) *ht, size_t extent_size,
 	ht->arg = arg;
 	matras_create(&ht->mtable,
 		      extent_size, sizeof(struct LIGHT(record)),
-		      extent_alloc_func, extent_free_func);
+		      extent_alloc_func, extent_free_func, alloc_ctx);
 }
 
 /**
diff --git a/src/lib/salad/rtree.c b/src/lib/salad/rtree.c
index 28fd8d66383ccb522365ab53a69972149a269e52..d17358128434688e65fada115fee91b233cdead8 100644
--- a/src/lib/salad/rtree.c
+++ b/src/lib/salad/rtree.c
@@ -943,7 +943,7 @@ rtree_iterator_next(struct rtree_iterator *itr)
 int
 rtree_init(struct rtree *tree, unsigned dimension, uint32_t extent_size,
 	   rtree_extent_alloc_t extent_alloc, rtree_extent_free_t extent_free,
-	   enum rtree_distance_type distance_type)
+	   void *alloc_ctx, enum rtree_distance_type distance_type)
 {
 	tree->n_records = 0;
 	tree->height = 0;
@@ -970,7 +970,7 @@ rtree_init(struct rtree *tree, unsigned dimension, uint32_t extent_size,
 		/ sizeof(struct rtree_neighbor);
 
 	matras_create(&tree->mtab, extent_size, tree->page_size,
-		      extent_alloc, extent_free);
+		      extent_alloc, extent_free, alloc_ctx);
 	return 0;
 }
 
diff --git a/src/lib/salad/rtree.h b/src/lib/salad/rtree.h
index 7a26c669a359af1a512fa7e69bee190116527cfc..2d3358c9a8aee5165b3f48f1067e1242de705d3b 100644
--- a/src/lib/salad/rtree.h
+++ b/src/lib/salad/rtree.h
@@ -99,8 +99,8 @@ enum spatial_search_op
 };
 
 /* pointers to page allocation and deallocations functions */
-typedef void *(*rtree_extent_alloc_t)();
-typedef void (*rtree_extent_free_t)(void *);
+typedef void *(*rtree_extent_alloc_t)(void *ctx);
+typedef void (*rtree_extent_free_t)(void *ctx, void *extent);
 
 /* A box in RTREE_DIMENSION space */
 struct rtree_rect
@@ -231,12 +231,13 @@ rtree_set2dp(struct rtree_rect *rect, coord_t x, coord_t y);
  * @param extent_size - size of extents allocated by extent_alloc (see next)
  * @param extent_alloc - extent allocation function
  * @param extent_free - extent deallocation function
+ * @param alloc_ctx - argument passed to extent allocator
  * @return 0 on success, -1 on error
  */
 int
 rtree_init(struct rtree *tree, unsigned dimension, uint32_t extent_size,
 	   rtree_extent_alloc_t extent_alloc, rtree_extent_free_t extent_free,
-	   enum rtree_distance_type distance_type);
+	   void *alloc_ctx, enum rtree_distance_type distance_type);
 
 /**
  * @brief Destroy a tree
diff --git a/src/lib/small b/src/lib/small
index c231b45095e68d4e561970b4db7fe1f5c82669ec..afbfa57d6ae0faeb5cf29c53e40b0eb2bf2ce969 160000
--- a/src/lib/small
+++ b/src/lib/small
@@ -1 +1 @@
-Subproject commit c231b45095e68d4e561970b4db7fe1f5c82669ec
+Subproject commit afbfa57d6ae0faeb5cf29c53e40b0eb2bf2ce969
diff --git a/test/unit/bps_tree.cc b/test/unit/bps_tree.cc
index 1aa522dc3a9e484504a8cb0e363e4814b3be476a..2a855a2c3c9861a8029bd9ace6d50205f54fbf73 100644
--- a/test/unit/bps_tree.cc
+++ b/test/unit/bps_tree.cc
@@ -66,16 +66,20 @@ compare(type_t a, type_t b)
 static int extents_count = 0;
 
 static void *
-extent_alloc()
+extent_alloc(void *ctx)
 {
-	extents_count++;
+	int *p_extents_count = (int *)ctx;
+	assert(p_extents_count == &extents_count);
+	++*p_extents_count;
 	return malloc(BPS_TREE_EXTENT_SIZE);
 }
 
 static void
-extent_free(void *extent)
+extent_free(void *ctx, void *extent)
 {
-	extents_count--;
+	int *p_extents_count = (int *)ctx;
+	assert(p_extents_count == &extents_count);
+	--*p_extents_count;
 	free(extent);
 }
 
@@ -86,7 +90,8 @@ simple_check()
 
 	const unsigned int rounds = 2000;
 	bps_tree_test tree;
-	bps_tree_test_create(&tree, 0, extent_alloc, extent_free);
+	bps_tree_test_create(&tree, 0, extent_alloc, extent_free,
+			     &extents_count);
 
 	printf("Insert 1..X, remove 1..X\n");
 	for (unsigned int i = 0; i < rounds; i++) {
@@ -231,7 +236,8 @@ compare_with_sptree_check()
 	sptree_test_init(&spt_test, sizeof(type_t), 0, 0, 0, &node_comp, 0, 0);
 
 	bps_tree_test tree;
-	bps_tree_test_create(&tree, 0, extent_alloc, extent_free);
+	bps_tree_test_create(&tree, 0, extent_alloc, extent_free,
+			     &extents_count);
 
 	const int rounds = 16 * 1024;
 	const int elem_limit = 	1024;
@@ -273,7 +279,8 @@ compare_with_sptree_check_branches()
 	sptree_test_init(&spt_test, sizeof(type_t), 0, 0, 0, &node_comp, 0, 0);
 
 	bps_tree_test tree;
-	bps_tree_test_create(&tree, 0, extent_alloc, extent_free);
+	bps_tree_test_create(&tree, 0, extent_alloc, extent_free,
+			     &extents_count);
 
 	const int elem_limit = 1024;
 
@@ -519,7 +526,8 @@ loading_test()
 		arr[i] = i;
 
 	for (type_t i = 0; i <= test_count; i++) {
-		bps_tree_test_create(&tree, 0, extent_alloc, extent_free);
+		bps_tree_test_create(&tree, 0, extent_alloc, extent_free,
+				     &extents_count);
 
 		if (bps_tree_test_build(&tree, arr, i))
 			fail("building failed", "true");
@@ -550,7 +558,8 @@ printing_test()
 	header();
 
 	bps_tree_test tree;
-	bps_tree_test_create(&tree, 0, extent_alloc, extent_free);
+	bps_tree_test_create(&tree, 0, extent_alloc, extent_free,
+			     &extents_count);
 
 	const type_t rounds = 22;
 
@@ -576,7 +585,8 @@ white_box_test()
 	header();
 
 	bps_tree_test tree;
-	bps_tree_test_create(&tree, 0, extent_alloc, extent_free);
+	bps_tree_test_create(&tree, 0, extent_alloc, extent_free,
+			     &extents_count);
 
 	assert(BPS_TREE_test_MAX_COUNT_IN_LEAF == 14);
 	assert(BPS_TREE_test_MAX_COUNT_IN_INNER == 10);
@@ -612,7 +622,8 @@ white_box_test()
 	bps_tree_test_print(&tree, TYPE_F);
 
 	bps_tree_test_destroy(&tree);
-	bps_tree_test_create(&tree, 0, extent_alloc, extent_free);
+	bps_tree_test_create(&tree, 0, extent_alloc, extent_free,
+			     &extents_count);
 	type_t arr[140];
 	for (type_t i = 0; i < 140; i++)
 		arr[i] = i;
diff --git a/test/unit/bps_tree_itr.cc b/test/unit/bps_tree_itr.cc
index 1e18b599bd01947833f82f07b7a51e56222fe72f..4c71aa458e47b473c0b1343275424021de31f827 100644
--- a/test/unit/bps_tree_itr.cc
+++ b/test/unit/bps_tree_itr.cc
@@ -42,16 +42,20 @@ static int compare_key(const elem_t &a, long b)
 int total_extents_allocated = 0;
 
 static void *
-extent_alloc()
+extent_alloc(void *ctx)
 {
-	total_extents_allocated++;
+	int *p_total_extents_allocated = (int *)ctx;
+	assert(p_total_extents_allocated == &total_extents_allocated);
+	++*p_total_extents_allocated;
 	return malloc(BPS_TREE_EXTENT_SIZE);
 }
 
 static void
-extent_free(void *extent)
+extent_free(void *ctx, void *extent)
 {
-	total_extents_allocated--;
+	int *p_total_extents_allocated = (int *)ctx;
+	assert(p_total_extents_allocated == &total_extents_allocated);
+	--*p_total_extents_allocated;
 	free(extent);
 }
 
@@ -61,7 +65,8 @@ itr_check()
 	header();
 
 	bps_tree_test tree;
-	bps_tree_test_create(&tree, 0, extent_alloc, extent_free);
+	bps_tree_test_create(&tree, 0, extent_alloc, extent_free,
+			     &total_extents_allocated);
 	
 	/* Stupid tests */
 	{
@@ -239,7 +244,8 @@ itr_invalidate_check()
 		long del_cnt = rand() % max_delete_count + 1;
 		if (del_pos + del_cnt > test_size)
 			del_cnt = test_size - del_pos;
-		bps_tree_test_create(&tree, 0, extent_alloc, extent_free);
+		bps_tree_test_create(&tree, 0, extent_alloc, extent_free,
+				     &total_extents_allocated);
 
 		for (long i = 0; i < test_size; i++) {
 			elem_t e;
@@ -283,7 +289,8 @@ itr_invalidate_check()
 	for (long attempt = 0; attempt < attempt_count; attempt++) {
 		long ins_pos = rand() % test_size;
 		long ins_cnt = rand() % max_insert_count + 1;
-		bps_tree_test_create(&tree, 0, extent_alloc, extent_free);
+		bps_tree_test_create(&tree, 0, extent_alloc, extent_free,
+				     &total_extents_allocated);
 
 		for (long i = 0; i < test_size; i++) {
 			elem_t e;
@@ -338,7 +345,8 @@ itr_invalidate_check()
 		long ins_cnt = rand() % max_insert_count + 1;
 		if (del_pos + del_cnt > test_size)
 			del_cnt = test_size - del_pos;
-		bps_tree_test_create(&tree, 0, extent_alloc, extent_free);
+		bps_tree_test_create(&tree, 0, extent_alloc, extent_free,
+				     &total_extents_allocated);
 
 		for (long i = 0; i < test_size; i++) {
 			elem_t e;
@@ -408,7 +416,8 @@ itr_freeze_check()
 	struct bps_tree_test tree;
 
 	for (int i = 0; i < 10; i++) {
-		bps_tree_test_create(&tree, 0, extent_alloc, extent_free);
+		bps_tree_test_create(&tree, 0, extent_alloc, extent_free,
+				     &total_extents_allocated);
 		int comp_buf_size1 = 0;
 		int comp_buf_size2 = 0;
 		for (int j = 0; j < test_data_size; j++) {
diff --git a/test/unit/light.cc b/test/unit/light.cc
index d459b7a7bc14e512e466e5f440d837c3c26eeea0..ca877ff06b7640caa4b293a8d24d4bf92f298c07 100644
--- a/test/unit/light.cc
+++ b/test/unit/light.cc
@@ -41,16 +41,20 @@ equal_key(hash_value_t v1, hash_value_t v2)
 #include "salad/light.h"
 
 inline void *
-my_light_alloc()
+my_light_alloc(void *ctx)
 {
-	extents_count++;
+	size_t *p_extents_count = (size_t *)ctx;
+	assert(p_extents_count == &extents_count);
+	++*p_extents_count;
 	return malloc(light_extent_size);
 }
 
 inline void
-my_light_free(void *p)
+my_light_free(void *ctx, void *p)
 {
-	extents_count--;
+	size_t *p_extents_count = (size_t *)ctx;
+	assert(p_extents_count == &extents_count);
+	--*p_extents_count;
 	free(p);
 }
 
@@ -61,7 +65,8 @@ simple_test()
 	header();
 
 	struct light_core ht;
-	light_create(&ht, light_extent_size, my_light_alloc, my_light_free, 0);
+	light_create(&ht, light_extent_size,
+		     my_light_alloc, my_light_free, &extents_count, 0);
 	std::vector<bool> vect;
 	size_t count = 0;
 	const size_t rounds = 1000;
@@ -124,7 +129,8 @@ collision_test()
 	header();
 
 	struct light_core ht;
-	light_create(&ht, light_extent_size, my_light_alloc, my_light_free, 0);
+	light_create(&ht, light_extent_size,
+		     my_light_alloc, my_light_free, &extents_count, 0);
 	std::vector<bool> vect;
 	size_t count = 0;
 	const size_t rounds = 100;
@@ -187,7 +193,8 @@ itr_test()
 	header();
 
 	struct light_core ht;
-	light_create(&ht, light_extent_size, my_light_alloc, my_light_free, 0);
+	light_create(&ht, light_extent_size,
+		     my_light_alloc, my_light_free, &extents_count, 0);
 	const size_t rounds = 1000;
 	const size_t start_limits = 20;
 
@@ -249,7 +256,8 @@ itr_freeze_check()
 	struct light_core ht;
 
 	for (int i = 0; i < 10; i++) {
-		light_create(&ht, light_extent_size, my_light_alloc, my_light_free, 0);
+		light_create(&ht, light_extent_size,
+			     my_light_alloc, my_light_free, &extents_count, 0);
 		int comp_buf_size = 0;
 		int comp_buf_size2 = 0;
 		for (int j = 0; j < test_data_size; j++) {
diff --git a/test/unit/rtree.cc b/test/unit/rtree.cc
index 6d482dc63ee95804055fd1ec1eeaf3ae44624e12..b41c0eb0903ba9eec963a60703bd66cfa8265a99 100644
--- a/test/unit/rtree.cc
+++ b/test/unit/rtree.cc
@@ -12,16 +12,20 @@ static int page_count = 0;
 const uint32_t extent_size = 1024 * 8;
 
 static void *
-extent_alloc()
+extent_alloc(void *ctx)
 {
-	page_count++;
+	int *p_page_count = (int *)ctx;
+	assert(p_page_count == &page_count);
+	++*p_page_count;
 	return malloc(extent_size);
 }
 
 static void
-extent_free(void *page)
+extent_free(void *ctx, void *page)
 {
-	page_count--;
+	int *p_page_count = (int *)ctx;
+	assert(p_page_count == &page_count);
+	--*p_page_count;
 	free(page);
 }
 
@@ -36,7 +40,8 @@ simple_check()
 	header();
 
 	struct rtree tree;
-	rtree_init(&tree, 2, extent_size, extent_alloc, extent_free,
+	rtree_init(&tree, 2, extent_size,
+		   extent_alloc, extent_free, &page_count,
 		   RTREE_EUCLID);
 
 	printf("Insert 1..X, remove 1..X\n");
@@ -229,7 +234,8 @@ neighbor_test()
 
 	for (size_t i = 0; i <= test_count; i++) {
 		struct rtree tree;
-		rtree_init(&tree, 2, extent_size, extent_alloc, extent_free,
+		rtree_init(&tree, 2, extent_size,
+			   extent_alloc, extent_free, &page_count,
 			   RTREE_EUCLID);
 
 		rtree_test_build(&tree, arr, i);
diff --git a/test/unit/rtree_itr.cc b/test/unit/rtree_itr.cc
index 3c6c3c3fdc1e7d46dc59a759da1a26b3fe9180c6..065912323f60411f65798aaea797cc96a36823e7 100644
--- a/test/unit/rtree_itr.cc
+++ b/test/unit/rtree_itr.cc
@@ -11,16 +11,20 @@ static int extent_count = 0;
 const uint32_t extent_size = 1024 * 8;
 
 static void *
-extent_alloc()
+extent_alloc(void *ctx)
 {
-	extent_count++;
+	int *p_extent_count = (int *)ctx;
+	assert(p_extent_count == &extent_count);
+	++*p_extent_count;
 	return malloc(extent_size);
 }
 
 static void
-extent_free(void *page)
+extent_free(void *ctx, void *page)
 {
-	extent_count--;
+	int *p_extent_count = (int *)ctx;
+	assert(p_extent_count == &extent_count);
+	--*p_extent_count;
 	free(page);
 }
 
@@ -30,7 +34,8 @@ itr_check()
 	header();
 
 	struct rtree tree;
-	rtree_init(&tree, 2, extent_size, extent_alloc, extent_free,
+	rtree_init(&tree, 2, extent_size,
+		   extent_alloc, extent_free, &extent_count,
 		   RTREE_EUCLID);
 
 	/* Filling tree */
@@ -212,7 +217,8 @@ itr_invalidate_check()
 			del_cnt = test_size - del_pos;
 		}
 		struct rtree tree;
-		rtree_init(&tree, 2, extent_size, extent_alloc, extent_free,
+		rtree_init(&tree, 2, extent_size,
+			   extent_alloc, extent_free, &extent_count,
 			   RTREE_EUCLID);
 		struct rtree_iterator iterators[test_size];
 		for (size_t i = 0; i < test_size; i++)
@@ -257,7 +263,8 @@ itr_invalidate_check()
 		size_t ins_cnt = rand() % max_insert_count + 1;
 
 		struct rtree tree;
-		rtree_init(&tree, 2, extent_size, extent_alloc, extent_free,
+		rtree_init(&tree, 2, extent_size,
+			   extent_alloc, extent_free, &extent_count,
 			   RTREE_EUCLID);
 		struct rtree_iterator iterators[test_size];
 		for (size_t i = 0; i < test_size; i++)
diff --git a/test/unit/rtree_multidim.cc b/test/unit/rtree_multidim.cc
index 50f7cde429d4443d5e48b2fc05deaeb12a97e5ef..8a90fac9c41145255eeb9f8cc59b10d84d923174 100644
--- a/test/unit/rtree_multidim.cc
+++ b/test/unit/rtree_multidim.cc
@@ -27,16 +27,20 @@ const unsigned TEST_ROUNDS = 1000;
 static int page_count = 0;
 
 static void *
-extent_alloc()
+extent_alloc(void *ctx)
 {
-	page_count++;
+	int *p_page_count = (int *)ctx;
+	assert(p_page_count == &page_count);
+	++*p_page_count;
 	return malloc(extent_size);
 }
 
 static void
-extent_free(void *page)
+extent_free(void *ctx, void *page)
 {
-	page_count--;
+	int *p_page_count = (int *)ctx;
+	assert(p_page_count == &page_count);
+	--*p_page_count;
 	free(page);
 }
 
@@ -486,7 +490,8 @@ rand_test()
 	CBoxSet<DIMENSION> set;
 
 	struct rtree tree;
-	rtree_init(&tree, DIMENSION, extent_size, extent_alloc, extent_free,
+	rtree_init(&tree, DIMENSION, extent_size,
+		   extent_alloc, extent_free, &page_count,
 		   RTREE_EUCLID);
 
 	printf("\tDIMENSION: %u, page size: %u, max fill good: %d\n",