v23-0004-Free-all-radix-tree-nodes-recursively.patch
application/octet-stream
Filename: v23-0004-Free-all-radix-tree-nodes-recursively.patch
Type: application/octet-stream
Part: 14
Patch
Format: format-patch
Series: patch v23-0004
Subject: Free all radix tree nodes recursively
| File | + | − |
|---|---|---|
| src/include/lib/radixtree.h | 78 | 0 |
From 9df198bc8781a4d619e4d8c4e584305ef560be48 Mon Sep 17 00:00:00 2001
From: Masahiko Sawada <sawada.mshk@gmail.com>
Date: Fri, 20 Jan 2023 12:38:54 +0700
Subject: [PATCH v23 04/18] Free all radix tree nodes recursively
TODO: Consider adding more general functionality to DSA
to free all segments.
---
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 bc0c0b5853..7fcd212ea4 100644
--- a/src/include/lib/radixtree.h
+++ b/src/include/lib/radixtree.h
@@ -139,6 +139,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_SWITCH_NODE_KIND RT_MAKE_NAME(grow_node_kind)
@@ -1458,6 +1459,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 (RT_NODE_IS_LEAF(node))
+ {
+ dsa_free(tree->dsa, ptr);
+ return;
+ }
+
+ switch (node->kind)
+ {
+ case RT_NODE_KIND_3:
+ {
+ RT_NODE_INNER_3 *n3 = (RT_NODE_INNER_3 *) node;
+
+ for (int i = 0; i < n3->base.n.count; i++)
+ RT_FREE_RECURSE(tree, n3->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
/*
@@ -1469,6 +1542,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.
@@ -2268,6 +2345,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_SWITCH_NODE_KIND
--
2.31.1