aboutsummaryrefslogtreecommitdiff
path: root/src/mem.hff
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-11 20:27:48 +0200
committerlemon <lsof@mailbox.org>2022-08-11 20:27:48 +0200
commit19f1093f0929b989a06cdee2e7d175e6db15559c (patch)
treeacf82e3cb1b8e81ff132978b7656c178249c5f15 /src/mem.hff
parentc7961d732e5d67e8ea1b0be05e979bf24361f794 (diff)
things
Diffstat (limited to 'src/mem.hff')
-rw-r--r--src/mem.hff62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/mem.hff b/src/mem.hff
new file mode 100644
index 0000000..9fee910
--- /dev/null
+++ b/src/mem.hff
@@ -0,0 +1,62 @@
+import "all.hff";
+
+def ARENA_SIZE = 16 * 1024;
+
+struct ArenaRegion {
+ prev *ArenaRegion,
+ idx int,
+ mem [ARENA_SIZE]u8,
+}
+
+struct Arena {
+ r *ArenaRegion,
+
+ fn allocf(a *void, n usize) *void {
+ let a *Arena = a;
+ n = ALIGNUP(n, 16);
+ if ARENA_SIZE < n {
+ return xmalloc(n);
+ } else if a.r == #null {
+ a.r = xcalloc(1, sizeof ArenaRegion);
+ return allocf(a, n);
+ } else if ARENA_SIZE - a.r.idx >= n {
+ let ptr = &a.r.mem[a.r.idx];
+ a.r.idx += n;
+ return ptr;
+ } else {
+ let rp = xmalloc(sizeof ArenaRegion);
+ *rp = a.r;
+ let r = ArenaRegion { .prev: rp };
+ return allocf(a, n);
+ }
+ }
+}
+
+struct Mallocator {
+ fn allocf(*void, n usize) *void {
+ return xmalloc(n);
+ }
+
+ fn freef(*void, ptr *void) void {
+ free(ptr);
+ }
+}
+
+struct Allocator {
+ a *void,
+ allocf *fn(a *void, n usize) *void,
+ freef *fn(a *void, ptr *void) void,
+
+ fn alloc(self *Allocator, n usize) *void {
+ if self.allocf {
+ return self.allocf(self.a, n);
+ }
+ return #null;
+ }
+
+ fn free(self *Allocator, ptr *void) void {
+ if self.freef {
+ self.freef(self.a, ptr);
+ }
+ }
+}