Browse Source

did we fix all the bugs yet?

tree_alloc
Thomas Johnson 1 year ago
parent
commit
83dcda7743
  1. 69
      tree_alloc.c

69
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) {

Loading…
Cancel
Save