-package alloc
+package memory
use "progs/intrinsics"
// Need to define this somewhere
null :: cast(rawptr) 0;
+AllocAction :: enum {
+ Alloc;
+ Free;
+ Resize;
+}
+
+Allocator :: struct {
+ data: rawptr;
+ func: alloc_proc;
+}
+
+alloc_proc :: #type proc (rawptr, AllocAction, u32, u32, rawptr) -> rawptr;
+
+alloc :: proc (a: ^Allocator, size: u32) -> rawptr {
+ return a.func(a.data, AllocAction.Alloc, size, 16, null);
+}
+
+free :: proc (a: ^Allocator, ptr: rawptr) {
+ a.func(a.data, AllocAction.Free, 0, 0, ptr);
+}
+
+
+
+
+
+
+
+heap_allocator : Allocator;
+
heap_state : struct {
free_list : ^heap_block;
next_alloc : rawptr;
}
heap_block :: struct {
- size : i32;
+ size : u32;
next : ^heap_block;
}
heap_state.free_list = null;
heap_state.next_alloc = __heap_start;
heap_state.remaining_space = (memory_size() << 16) - cast(u32) __heap_start;
-}
-heap_align_to :: 16
+ heap_allocator.data = null;
+ heap_allocator.func = heap_alloc_proc;
+}
-heap_alloc :: proc (size_: i32) -> rawptr {
+heap_alloc :: proc (size_: u32, align: u32) -> rawptr {
if size_ == 0 return null;
size := size_ + sizeof heap_block;
- if size % heap_align_to != 0 {
- size += heap_align_to - (size % heap_align_to);
+ if size % align != 0 {
+ size += align - (size % align);
}
prev := ^heap_state.free_list;
return cast(rawptr) (cast(u32) ret + sizeof heap_block);
}
-
- // grow the memory with memory_grow
- return cast(rawptr) -1;
+
+ new_pages :: (size - heap_state.remaining_space) >> 16;
+ if memory_grow(new_pages) == -1 {
+ // out of memory
+ return null;
+ }
+ heap_state.remaining_space += new_pages << 16;
+
+ ret := cast(^heap_block) heap_state.next_alloc;
+ ret.size = size;
+ ret.next = null;
+
+ heap_state.next_alloc = cast(rawptr) (cast(u32) heap_state.next_alloc + size);
+ heap_state.remaining_space -= size;
+
+ return cast(rawptr) (cast(u32) ret + sizeof heap_block);
}
heap_free :: proc (ptr: rawptr) {
hb_ptr := cast(^heap_block) (cast(u32) ptr - sizeof heap_block);
hb_ptr.next = heap_state.free_list;
heap_state.free_list = hb_ptr;
-}
\ No newline at end of file
+}
+
+heap_alloc_proc :: proc (data: rawptr, aa: AllocAction, size: u32, align: u32, oldptr: rawptr) -> rawptr {
+ if aa == AllocAction.Alloc return heap_alloc(size, align);
+ if aa == AllocAction.Free {
+ heap_free(oldptr);
+ return null;
+ }
+
+ return null;
+}
use "progs/alloc"
use "progs/print_funcs"
-use package alloc
+use package memory
use package printing
proc #export "main" {
asdf :: "staring asdfkjasd asdflkjasdflkajsdflk";
heap_init();
- first := cast([] i32) heap_alloc(sizeof [4] i32);
+ first := cast([] i32) alloc(^heap_allocator, sizeof [4] i32);
for i: 0, 4 first[i] = i * 2;
- second := cast([] f32) heap_alloc(sizeof [24] f32);
+ second := cast([] f32) alloc(^heap_allocator, sizeof [24] f32);
for i: 0, 24 second[i] = cast(f32) i;
print(cast(u32) first);
for i: 0, 4 print(first[i]);
for i: 0, 24 print(second[i]);
- heap_free(first);
+ free(^heap_allocator, first);
- third := cast(^i32) heap_alloc(sizeof i32);
+ third := cast(^i32) alloc(^heap_allocator, sizeof i32);
print(cast(u32) third);
*third = 1234;
print(*third);
- heap_free(second);
+ free(^heap_allocator, second);
- fourth := cast([] i32) heap_alloc(sizeof [128]i32);
+ fourth := cast([] i32) alloc(^heap_allocator, sizeof [128]i32);
print(cast(u32) fourth);
- fifth := cast(^i32) heap_alloc(sizeof i32);
+ fifth := cast(^i32) alloc(^heap_allocator, sizeof i32);
print(cast(u32) fifth);
-
- sixth := heap_alloc(8 << 16);
- print(cast(u32) sixth);
}
\ No newline at end of file