Browse Source

Finished OOM handler and fixed some definite bugs

tree_alloc
Thomas Johnson 1 year ago
parent
commit
e86edef1ea
  1. 30
      tree_alloc.c

30
tree_alloc.c

@ -209,19 +209,29 @@ void insert_left(TreeAlloc** root_ptr, TreeAlloc* to_insert, TreeAlloc* before)
repair_tree_after_insert(to_insert);
}
int *add_new_region(Arena *arena, uintptr_t size, uintptr_t padding, uintptr_t align) {
uintptr_t realsize = size + align + padding - 1;
int add_new_region(Arena *arena, uintptr_t size, uintptr_t padding, uintptr_t align) {
uintptr_t realsize = size + align + alignof(WatermarkAlloc) + padding - 1;
if (realsize < MIN_NEW_MEM_SIZE) {
realsize = MIN_NEW_MEM_SIZE;
}
FreeSpace *newreg = (FreeSpace*) arena->get_new_region(size);
if (newreg == NULL) {
FreeSpace *reg = (FreeSpace*) arena->get_new_region(realsize);
if (reg == NULL) {
arena->error("can't allocate a new memory region!");
return 0;
}
FreeSpace *newreg = align_after(reg, alignof(WatermarkAlloc));
newreg->left = NULL;
newreg->right = NULL;
realsize -= (void*) newreg - (void*) reg;
realsize -= realsize % alignof(WatermarkAlloc);
if (arena->root_freespace == NULL) {
insert_singleton((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) newreg);
} else {
newreg = align_after(newreg, alignof(WatermarkAlloc));
newreg->left = NULL;
newreg->right = NULL;
FreeSpace *head = arena->root_freespace;
while (head->right != NULL) {
head = head->right;
}
insert_right((TreeAlloc**) arena->root_freespace, (TreeAlloc*) newreg, (TreeAlloc*) newreg);
}
return 1;
}
@ -277,18 +287,18 @@ void unalloc(Arena *arena, void *addr) {
}
void *alloc(Arena *arena, uintptr_t size, uintptr_t align) {
uintptr_t actual_align = lcm(alignof(struct WatermarkAlloc), align);
if (arena->root_freespace == NULL) {
// Handle being out of freespace.
if (!add_new_region(arena, size, sizeof(TreeAlloc), align)) {
if (!add_new_region(arena, size, sizeof(TreeAlloc), actual_align)) {
return NULL;
}
return alloc(arena, size, align);
} else {
uintptr_t actual_align = lcm(alignof(struct WatermarkAlloc), align);
TreeAlloc *region = search_by_size((TreeAlloc*) arena->root_freespace, sizeof(TreeAlloc), actual_align, size);
if (region == NULL) {
// Handle insufficient freespace or fragmentation.
if (!add_new_region(arena, size, sizeof(TreeAlloc), align)) {
if (!add_new_region(arena, size, sizeof(TreeAlloc), actual_align)) {
return NULL;
}
return alloc(arena, size, align);

Loading…
Cancel
Save