aboutsummaryrefslogtreecommitdiff
path: root/BumpAlloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'BumpAlloc.c')
-rw-r--r--BumpAlloc.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/BumpAlloc.c b/BumpAlloc.c
new file mode 100644
index 0000000..327bfd5
--- /dev/null
+++ b/BumpAlloc.c
@@ -0,0 +1,116 @@
+#include "BumpAlloc.h"
+#include "Types.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+struct BumpArena {
+ void* memory;
+ usize size;
+ usize top;
+};
+
+BumpArena
+Bcreate(usize size) {
+ struct BumpArena *b = malloc(sizeof(struct BumpArena));
+ b->memory = malloc(size);
+ b->size = size;
+ b->top = 0;
+
+ return b;
+}
+
+Result
+Bdestroy(BumpArena bp) {
+ if (NULL == bp)
+ return R_Uninitialized;
+
+ struct BumpArena b = *(struct BumpArena*)bp;
+
+ if (NULL == b.memory)
+ return R_Uninitialized;
+
+ free(b.memory);
+ b.memory = NULL;
+ b.size = b.top = 0;
+
+ return R_Ok;
+}
+
+static inline usize*
+top_size(struct BumpArena* b) {
+ return (usize*)(b->memory + b->top);
+}
+
+void*
+Balloc(BumpArena bp, usize size) {
+ if (bp == NULL || size == 0)
+ return NULL;
+
+ struct BumpArena *b = (struct BumpArena*)bp;
+
+ if (size + b->top + sizeof(usize) > b->size)
+ return NULL;
+
+ if (b->top > 0)
+ b->top += sizeof(usize);
+ usize start = b->top;
+
+ b->top += size;
+ // Keep allocated memory size at the end of every allocation
+ *top_size(b) = size;
+
+ return b->memory + start;
+}
+
+int
+Bresizeable(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;
+}
+
+Result
+Bresize(BumpArena bp, usize size) {
+ if (NULL == bp)
+ return R_Uninitialized;
+
+ struct BumpArena *b = (struct BumpArena*)bp;
+
+ if (size == 0) {
+ Bfree(bp);
+ return R_Ok;
+ }
+
+ usize last_size = *top_size(b);
+ usize start = b->top - last_size;
+ if (start > 0)
+ start -= sizeof(usize);
+
+ if (start + size + sizeof(usize) > b->size)
+ return R_OutOfBounds;
+
+ b->top += size;
+ *top_size(b) = size;
+
+ return R_Ok;
+}
+
+Result
+Bfree(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);
+ }
+
+ return R_Ok;
+}