diff options
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, + }; } |
