aboutsummaryrefslogtreecommitdiff
path: root/src/arena.c
diff options
context:
space:
mode:
authorMistivia <i@mistivia.com>2024-03-24 09:36:51 +0800
committerMistivia <i@mistivia.com>2024-03-24 09:36:51 +0800
commit1208bdd0fccc5f1e380053d8e0a7f4df6fe8f805 (patch)
treea4fddb7211a2782b3934cf02d80ef6d1734ec1c2 /src/arena.c
git init
Diffstat (limited to 'src/arena.c')
-rw-r--r--src/arena.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/arena.c b/src/arena.c
new file mode 100644
index 0000000..f45d11b
--- /dev/null
+++ b/src/arena.c
@@ -0,0 +1,40 @@
+#include "arena.h"
+
+#include <stdlib.h>
+
+void init_arena(arena_t *r, int blocksz) {
+ if (blocksz < 4096) blocksz = 4096;
+ r->head = (struct memblock){NULL, 0, blocksz};
+ r->head.buf = malloc(blocksz);
+ r->current = &(r->head);
+ r->blocksz = blocksz;
+}
+
+void destroy_arena(arena_t *r) {
+ free(r->head.buf);
+ struct memblock *cur = r->head.next;
+ while (cur != NULL) {
+ struct memblock *prev = cur;
+ cur = cur->next;
+ free(prev->buf);
+ free(prev);
+ }
+}
+
+void *arena_alloc(arena_t *r, int sz) {
+ int remain = r->current->cap - r->current->sz;
+ if (remain >= sz) {
+ void *ptr = r->current->buf + r->current->sz;
+ r->current->sz += sz;
+ return ptr;
+ }
+ int blocksz = sz > blocksz ? sz : blocksz;
+ struct memblock *nextblock = malloc(sizeof(struct memblock));
+ void *ptr = malloc(blocksz);
+ nextblock->buf = ptr;
+ nextblock->cap = blocksz;
+ nextblock->sz = sz;
+ r->current->next = nextblock;
+ r->current = nextblock;
+ return ptr;
+}