v20-0010-Free-all-radix-tree-node-recursively.patch
application/octet-stream
Filename: v20-0010-Free-all-radix-tree-node-recursively.patch
Type: application/octet-stream
Part: 1
Patch
Format: format-patch
Series: patch v20-0010
Subject: Free all radix tree node recursively.
| File | + | − |
|---|---|---|
| src/include/lib/radixtree.h | 78 | 0 |
From cc2a07008e0eedef43c67c8ef9b55560ce2858b6 Mon Sep 17 00:00:00 2001
From: Masahiko Sawada <sawada.mshk@gmail.com>
Date: Thu, 19 Jan 2023 14:50:37 +0900
Subject: [PATCH v20 10/13] Free all radix tree node recursively.
---
src/include/lib/radixtree.h | 78 +++++++++++++++++++++++++++++++++++++
1 file changed, 78 insertions(+)
diff --git a/src/include/lib/radixtree.h b/src/include/lib/radixtree.h
index 4ed463ba51..fe94335d53 100644
--- a/src/include/lib/radixtree.h
+++ b/src/include/lib/radixtree.h
@@ -127,6 +127,7 @@
#define RT_ALLOC_NODE RT_MAKE_NAME(alloc_node)
#define RT_INIT_NODE RT_MAKE_NAME(init_node)
#define RT_FREE_NODE RT_MAKE_NAME(free_node)
+#define RT_FREE_RECURSE RT_MAKE_NAME(free_recurse)
#define RT_EXTEND RT_MAKE_NAME(extend)
#define RT_SET_EXTEND RT_MAKE_NAME(set_extend)
//#define RT_GROW_NODE_KIND RT_MAKE_NAME(grow_node_kind)
@@ -1408,6 +1409,78 @@ RT_GET_HANDLE(RT_RADIX_TREE *tree)
Assert(tree->ctl->magic == RT_RADIX_TREE_MAGIC);
return tree->ctl->handle;
}
+
+/*
+ * Recursively free all nodes allocated to the DSA area.
+ */
+static inline void
+RT_FREE_RECURSE(RT_RADIX_TREE *tree, RT_PTR_ALLOC ptr)
+{
+ RT_PTR_LOCAL node = RT_PTR_GET_LOCAL(tree, ptr);
+
+ check_stack_depth();
+ CHECK_FOR_INTERRUPTS();
+
+ /* The leaf node doesn't have child pointers */
+ if (NODE_IS_LEAF(node))
+ {
+ dsa_free(tree->dsa, ptr);
+ return;
+ }
+
+ switch (node->kind)
+ {
+ case RT_NODE_KIND_4:
+ {
+ RT_NODE_INNER_4 *n4 = (RT_NODE_INNER_4 *) node;
+
+ for (int i = 0; i < n4->base.n.count; i++)
+ RT_FREE_RECURSE(tree, n4->children[i]);
+
+ break;
+ }
+ case RT_NODE_KIND_32:
+ {
+ RT_NODE_INNER_32 *n32 = (RT_NODE_INNER_32 *) node;
+
+ for (int i = 0; i < n32->base.n.count; i++)
+ RT_FREE_RECURSE(tree, n32->children[i]);
+
+ break;
+ }
+ case RT_NODE_KIND_125:
+ {
+ RT_NODE_INNER_125 *n125 = (RT_NODE_INNER_125 *) node;
+
+ for (int i = 0; i < RT_NODE_MAX_SLOTS; i++)
+ {
+ if (!RT_NODE_125_IS_CHUNK_USED(&n125->base, i))
+ continue;
+
+ RT_FREE_RECURSE(tree, RT_NODE_INNER_125_GET_CHILD(n125, i));
+ }
+
+ break;
+ }
+ case RT_NODE_KIND_256:
+ {
+ RT_NODE_INNER_256 *n256 = (RT_NODE_INNER_256 *) node;
+
+ for (int i = 0; i < RT_NODE_MAX_SLOTS; i++)
+ {
+ if (!RT_NODE_INNER_256_IS_CHUNK_USED(n256, i))
+ continue;
+
+ RT_FREE_RECURSE(tree, RT_NODE_INNER_256_GET_CHILD(n256, i));
+ }
+
+ break;
+ }
+ }
+
+ /* Free the inner node */
+ dsa_free(tree->dsa, ptr);
+}
#endif
/*
@@ -1419,6 +1492,10 @@ RT_FREE(RT_RADIX_TREE *tree)
#ifdef RT_SHMEM
Assert(tree->ctl->magic == RT_RADIX_TREE_MAGIC);
+ /* Free all memory used for radix tree nodes */
+ if (RT_PTR_ALLOC_IS_VALID(tree->ctl->root))
+ RT_FREE_RECURSE(tree, tree->ctl->root);
+
/*
* Vandalize the control block to help catch programming error where
* other backends access the memory formerly occupied by this radix tree.
@@ -2197,6 +2274,7 @@ RT_DUMP(RT_RADIX_TREE *tree)
#undef RT_ALLOC_NODE
#undef RT_INIT_NODE
#undef RT_FREE_NODE
+#undef RT_FREE_RECURSE
#undef RT_EXTEND
#undef RT_SET_EXTEND
#undef RT_GROW_NODE_KIND
--
2.31.1