diff options
author | WormHeamer | 2025-02-28 17:00:08 -0500 |
---|---|---|
committer | WormHeamer | 2025-02-28 17:00:08 -0500 |
commit | 622624ab7ac364701f0bbb9164beb6f10ddb29fd (patch) | |
tree | e8717c319851f0dc95fe89b2d3a38a0073336249 | |
parent | 93608e2f90689c0eddd4714debcab9892f1dc7d7 (diff) |
add zone.h (memory arenas)
-rw-r--r-- | zone.h | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/zone.h b/zone.h new file mode 100644 index 0000000..4daa2fa --- /dev/null +++ b/zone.h @@ -0,0 +1,97 @@ +#ifndef ZONE_H +#define ZONE_H + +#include <stdint.h> + +#define ZONE_FRAME_CAPACITY_DEFAULT 1024 + +typedef struct ZoneFrame ZoneFrame; +struct ZoneFrame { + ZoneFrame *prev, *next; + size_t length, capacity; + uintptr_t data[]; +}; + +typedef struct { + ZoneFrame *tail, *here; +} Zone; + +void zn_free(Zone *z); +void zn_clear(Zone *z); + +void *zn_alloc(Zone *z, size_t n); +char *zn_strdup(Zone *z, const char *s); + +#ifdef ZONE_IMPL + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "zone.h" + +static ZoneFrame *zn_new_frame(size_t capacity) { + ZoneFrame *zf = malloc(sizeof *zf + capacity * sizeof(uintptr_t)); + if (!zf) { + fprintf(stderr, "failed to allocate memory zone frame\n"); + abort(); + } + zf->prev = NULL; + zf->next = NULL; + zf->length = 0; + zf->capacity = capacity; + return zf; +} + +void *zn_alloc(Zone *z, size_t n) { + ZoneFrame *zf = NULL; + size_t wordsz = (n + sizeof(uintptr_t) - 1) / sizeof(uintptr_t); + for (ZoneFrame *f = z->here; f; f = f->next) { + if (f->capacity - f->length >= wordsz) { + zf = f; + break; + } + } + if (!zf) { + size_t cap = ZONE_FRAME_CAPACITY_DEFAULT; + while (wordsz >= cap) cap <<= 1; + zf = zn_new_frame(cap); + zf->prev = z->tail; + if (z->tail) z->tail->next = zf; + z->tail = zf; + } + void *ptr = &zf->data[zf->length]; + zf->length += wordsz; + z->here = zf; + return ptr; +} + +void zn_free(Zone *z) { + ZoneFrame *p, *t; + t = z->tail; + while (t) { + p = t->prev; + free(t); + t = p; + } +} + +void zn_clear(Zone *z) { + ZoneFrame *zf = z->here; + if (!zf) return; + for (;;) { + zf->length = 0; + if (zf->prev) zf = zf->prev; + else break; + } + z->tail = zf; +} + +char *zn_strdup(Zone *z, const char *s) { + size_t n = strlen(s) + 1; + char *d = zn_alloc(z, n); + memcpy(d, s, n); + return d; +} + +#endif +#endif |