Browse Source

Fixed some bugs

tree_alloc
Thomas Johnson 1 year ago
parent
commit
fb70ac29e7
  1. 42
      tree_alloc.c

42
tree_alloc.c

@ -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

Loading…
Cancel
Save