|
|
@ -209,11 +209,54 @@ void insert_left(TreeAlloc** root_ptr, TreeAlloc* to_insert, TreeAlloc* before) |
|
|
|
repair_tree_after_insert(to_insert); |
|
|
|
} |
|
|
|
|
|
|
|
void *unalloc(Arena *arena, void *addr) { |
|
|
|
void unalloc(Arena *arena, void *addr) { |
|
|
|
if (arena->root_treealloc == NULL) { |
|
|
|
arena->error("attempt to unallocate when there are no allocations!"); |
|
|
|
return; |
|
|
|
} |
|
|
|
// Find the node this address belongs to |
|
|
|
TreeAlloc *node = search_by_address(arena->root_treealloc, addr); |
|
|
|
if (node == NULL) { |
|
|
|
arena->error("attempt to free memory outside any allocations!"); |
|
|
|
return; |
|
|
|
} |
|
|
|
// Handle the watermark allocator in this region |
|
|
|
if (node->type == RT_WATERMARK) { |
|
|
|
// TODO: handle watermark deallocation |
|
|
|
return; |
|
|
|
} |
|
|
|
// Get rid of it |
|
|
|
remove_node(&arena->root_treealloc, node); |
|
|
|
// If there's free space on either side of it, merge it with the free space into a bigger chunk of |
|
|
|
// free space. |
|
|
|
uintptr_t size = node->size; |
|
|
|
FreeSpace *start = (FreeSpace*) node; |
|
|
|
if (node->before != NULL && node->before->type == RT_FREESPACE) { |
|
|
|
start = (FreeSpace*) node->before; |
|
|
|
size += node->before->size; |
|
|
|
remove_node((TreeAlloc**) &arena->root_freespace, node->before); |
|
|
|
} |
|
|
|
if (node->after != NULL && node->after->type == RT_FREESPACE) { |
|
|
|
size += node->after->size; |
|
|
|
remove_node((TreeAlloc**) &arena->root_freespace, node->after); |
|
|
|
} |
|
|
|
start->type = RT_FREESPACE; |
|
|
|
start->size = size; |
|
|
|
// And finally, insert the resulting free space. |
|
|
|
if (arena->root_freespace == NULL) { |
|
|
|
insert_singleton((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) start); |
|
|
|
} else { |
|
|
|
TreeAlloc *insert_point = search_by_size((TreeAlloc*) arena->root_freespace, 0, 1, size); |
|
|
|
if (insert_point == NULL) { |
|
|
|
TreeAlloc *head = (TreeAlloc*) arena->root_freespace; |
|
|
|
while (head->right != NULL) { |
|
|
|
head = head->right; |
|
|
|
} |
|
|
|
insert_right((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) start, head); |
|
|
|
} else { |
|
|
|
insert_left((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) start, insert_point); |
|
|
|
} |
|
|
|
} |
|
|
|
// TODO |
|
|
|
} |
|
|
|
|
|
|
|