summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWormHeamer2025-02-28 17:45:34 -0500
committerWormHeamer2025-02-28 17:45:34 -0500
commitc2995c57c4a8a97c7a456e63d9f847b2809a31aa (patch)
tree4909c1b15e6890cce0212436765af07a1e566313
parent7794a719c0114153ccbf009339e0f354eff8c1f5 (diff)
add zn_zf_alloc, zn_zf_realloc
-rw-r--r--zone.h22
1 files changed, 22 insertions, 0 deletions
diff --git a/zone.h b/zone.h
index 4daa2fa..71ad926 100644
--- a/zone.h
+++ b/zone.h
@@ -20,6 +20,8 @@ void zn_free(Zone *z);
void zn_clear(Zone *z);
void *zn_alloc(Zone *z, size_t n);
+void *zn_zf_alloc(Zone *z, ZoneFrame **zf, size_t n);
+void *zn_zf_realloc(Zone *z, ZoneFrame **zf, void *ptr, size_t oldsz, size-t newsz);
char *zn_strdup(Zone *z, const char *s);
#ifdef ZONE_IMPL
@@ -43,6 +45,10 @@ static ZoneFrame *zn_new_frame(size_t capacity) {
}
void *zn_alloc(Zone *z, size_t n) {
+ return zn_zf_alloc(z, NULL, n);
+}
+
+void *zn_zf_alloc(Zone *z, ZoneFrame **zfo, 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) {
@@ -62,9 +68,25 @@ void *zn_alloc(Zone *z, size_t n) {
void *ptr = &zf->data[zf->length];
zf->length += wordsz;
z->here = zf;
+ if (zfo) *zfo = zf;
return ptr;
}
+void *zn_zf_realloc(Zone *z, ZoneFrame **zfo, void *old, size_t oldsz, size_t newsz) {
+ ZoneFrame *zf = *zfo;
+ size_t old_wordsz = (oldsz + sizeof(uintptr_t) - 1) / sizeof(uintptr_t);
+ size_t new_wordsz = (newsz + sizeof(uintptr_t) - 1) / sizeof(uintptr_t);
+ if (&zf->data[zf->length - old_wordsz] == old && zf->length + new_wordsz - old_wordsz <= zf->capacity) {
+ zf->length = zf->length + new_wordsz - old_wordsz;
+ return old;
+ } else {
+ void *new = zn_zf_alloc(z, zfo, newsz);
+ zf->length -= old_wordsz;
+ memcpy(new, old, oldsz);
+ return new;
+ }
+}
+
void zn_free(Zone *z) {
ZoneFrame *p, *t;
t = z->tail;