Init new repository
This commit is contained in:
68
examples/sandbox/arena.lc
Normal file
68
examples/sandbox/arena.lc
Normal file
@@ -0,0 +1,68 @@
|
||||
import "std_types";
|
||||
import libc "libc";
|
||||
|
||||
PAGE_SIZE :: 4096;
|
||||
|
||||
Arena :: struct {
|
||||
data: *u8;
|
||||
len: usize;
|
||||
commit: usize;
|
||||
reserve: usize;
|
||||
alignment: usize;
|
||||
}
|
||||
|
||||
GetAlignOffset :: proc(size: usize, align: usize): usize {
|
||||
mask: usize = align - 1;
|
||||
val: usize = size & mask;
|
||||
if val {
|
||||
val = align - val;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
AlignUp :: proc(size: usize, align: usize): usize {
|
||||
result := size + GetAlignOffset(size, align);
|
||||
return result;
|
||||
}
|
||||
|
||||
InitArena :: proc(arena: *Arena, reserve: usize) {
|
||||
aligned_reserve := AlignUp(reserve, PAGE_SIZE);
|
||||
data := VReserve(aligned_reserve);
|
||||
libc.assert(data != nil);
|
||||
|
||||
if data {
|
||||
arena.data = data;
|
||||
arena.reserve = aligned_reserve;
|
||||
arena.alignment = 8;
|
||||
}
|
||||
}
|
||||
|
||||
PushSize :: proc(arena: *Arena, size: usize): *void {
|
||||
libc.assert(arena.data != nil);
|
||||
|
||||
pointer := :usize(arena.data) + arena.len + size;
|
||||
align := GetAlignOffset(pointer, arena.alignment);
|
||||
aligned_size := size + align;
|
||||
|
||||
a := arena.len + aligned_size;
|
||||
if a > arena.commit {
|
||||
diff := a - arena.commit;
|
||||
commit_size := AlignUp(diff, PAGE_SIZE*4);
|
||||
libc.assert(commit_size + arena.commit <= arena.reserve);
|
||||
|
||||
if VCommit(&arena.data[arena.commit], commit_size) {
|
||||
arena.commit += commit_size;
|
||||
} else {
|
||||
libc.assert(false && "commit failed"[0]);
|
||||
}
|
||||
}
|
||||
|
||||
arena.len += align;
|
||||
result: *void = &arena.data[arena.len];
|
||||
arena.len += size;
|
||||
return result;
|
||||
}
|
||||
|
||||
TestArena :: proc() {
|
||||
arena: Arena;
|
||||
}
|
||||
Reference in New Issue
Block a user