summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zone.h53
1 files changed, 42 insertions, 11 deletions
diff --git a/zone.h b/zone.h
index c2e033e..bce6796 100644
--- a/zone.h
+++ b/zone.h
@@ -3,8 +3,6 @@
#include <stdint.h>
-#define ZONE_FRAME_CAPACITY_DEFAULT 1024
-
typedef struct ZoneFrame ZoneFrame;
struct ZoneFrame {
ZoneFrame *prev, *next;
@@ -33,17 +31,50 @@ 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();
+#if defined(ZONE_USE_MMAP)
+
+ #include <sys/mman.h>
+ #include <unistd.h>
+
+ #define ZONE_CAPACITY ((sysconf(_SC_PAGE_SIZE) * 2 - sizeof(ZoneFrame))/sizeof(uintptr_t))
+ static ZoneFrame *zn_zf_allocate(size_t capacity) {
+ ZoneFrame *zf = mmap(NULL, sizeof *zf + capacity * sizeof(uintptr_t), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ if (!zf) {
+ fprintf(stderr, "failed to allocate memory zone frame\n");
+ abort();
+ }
+ return zf;
+ }
+ static void zn_zf_free(ZoneFrame *zf) {
+ munmap(zf, sizeof *zf + zf->capacity * sizeof(uintptr_t));
+ }
+
+#else
+
+ #include <stdlib.h>
+
+ #define ZONE_CAPACITY 1024
+ static ZoneFrame *zn_zf_allocate(size_t capacity) {
+ ZoneFrame *zf = malloc(sizeof *zf + capacity * sizeof(uintptr_t));
+ if (!zf) {
+ fprintf(stderr, "failed to allocate memory zone frame\n");
+ abort();
+ }
+ return zf;
}
+ static void zn_zf_free(ZoneFrame *zf) {
+ free(zf);
+ }
+
+#endif
+
+static ZoneFrame *zn_zf_new(size_t capacity) {
+ ZoneFrame *zf = zn_zf_allocate(capacity);
zf->prev = NULL;
zf->next = NULL;
zf->length = 0;
@@ -65,9 +96,9 @@ void *zn_zf_alloc(Zone *z, ZoneFrame **zfo, size_t n) {
}
}
if (!zf) {
- size_t cap = ZONE_FRAME_CAPACITY_DEFAULT;
+ size_t cap = ZONE_CAPACITY;
while (wordsz >= cap) cap <<= 1;
- zf = zn_new_frame(cap);
+ zf = zn_zf_new(cap);
zf->prev = z->tail;
if (z->tail) z->tail->next = zf;
z->tail = zf;
@@ -99,7 +130,7 @@ void zn_free(Zone *z) {
t = z->tail;
while (t) {
p = t->prev;
- free(t);
+ zn_zf_free(t);
t = p;
}
}