diff options
author | WormHeamer | 2025-02-28 17:45:34 -0500 |
---|---|---|
committer | WormHeamer | 2025-02-28 17:45:34 -0500 |
commit | c2995c57c4a8a97c7a456e63d9f847b2809a31aa (patch) | |
tree | 4909c1b15e6890cce0212436765af07a1e566313 | |
parent | 7794a719c0114153ccbf009339e0f354eff8c1f5 (diff) |
add zn_zf_alloc, zn_zf_realloc
-rw-r--r-- | zone.h | 22 |
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; |