diff options
| author | Mistivia <i@mistivia.com> | 2024-03-24 09:36:51 +0800 |
|---|---|---|
| committer | Mistivia <i@mistivia.com> | 2024-03-24 09:36:51 +0800 |
| commit | 1208bdd0fccc5f1e380053d8e0a7f4df6fe8f805 (patch) | |
| tree | a4fddb7211a2782b3934cf02d80ef6d1734ec1c2 /src/arena.c | |
git init
Diffstat (limited to 'src/arena.c')
| -rw-r--r-- | src/arena.c | 40 |
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; +} |
