aboutsummaryrefslogtreecommitdiff
path: root/BumpAlloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'BumpAlloc.c')
-rw-r--r--BumpAlloc.c133
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,
+ };
}