From 83dcda77439371bd03b950bbbd2bc8f2c8e9c8d7 Mon Sep 17 00:00:00 2001 From: thajohns Date: Mon, 11 May 2020 04:17:44 -0400 Subject: [PATCH] did we fix all the bugs yet? --- tree_alloc.c | 69 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/tree_alloc.c b/tree_alloc.c index c8da89c..f7780f3 100644 --- a/tree_alloc.c +++ b/tree_alloc.c @@ -14,14 +14,15 @@ int debug_tree_black_height(TreeAlloc *node) { return ((node->color == COLOR_BLACK) ? 1 : 0) + debug_tree_black_height(node->left); } -void debug_print_tree(int indent, void *p) { +void debug_print_tree(int indent, void *p, int safe) { TreeAlloc *node = (TreeAlloc*) p; if (node != NULL) { int bad = debug_tree_black_height(node->left) != debug_tree_black_height(node->right); bad |= node->color == COLOR_RED && ((node->left != NULL && node->left->color == COLOR_RED) || (node->right != NULL && node->right->color == COLOR_RED) || (node->parent != NULL && node->parent->color == COLOR_RED)); - debug_print_tree(indent + 1, node->left); + bad &= !safe; + debug_print_tree(indent + 1, node->left, safe); for (int ii = 0; ii < indent; ii++) { printf(" "); } if (node->color == COLOR_RED) { printf("\e[31m"); } else if (bad) { printf("\e[30m]"); } @@ -29,7 +30,7 @@ void debug_print_tree(int indent, void *p) { printf("%p %lu\n", node, node->size); printf("\e[37m"); if (bad) { printf("\e[40m"); } - debug_print_tree(indent + 1, node->right); + debug_print_tree(indent + 1, node->right, safe); } } @@ -230,7 +231,7 @@ void insert_singleton(TreeAlloc **root_ptr, TreeAlloc *to_insert) { #ifdef DEBUG printf("= PRE-INSERT-SINGLETON =\n"); printf("===== CURRENT TREE =====\n"); - debug_print_tree(0, *root_ptr); + debug_print_tree(0, *root_ptr, 0); printf("===== END OF TREES =====\n"); #endif *root_ptr = to_insert; @@ -239,7 +240,7 @@ void insert_singleton(TreeAlloc **root_ptr, TreeAlloc *to_insert) { #ifdef DEBUG printf("= POST-INSERT-SINGLETON =\n"); printf("===== CURRENT TREE =====\n"); - debug_print_tree(0, *root_ptr); + debug_print_tree(0, *root_ptr, 0); printf("===== END OF TREES =====\n"); #endif } @@ -248,9 +249,9 @@ void insert_right(TreeAlloc** root_ptr, TreeAlloc* to_insert, TreeAlloc* after) #ifdef DEBUG printf("=== PRE-INSERT-RIGHT ===\n"); printf("===== INSERTING =====\n"); - debug_print_tree(0, to_insert); + debug_print_tree(0, to_insert, 0); printf("===== CURRENT TREE =====\n"); - debug_print_tree(0, *root_ptr); + debug_print_tree(0, *root_ptr, 0); printf("===== END OF TREES =====\n"); #endif if (after->right != NULL) { @@ -269,7 +270,7 @@ void insert_right(TreeAlloc** root_ptr, TreeAlloc* to_insert, TreeAlloc* after) #ifdef DEBUG printf("== POST-INSERT-FIXUP ===\n"); printf("===== CURRENT TREE =====\n"); - debug_print_tree(0, *root_ptr); + debug_print_tree(0, *root_ptr, 0); printf("===== END OF TREES =====\n"); #endif } @@ -278,9 +279,9 @@ void insert_left(TreeAlloc** root_ptr, TreeAlloc* to_insert, TreeAlloc* before) #ifdef DEBUG printf("=== PRE-INSERT-LEFT ====\n"); printf("===== INSERTING =====\n"); - debug_print_tree(0, to_insert); + debug_print_tree(0, to_insert, 0); printf("===== CURRENT TREE =====\n"); - debug_print_tree(0, *root_ptr); + debug_print_tree(0, *root_ptr, 0); printf("===== END OF TREES =====\n"); #endif if (before->left != NULL) { @@ -299,7 +300,7 @@ void insert_left(TreeAlloc** root_ptr, TreeAlloc* to_insert, TreeAlloc* before) #ifdef DEBUG printf("== POST-INSERT-FIXUP ===\n"); printf("===== CURRENT TREE =====\n"); - debug_print_tree(0, *root_ptr); + debug_print_tree(0, *root_ptr, 0); printf("===== END OF TREES =====\n"); #endif } @@ -318,7 +319,7 @@ void replace_node(TreeAlloc **root_ptr, TreeAlloc *node, TreeAlloc *replace) { void repair_after_remove(TreeAlloc **root_ptr, TreeAlloc *parent, TreeAlloc *node) { #ifdef DEBUG - printf("delete fixup at %p\n", node); + printf("delete fixup at %p -> %p\n", parent, node); #endif // In theory, the last two conditions should be the same ... if (IS_RED_NODE(node) || (node != NULL && node == *root_ptr)) { @@ -326,7 +327,7 @@ void repair_after_remove(TreeAlloc **root_ptr, TreeAlloc *parent, TreeAlloc *nod } else { TreeAlloc *sibling = get_sibling(parent, node); if (IS_RED_NODE(sibling)) { - if (node->parent->left == node) { + if (parent->left == node) { rotate_left(root_ptr, parent); } else { rotate_right(root_ptr, parent); @@ -377,34 +378,45 @@ void remove_node(TreeAlloc **root_ptr, TreeAlloc *to_remove) { char old_color; #ifdef DEBUG printf("====== PRE-REMOVE ======\n"); - printf("===== REMOVING =====\n"); - debug_print_tree(0, to_remove); + printf("======= REMOVING =======\n"); + debug_print_tree(0, to_remove, 0); printf("===== CURRENT TREE =====\n"); - debug_print_tree(0, *root_ptr); + debug_print_tree(0, *root_ptr, 0); printf("===== END OF TREES =====\n"); #endif TreeAlloc *replace, *parent_of_replace; TreeAlloc *parent = to_remove->parent; if (!to_remove->left) { +#ifdef DEBUG + printf("code path 1l\n"); +#endif replace = to_remove->right; parent_of_replace = to_remove->parent; do_repair = to_remove->color == COLOR_BLACK; replace_node(root_ptr, to_remove, replace); } else if (!to_remove->right) { +#ifdef DEBUG + printf("code path 1r\n"); +#endif replace = to_remove->left; parent_of_replace = to_remove->parent; do_repair = to_remove->color == COLOR_BLACK; replace_node(root_ptr, to_remove, replace); } else { +#ifdef DEBUG + printf("code path 2\n"); +#endif TreeAlloc *tmp = succ(to_remove); replace = tmp->right; - parent_of_replace = tmp->parent; do_repair = tmp->color == COLOR_BLACK; if (tmp != to_remove->right) { replace_node(root_ptr, tmp, replace); tmp->right = to_remove->right; to_remove->right->parent = tmp; - } + parent_of_replace = tmp->parent; + } else { + parent_of_replace = tmp; + } replace_node(root_ptr, to_remove, tmp); tmp->color = to_remove->color; tmp->left = to_remove->left; @@ -414,6 +426,13 @@ void remove_node(TreeAlloc **root_ptr, TreeAlloc *to_remove) { // Make sure that it doesn't have any tree pointers it shouldn't have. to_remove->parent = to_remove->left = to_remove->right = NULL; +#ifdef DEBUG + printf("==== PRE-REMOVE-FIXUP ===\n"); + printf("===== CURRENT TREE =====\n"); + debug_print_tree(0, *root_ptr, 1); + printf("===== END OF TREES =====\n"); + printf("considering fixing up %p -> %p\n", parent_of_replace, replace); +#endif if (replace && parent_of_replace == NULL) { replace->color = COLOR_BLACK; } else if (parent_of_replace != NULL && do_repair) { @@ -422,7 +441,7 @@ void remove_node(TreeAlloc **root_ptr, TreeAlloc *to_remove) { #ifdef DEBUG printf("=== POST-REMOVE ===\n"); printf("===== CURRENT TREE =====\n"); - debug_print_tree(0, *root_ptr); + debug_print_tree(0, *root_ptr, 0); printf("===== END OF TREES =====\n"); #endif } @@ -455,9 +474,9 @@ int add_new_region(Arena *arena, uintptr_t size, uintptr_t padding, uintptr_t al #ifdef DEBUG printf("= POST-REGION-CREATION =\n"); printf("==== FREESPACE TREE ====\n"); - debug_print_tree(0, arena->root_freespace); + debug_print_tree(0, arena->root_freespace, 0); printf("==== TREEALLOC TREE ====\n"); - debug_print_tree(0, arena->root_treealloc); + debug_print_tree(0, arena->root_treealloc, 0); printf("===== END OF TREES =====\n"); #endif return 1; @@ -467,9 +486,9 @@ void unalloc(Arena *arena, void *addr) { #ifdef DEBUG printf("==== UNALLOCATING ====\n"); printf("=== FREESPACE TREE ===\n"); - debug_print_tree(0, arena->root_freespace); + debug_print_tree(0, arena->root_freespace, 0); printf("=== TREEALLOC TREE ===\n"); - debug_print_tree(0, arena->root_treealloc); + debug_print_tree(0, arena->root_treealloc, 0); printf("==== END OF TREES ====\n"); #endif if (arena->root_treealloc == NULL) { @@ -526,9 +545,9 @@ void *alloc(Arena *arena, uintptr_t size, uintptr_t align) { #ifdef DEBUG printf("==== ALLOCATING =====\n"); printf("=== FREESPACE TREE ===\n"); - debug_print_tree(0, arena->root_freespace); + debug_print_tree(0, arena->root_freespace, 0); printf("=== TREEALLOC TREE ===\n"); - debug_print_tree(0, arena->root_treealloc); + debug_print_tree(0, arena->root_treealloc, 0); printf("==== END OF TREES ====\n"); #endif if (arena->root_freespace == NULL) {