summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zone.h36
1 files changed, 22 insertions, 14 deletions
diff --git a/zone.h b/zone.h
index 59ffe2b..2525898 100644
--- a/zone.h
+++ b/zone.h
@@ -69,6 +69,7 @@ void *zn_zeroed(void *, size_t);
#include <unistd.h>
#define ZONE_PAGE_SIZE (ZONE_PAGE_MULT * sysconf(_SC_PAGE_SIZE))
+ #define ZONE_PAGE_FAIL MAP_FAILED
static void *zn_pg_alloc(size_t n) {
return mmap(NULL, n * ZONE_PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
@@ -80,9 +81,10 @@ void *zn_zeroed(void *, size_t);
#elif ZONE_BACKEND == ZONE_USE_MALLOC
#define ZONE_PAGE_SIZE (ZONE_PAGE_MULT * 4 * 1024)
+ #define ZONE_PAGE_FAIL NULL
static void zn_pg_alloc(size_t n) {
- eturn malloc(n * ZONE_PAGE_SIZE);
+ return malloc(n * ZONE_PAGE_SIZE);
}
static void zn_pg_free(void *p, size_t n) {
free(p);
@@ -100,6 +102,10 @@ static inline size_t zn_pg_fit(size_t cap) {
static ZoneFrame *zn_zf_new(size_t capacity) {
ZoneFrame *zf = zn_pg_alloc(capacity / ZONE_PAGE_SIZE);
+ if (zf == ZONE_PAGE_FAIL) {
+ fprintf(stderr, "failed to allocate zone frame\n");
+ abort();
+ }
zf->prev = NULL;
zf->next = NULL;
zf->beg = zf->data;
@@ -111,24 +117,26 @@ static void zn_zf_free(ZoneFrame *z) {
zn_pg_free(z, (uintptr_t)z->end - (uintptr_t)z->beg);
}
-#define PTR_ALIGN(ptr, align) (typeof(ptr))((uint8_t*)ptr + ((-(uintptr_t)ptr) & ((align)-1)))
+#define UPTR_ALIGN(x, align) ((x)+((-x)&((align)-1)))
+#define PTR_ALIGN(ptr, align) (typeof(ptr)) (((uintptr_t)ptr + (align - 1)) & -align)
void *zn_alloc_align(Zone *z, ptrdiff_t n, size_t align) {
ZoneFrame *zf = z->cur;
- while (zf && PTR_ALIGN(zf->beg, align) + n >= zf->end) {
+ uint8_t *aligned;
+ for (;;) {
+ if (!zf) {
+ zf = zn_zf_new(zn_pg_fit(n + sizeof(ZoneFrame) + align - 1));
+ zf->prev = z->tail;
+ if (z->tail) z->tail->next = zf;
+ z->tail = zf;
+ z->cur = zf;
+ }
+ aligned = PTR_ALIGN(zf->beg, align);
+ if (aligned + n < zf->end) break;
zf = zf->next;
}
- if (!zf) {
- zf = zn_zf_new(zn_pg_fit(n + sizeof(ZoneFrame) + align - 1));
- zf->prev = z->tail;
- if (z->tail) z->tail->next = zf;
- z->tail = zf;
- z->cur = zf;
- }
- zf->beg = PTR_ALIGN(zf->beg, align);
- void *p = zf->beg;
- zf->beg += n;
- return p;
+ zf->beg = aligned + n;
+ return aligned;
}
void *zn_realloc_align(Zone *z, void *ptr, ptrdiff_t oldsz, ptrdiff_t newsz, size_t align) {