aboutsummaryrefslogtreecommitdiff
path: root/src/mem.hff
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-14 09:25:16 +0200
committerlemon <lsof@mailbox.org>2022-08-14 09:25:16 +0200
commitc129f77ad724aa940b53a125de0e1e4de0ca7240 (patch)
tree57ad369bcfe02d0fb8a311c659e45cf2ae5df075 /src/mem.hff
parent66ed623e65ab9350f08061fe7cf12b989c84f65c (diff)
fix arena
Diffstat (limited to 'src/mem.hff')
-rw-r--r--src/mem.hff42
1 files changed, 28 insertions, 14 deletions
diff --git a/src/mem.hff b/src/mem.hff
index 84064f3..a86bee3 100644
--- a/src/mem.hff
+++ b/src/mem.hff
@@ -9,30 +9,44 @@ extern fn xrealloc(p *void, n usize) *void;
struct ArenaRegion {
prev *ArenaRegion,
- idx int,
- mem [ARENA_SIZE]u8,
+ idx usize,
+ siz usize,
+ mem [0]u8,
}
struct Arena {
r *ArenaRegion,
+ fn addregion(a *Arena, siz usize) void {
+ let r *ArenaRegion = xcalloc(sizeof ArenaRegion + siz, 1);
+ r.siz = siz;
+ r.prev = a.r;
+ a.r = r;
+ }
+
fn allocf(a *void, n usize) *void {
let a *Arena = a;
n = ALIGNUP(n, 16);
- if ARENA_SIZE < n {
- return xmalloc(n);
+ if n > ARENA_SIZE {
+ a->addregion(n);
+ return a.r.mem;
} 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;
+ a->addregion(ARENA_SIZE);
+ return allocf(a, n);
+ } else if n > a.r.siz - a.r.idx {
+ a->addregion(ARENA_SIZE);
+ return allocf(a, n);
} else {
- let rp *ArenaRegion = xmalloc(sizeof ArenaRegion);
- *rp = *a.r;
- let r = ArenaRegion { .prev: rp };
- return allocf(a, n);
+ let p = &a.r.mem[a.r.idx];
+ a.r.idx += n;
+ return p;
+ }
+ }
+
+ fn destroy(a *Arena) void {
+ for let r = a.r, next *ArenaRegion = #null; r; r = next {
+ next = r.prev;
+ free(r);
}
}
}