From d146adfefcc70f0ffda8c9c6c75c8d2337e89351 Mon Sep 17 00:00:00 2001
From: Vladimir Davydov <vdavydov@tarantool.org>
Date: Tue, 19 Jul 2022 17:29:19 +0300
Subject: [PATCH] memtx: use MemtxAllocator::collect_garbage in unit test

Once we start reusing read views, we won't be able to allocate and free
a tuple to trigger garbage collection in tests, because the tuple may
get attached to the last read view. Let's make the collect_garbage()
method public and use it in tests.

While we are at it, let's also rewrite the destroy() method using
collect_garbage().

Needed for #7189

NO_DOC=refactoring
NO_CHANGELOG=refactoring
---
 src/box/memtx_allocator.h    | 28 +++++++++++++++-------------
 test/unit/memtx_allocator.cc |  6 ++----
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/src/box/memtx_allocator.h b/src/box/memtx_allocator.h
index 755ec0206a..5b5ae11eec 100644
--- a/src/box/memtx_allocator.h
+++ b/src/box/memtx_allocator.h
@@ -198,10 +198,7 @@ class MemtxAllocator {
 
 	static void destroy()
 	{
-		while (!stailq_empty(&gc)) {
-			struct memtx_tuple *memtx_tuple = stailq_shift_entry(
-					&gc, struct memtx_tuple, in_gc);
-			immediate_free_tuple(memtx_tuple);
+		while (collect_garbage()) {
 		}
 	}
 
@@ -273,6 +270,20 @@ class MemtxAllocator {
 		}
 	}
 
+	/**
+	 * Does a garbage collection step. Returns false if there's no more
+	 * tuples to collect.
+	 */
+	static bool collect_garbage()
+	{
+		for (int i = 0; !stailq_empty(&gc) && i < GC_BATCH_SIZE; i++) {
+			struct memtx_tuple *memtx_tuple = stailq_shift_entry(
+					&gc, struct memtx_tuple, in_gc);
+			immediate_free_tuple(memtx_tuple);
+		}
+		return !stailq_empty(&gc);
+	}
+
 private:
 	static constexpr int GC_BATCH_SIZE = 100;
 
@@ -294,15 +305,6 @@ class MemtxAllocator {
 		free(memtx_tuple, size);
 	}
 
-	static void collect_garbage()
-	{
-		for (int i = 0; !stailq_empty(&gc) && i < GC_BATCH_SIZE; i++) {
-			struct memtx_tuple *memtx_tuple = stailq_shift_entry(
-					&gc, struct memtx_tuple, in_gc);
-			immediate_free_tuple(memtx_tuple);
-		}
-	}
-
 	/**
 	 * Returns the most recent open read view that needs this tuple or null
 	 * if the tuple may be freed immediately.
diff --git a/test/unit/memtx_allocator.cc b/test/unit/memtx_allocator.cc
index e4520dacb9..16792a572a 100644
--- a/test/unit/memtx_allocator.cc
+++ b/test/unit/memtx_allocator.cc
@@ -88,10 +88,8 @@ alloc_tuple_count_cb(const void *stats_, void *ctx_)
 static int
 alloc_tuple_count()
 {
-	/* Trigger garbage collection before checking count. */
-	struct tuple *tuple = alloc_tuple();
-	fail_if(tuple == NULL);
-	free_tuple(tuple);
+	while (MemtxAllocator<SmallAlloc>::collect_garbage()) {
+	}
 	struct alloc_tuple_count_ctx ctx;
 	struct allocator_stats unused;
 	ctx.count = 0;
-- 
GitLab