From cc2a07008e0eedef43c67c8ef9b55560ce2858b6 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada 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