diff options
| author | Syndamia <kamen@syndamia.com> | 2026-04-28 14:06:44 +0300 |
|---|---|---|
| committer | Syndamia <kamen@syndamia.com> | 2026-05-12 07:08:56 +0300 |
| commit | 0d249b1d47a7f84cfe5f09ad070d1affd26566da (patch) | |
| tree | f395f67eecb27daea3fc4a9ad8e59bf40f988984 /BumpAlloc.c | |
| parent | 5c36b582ad60a569ed996fe188ed92ef6bd7fc5f (diff) | |
| download | foollib-0d249b1d47a7f84cfe5f09ad070d1affd26566da.tar foollib-0d249b1d47a7f84cfe5f09ad070d1affd26566da.tar.gz foollib-0d249b1d47a7f84cfe5f09ad070d1affd26566da.zip | |
feat!: Refactor using MemoryManager
The idea is to provide a universal memory management "API", through
which you allocate and deallocate. This allows our implementations (for
String and Vector) to be more generic.
It does also allow usage of different allocators depending on situation.
Diffstat (limited to 'BumpAlloc.c')
| -rw-r--r-- | BumpAlloc.c | 133 |
1 files changed, 77 insertions, 56 deletions
diff --git a/BumpAlloc.c b/BumpAlloc.c index 1d1e1c1..09af8fa 100644 --- a/BumpAlloc.c +++ b/BumpAlloc.c @@ -3,54 +3,81 @@ #include <stdio.h> #include <stdlib.h> -struct BumpArena { +struct BumpAlloc { void* memory; usize size; usize top; }; -BumpArena -B_create(usize size) { - struct BumpArena *b = malloc(sizeof(struct BumpArena)); - b->memory = malloc(size); - b->size = size; - b->top = 0; +static inline usize* +top_size(struct BumpAlloc* b) { + return (usize*)(b->memory + b->top); +} + +static int +bump_resizeable(struct BumpAlloc *b, void *ptr) { + if (NULL == b) + return 0; - return b; + return b->memory + b->top - *top_size(b) <= ptr && + ptr < b->memory + b->top; } Result -B_destroy(BumpArena bp) { - if (NULL == bp) +bump_free(MemoryManager mm, void **ptr) { + if (NULL == mm.priv) return R_Uninitialized; - struct BumpArena b = *(struct BumpArena*)bp; + struct BumpAlloc *b = (struct BumpAlloc*)mm.priv; + + if (NULL != ptr) { + if (bump_resizeable(b, *ptr)) + *ptr = NULL; + else + return R_InvalidArgument; + } + + if (b->top > 0) { + b->top -= *top_size(b); + if (b->top > 0) + b->top -= sizeof(usize); + } + + return R_Ok; +} + +Result +bump_destroy(MemoryManager *mm) { + if (NULL == mm->priv) + return R_Uninitialized; + + struct BumpAlloc b = *(struct BumpAlloc*)mm->priv; if (NULL == b.memory) { - free(bp); + free(mm->priv); + mm->priv = NULL; return R_Uninitialized; } free(b.memory); - free(bp); + free(mm->priv); + mm->priv = NULL; return R_Ok; } -static inline usize* -top_size(struct BumpArena* b) { - return (usize*)(b->memory + b->top); -} +Result +bump_alloc(MemoryManager mm, void** ptr, usize size) { + if (NULL == mm.priv) + return R_Uninitialized; -void* -B_alloc(BumpArena bp, usize size) { - if (bp == NULL || size == 0) - return NULL; + if (0 == size || NULL == ptr) + return R_NullArgument; - struct BumpArena *b = (struct BumpArena*)bp; + struct BumpAlloc *b = (struct BumpAlloc*)mm.priv; if (size + b->top + sizeof(usize) > b->size) - return NULL; + return R_OutOfMemory; if (b->top > 0) b->top += sizeof(usize); @@ -60,37 +87,31 @@ B_alloc(BumpArena bp, usize size) { // Keep allocated memory size at the end of every allocation *top_size(b) = size; - return b->memory + start; -} - -int -B_resizeable(BumpArena bp, void* ptr) { - if (NULL == bp) - return 0; - - struct BumpArena *b = (struct BumpArena*)bp; - - return b->memory + b->top - *top_size(b) <= ptr && - ptr < b->memory + b->top; + *ptr = b->memory + start; + return R_Ok; } Result -B_resize(BumpArena bp, usize size) { - if (NULL == bp) +bump_resize(MemoryManager mm, void **ptr, usize size) { + if (NULL == mm.priv) return R_Uninitialized; - struct BumpArena *b = (struct BumpArena*)bp; + if (size == 0) + return bump_free(mm, ptr); - if (size == 0) { - B_free(bp); - return R_Ok; - } + if (NULL == ptr) + return R_NullArgument; + + struct BumpAlloc *b = (struct BumpAlloc*)mm.priv; + + if (NULL == ptr || !bump_resizeable(b, *ptr)) + return R_InvalidArgument; usize last_size = *top_size(b); usize start = b->top - last_size; if (start + size + sizeof(usize) > b->size) - return R_OutOfBounds; + return R_OutOfMemory; *top_size(b) = 0; b->top = start + size; @@ -99,18 +120,18 @@ B_resize(BumpArena bp, usize size) { return R_Ok; } -Result -B_free(BumpArena bp) { - if (NULL == bp) - return R_Uninitialized; - - struct BumpArena *b = (struct BumpArena*)bp; - - if (b->top > 0) { - b->top -= *top_size(b); - if (b->top > 0) - b->top -= sizeof(usize); - } +MemoryManager +M_bump(usize size) { + struct BumpAlloc *b = malloc(sizeof(struct BumpAlloc)); + b->memory = malloc(size); + b->size = size; + b->top = 0; - return R_Ok; + return (MemoryManager){ + .alloc = &bump_alloc, + .realloc = &bump_resize, + .free = &bump_free, + .destroy = &bump_destroy, + .priv = b, + }; } |
