diff --git a/memory.jai b/memory.jai index 5b9bfe8..56c396f 100644 --- a/memory.jai +++ b/memory.jai @@ -64,6 +64,78 @@ make :: ($T: Type, $init := true) -> *T return ptr; } +Crash_Allocator :: Allocator.{ proc = crash_allocator_proc }; + +crash_allocator_proc :: (mode: Allocator_Mode, size: s64, old_size: s64, old_memory: *void, allocator_data: *void) -> *void { + message: string; + if mode == { + case .ALLOCATE; + message = basic.tprint("Attempt to allocate % byte(s) using the crash allocator!", size); + case .RESIZE; + message = basic.tprint("Attempt to resize (from % to % byte(s)) using the crash allocator!", old_size, size); + case .FREE; + message = basic.tprint("Attempt to free % byte(s) using the crash allocator!", size); + } + + basic.assert(false, message); + debug_break(); + return null; +} + +Arena :: struct { + memory: *void; + memory_size: u64; + offset: u64; +} + +init_arena :: (a: *Arena, memory: *void, size: u64) { + a.memory = memory; + a.memory_size = size; + a.offset = 0; +} + +arena_allocator_proc :: (mode: Allocator_Mode, size: s64, old_size: s64, old_memory: *void, allocator_data: *void) -> *void { + arena := allocator_data.(*Arena); + if mode == { + case .ALLOCATE; + return arena_alloc(arena, size); + + case .RESIZE; + if old_memory == null { + return arena_alloc(arena, size); + } + + if size == 0 { + return null; + } + + if size == old_size { + return old_memory; + } + + new_memory := arena_alloc(arena, size); + memcpy(new_memory, old_memory, old_size); + return new_memory; + case; + } + + return null; +} + +arena_alloc :: (a: *Arena, count: int, alignment := Default_Align, loc := #caller_location) -> *void { + basic.assert(a.memory != null, "arena: not initialized", loc = loc); + basic.assert(power_of_two(alignment)); + + end := a.memory.(*u8) + a.offset; + ptr := align_forward(end.(uint), alignment); + total_size := (count + ptr.(*u8) - end.(*u8)).(u64); + + basic.assert(a.offset + total_size <= a.memory_size, "arena: out of memory", loc = loc); + a.offset += total_size; + + return ptr.(*void); +} + #scope_file;