|
|
@ -12,9 +12,9 @@ void debug_print_tree(int indent, void *p) { |
|
|
|
if (node != NULL) { |
|
|
|
debug_print_tree(indent + 1, node->left); |
|
|
|
for (int ii = 0; ii < indent; ii++) { printf(" "); } |
|
|
|
if (node->color == COLOR_RED) { printf("\e[31"); } |
|
|
|
if (node->color == COLOR_RED) { printf("\e[31m"); } |
|
|
|
printf("%p %lu\n", node, node->size); |
|
|
|
if (node->color == COLOR_RED) { printf("\e[37"); } |
|
|
|
if (node->color == COLOR_RED) { printf("\e[37m"); } |
|
|
|
debug_print_tree(indent + 1, node->right); |
|
|
|
} |
|
|
|
} |
|
|
@ -173,7 +173,6 @@ void repair_tree_after_insert(TreeAlloc **root_ptr, TreeAlloc *ta) { |
|
|
|
ta->color = COLOR_BLACK; |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
TreeAlloc *grandparent = parent->parent; |
|
|
|
TreeAlloc *uncle = get_sibling(parent); |
|
|
|
|
|
|
@ -187,12 +186,13 @@ void repair_tree_after_insert(TreeAlloc **root_ptr, TreeAlloc *ta) { |
|
|
|
if (ta == parent->left && parent == grandparent->left) { |
|
|
|
rotate_left(root_ptr, parent); |
|
|
|
ta = ta->left; |
|
|
|
parent = parent->left; |
|
|
|
} else { |
|
|
|
rotate_right(root_ptr, parent); |
|
|
|
ta = ta->right; |
|
|
|
parent = parent->right; |
|
|
|
} |
|
|
|
|
|
|
|
parent = ta->parent; |
|
|
|
grandparent = parent->parent; |
|
|
|
if (ta == parent->left) { |
|
|
|
rotate_right(root_ptr, grandparent); |
|
|
@ -222,7 +222,7 @@ void repair_after_remove(TreeAlloc **root_ptr, TreeAlloc *node) { |
|
|
|
node->color = COLOR_BLACK; |
|
|
|
} else { |
|
|
|
TreeAlloc *sibling = get_sibling(node); |
|
|
|
if (sibling->color == COLOR_RED) { |
|
|
|
if (sibling != NULL && sibling->color == COLOR_RED) { |
|
|
|
if (node->parent->left == node) |
|
|
|
rotate_left(root_ptr, node->parent); |
|
|
|
else |
|
|
@ -261,6 +261,12 @@ void repair_after_remove(TreeAlloc **root_ptr, TreeAlloc *node) { |
|
|
|
|
|
|
|
void remove_node(TreeAlloc **root_ptr, TreeAlloc *node) { |
|
|
|
char do_repair = 0; |
|
|
|
#ifdef DEBUG |
|
|
|
printf("====== PRE-REMOVE ======\n"); |
|
|
|
printf("===== CURRENT TREE =====\n"); |
|
|
|
debug_print_tree(0, *root_ptr); |
|
|
|
printf("===== END OF TREES =====\n"); |
|
|
|
#endif |
|
|
|
TreeAlloc *replace; |
|
|
|
TreeAlloc *parent = node->parent; |
|
|
|
if (!node->left) { |
|
|
@ -287,7 +293,13 @@ void remove_node(TreeAlloc **root_ptr, TreeAlloc *node) { |
|
|
|
node->left->parent = tmp; |
|
|
|
} |
|
|
|
|
|
|
|
if (do_repair && replace) { |
|
|
|
if (do_repair && replace && replace->parent != NULL) { |
|
|
|
#ifdef DEBUG |
|
|
|
printf("=== PRE-REMOVE-FIXUP ===\n"); |
|
|
|
printf("===== CURRENT TREE =====\n"); |
|
|
|
debug_print_tree(0, *root_ptr); |
|
|
|
printf("===== END OF TREES =====\n"); |
|
|
|
#endif |
|
|
|
repair_after_remove(root_ptr, replace); |
|
|
|
} |
|
|
|
} |
|
|
@ -456,7 +468,15 @@ void *alloc(Arena *arena, uintptr_t size, uintptr_t align) { |
|
|
|
insert_singleton((TreeAlloc**) &arena->root_treealloc, region); |
|
|
|
} else { |
|
|
|
TreeAlloc *insert_point = search_by_address((TreeAlloc*) arena->root_treealloc, region); |
|
|
|
insert_right(&arena->root_treealloc, region, insert_point); |
|
|
|
if (insert_point == NULL) { |
|
|
|
TreeAlloc *head = arena->root_treealloc; |
|
|
|
while (head->left != NULL) { |
|
|
|
head = head->left; |
|
|
|
} |
|
|
|
insert_left(&arena->root_treealloc, region, head); |
|
|
|
} else { |
|
|
|
insert_right(&arena->root_treealloc, region, insert_point); |
|
|
|
} |
|
|
|
} |
|
|
|
if (new_free_size >= sizeof(FreeSpace)) { |
|
|
|
// If there's enough free space after the allocation, use it! |
|
|
@ -479,6 +499,10 @@ void *alloc(Arena *arena, uintptr_t size, uintptr_t align) { |
|
|
|
// region. |
|
|
|
region->after = succ(region); |
|
|
|
} |
|
|
|
// I seem to have forgotten about the fact that memory may not be contiguous |
|
|
|
if (region->after != NULL && region->after != (void*) region + region->size) { |
|
|
|
region->after = NULL; |
|
|
|
} |
|
|
|
// Also make sure the `before` pointer is correct. |
|
|
|
TreeAlloc *before_alloc = pred(region); |
|
|
|
if (before_alloc == NULL || ((void*) before_alloc) + before_alloc->size < (void*) region) { |
|
|
@ -486,6 +510,10 @@ void *alloc(Arena *arena, uintptr_t size, uintptr_t align) { |
|
|
|
} else { |
|
|
|
region->before = before_alloc; |
|
|
|
} |
|
|
|
// I seem to have forgotten about the fact that memory may not be contiguous |
|
|
|
if (region->before != NULL && region->before != (void*) region->before + region->before->size) { |
|
|
|
region->before = NULL; |
|
|
|
} |
|
|
|
#ifdef DEBUG |
|
|
|
printf("region is still at %p\n", region); |
|
|
|
#endif |
|
|
|