Browse Source

Added OOM/fragmentation handler

Thomas Johnson 1 year ago
parent
commit
ba1438d3b9
2 changed files with 29 additions and 2 deletions
  1. 2
    0
      allocator_internal.h
  2. 27
    2
      tree_alloc.c

+ 2
- 0
allocator_internal.h View File

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

+ 27
- 2
tree_alloc.c View File

@@ -209,6 +209,23 @@ void insert_left(TreeAlloc** root_ptr, TreeAlloc* to_insert, TreeAlloc* before)
209 209
 	repair_tree_after_insert(to_insert);
210 210
 }
211 211
 
212
+int *add_new_region(Arena *arena, uintptr_t size, uintptr_t padding, uintptr_t align) {
213
+    uintptr_t realsize = size + align + padding - 1;
214
+    if (realsize < MIN_NEW_MEM_SIZE) {
215
+      realsize = MIN_NEW_MEM_SIZE;
216
+    }
217
+    FreeSpace *newreg = (FreeSpace*) arena->get_new_region(size);
218
+    if (newreg == NULL) {
219
+      arena->error("can't allocate a new memory region!");
220
+      return 0;
221
+    } else {
222
+      newreg = align_after(newreg, alignof(WatermarkAlloc));
223
+      newreg->left = NULL;
224
+      newreg->right = NULL;
225
+    }
226
+    return 1;
227
+}
228
+
212 229
 void unalloc(Arena *arena, void *addr) {
213 230
   if (arena->root_treealloc == NULL) {
214 231
     arena->error("attempt to unallocate when there are no allocations!");
@@ -261,12 +278,20 @@ void unalloc(Arena *arena, void *addr) {
261 278
 
262 279
 void *alloc(Arena *arena, uintptr_t size, uintptr_t align) {
263 280
   if (arena->root_freespace == NULL) {
264
-    // TODO: handle out-of-memory
281
+    // Handle being out of freespace.
282
+    if (!add_new_region(arena, size, sizeof(TreeAlloc), align)) {
283
+      return NULL;
284
+    }
285
+    return alloc(arena, size, align);
265 286
   } else {
266 287
     uintptr_t actual_align = lcm(alignof(struct WatermarkAlloc), align);
267 288
     TreeAlloc *region = search_by_size((TreeAlloc*) arena->root_freespace, sizeof(TreeAlloc), actual_align, size);
268 289
     if (region == NULL) {
269
-      // TODO: handle memory fragmentation (or OOM)
290
+      // Handle insufficient freespace or fragmentation.
291
+      if (!add_new_region(arena, size, sizeof(TreeAlloc), align)) {
292
+        return NULL;
293
+      }
294
+      return alloc(arena, size, align);
270 295
     }
271 296
     remove_node((TreeAlloc**) &arena->root_freespace, region);
272 297
     void *true_end = align_after(align_after(region + sizeof(TreeAlloc), actual_align) + size, alignof(WatermarkAlloc));

Loading…
Cancel
Save