Browse Source

Added OOM/fragmentation handler

tree_alloc
Thomas Johnson 1 year ago
parent
commit
ba1438d3b9
  1. 2
      allocator_internal.h
  2. 29
      tree_alloc.c

2
allocator_internal.h

@ -13,6 +13,8 @@ const char RT_WATERMARK = 2;
const char COLOR_RED = 0;
const char COLOR_BLACK = 1;
const uintptr_t MIN_NEW_MEM_SIZE = 4096;
typedef struct Arena {
struct FreeSpace *root_freespace;
struct TreeAlloc *root_treealloc;

29
tree_alloc.c

@ -209,6 +209,23 @@ 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;
if (realsize < MIN_NEW_MEM_SIZE) {
realsize = MIN_NEW_MEM_SIZE;
}
FreeSpace *newreg = (FreeSpace*) arena->get_new_region(size);
if (newreg == NULL) {
arena->error("can't allocate a new memory region!");
return 0;
} else {
newreg = align_after(newreg, alignof(WatermarkAlloc));
newreg->left = NULL;
newreg->right = NULL;
}
return 1;
}
void unalloc(Arena *arena, void *addr) {
if (arena->root_treealloc == NULL) {
arena->error("attempt to unallocate when there are no allocations!");
@ -261,12 +278,20 @@ void unalloc(Arena *arena, void *addr) {
void *alloc(Arena *arena, uintptr_t size, uintptr_t align) {
if (arena->root_freespace == NULL) {
// TODO: handle out-of-memory
// Handle being out of freespace.
if (!add_new_region(arena, size, sizeof(TreeAlloc), 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) {
// TODO: handle memory fragmentation (or OOM)
// Handle insufficient freespace or fragmentation.
if (!add_new_region(arena, size, sizeof(TreeAlloc), align)) {
return NULL;
}
return alloc(arena, size, align);
}
remove_node((TreeAlloc**) &arena->root_freespace, region);
void *true_end = align_after(align_after(region + sizeof(TreeAlloc), actual_align) + size, alignof(WatermarkAlloc));

Loading…
Cancel
Save