mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
[mem]: API for using arena directly
This commit is contained in:
+38
-33
@@ -3,6 +3,13 @@ package mem
|
|||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
import "base:runtime"
|
import "base:runtime"
|
||||||
|
|
||||||
|
nil_allocator :: proc() -> Allocator {
|
||||||
|
return Allocator{
|
||||||
|
procedure = nil_allocator_proc,
|
||||||
|
data = nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nil_allocator_proc :: proc(
|
nil_allocator_proc :: proc(
|
||||||
allocator_data: rawptr,
|
allocator_data: rawptr,
|
||||||
mode: Allocator_Mode,
|
mode: Allocator_Mode,
|
||||||
@@ -14,13 +21,6 @@ nil_allocator_proc :: proc(
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
nil_allocator :: proc() -> Allocator {
|
|
||||||
return Allocator{
|
|
||||||
procedure = nil_allocator_proc,
|
|
||||||
data = nil,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Arena :: struct {
|
Arena :: struct {
|
||||||
data: []byte,
|
data: []byte,
|
||||||
offset: int,
|
offset: int,
|
||||||
@@ -56,6 +56,30 @@ arena_allocator :: proc(arena: ^Arena) -> Allocator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arena_alloc_non_zeroed :: proc(a: ^Arena, size: int, alignment := DEFAULT_ALIGNMENT) -> ([]byte, Allocator_Error) {
|
||||||
|
#no_bounds_check end := &a.data[a.offset]
|
||||||
|
ptr := align_forward(end, uintptr(alignment))
|
||||||
|
total_size := size + ptr_sub((^byte)(ptr), (^byte)(end))
|
||||||
|
if a.offset + total_size > len(a.data) {
|
||||||
|
return nil, .Out_Of_Memory
|
||||||
|
}
|
||||||
|
a.offset += total_size
|
||||||
|
a.peak_used = max(a.peak_used, a.offset)
|
||||||
|
return byte_slice(ptr, size), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
arena_alloc :: proc(a: ^Arena, size: int, alignment := DEFAULT_ALIGNMENT) -> ([]byte, Allocator_Error) {
|
||||||
|
bytes, err := arena_alloc_non_zeroed(a, size, alignment)
|
||||||
|
if bytes != nil {
|
||||||
|
zero(raw_data(bytes), size)
|
||||||
|
}
|
||||||
|
return bytes, err
|
||||||
|
}
|
||||||
|
|
||||||
|
arena_free_all :: proc(a: ^Arena) {
|
||||||
|
a.offset = 0
|
||||||
|
}
|
||||||
|
|
||||||
arena_allocator_proc :: proc(
|
arena_allocator_proc :: proc(
|
||||||
allocator_data: rawptr,
|
allocator_data: rawptr,
|
||||||
mode: Allocator_Mode,
|
mode: Allocator_Mode,
|
||||||
@@ -66,49 +90,28 @@ arena_allocator_proc :: proc(
|
|||||||
location := #caller_location,
|
location := #caller_location,
|
||||||
) -> ([]byte, Allocator_Error) {
|
) -> ([]byte, Allocator_Error) {
|
||||||
arena := cast(^Arena)allocator_data
|
arena := cast(^Arena)allocator_data
|
||||||
|
|
||||||
switch mode {
|
switch mode {
|
||||||
case .Alloc, .Alloc_Non_Zeroed:
|
case .Alloc:
|
||||||
#no_bounds_check end := &arena.data[arena.offset]
|
return arena_alloc(arena, size, alignment)
|
||||||
|
case .Alloc_Non_Zeroed:
|
||||||
ptr := align_forward(end, uintptr(alignment))
|
return arena_alloc_non_zeroed(arena, size, alignment)
|
||||||
|
|
||||||
total_size := size + ptr_sub((^byte)(ptr), (^byte)(end))
|
|
||||||
|
|
||||||
if arena.offset + total_size > len(arena.data) {
|
|
||||||
return nil, .Out_Of_Memory
|
|
||||||
}
|
|
||||||
|
|
||||||
arena.offset += total_size
|
|
||||||
arena.peak_used = max(arena.peak_used, arena.offset)
|
|
||||||
if mode != .Alloc_Non_Zeroed {
|
|
||||||
zero(ptr, size)
|
|
||||||
}
|
|
||||||
return byte_slice(ptr, size), nil
|
|
||||||
|
|
||||||
case .Free:
|
case .Free:
|
||||||
return nil, .Mode_Not_Implemented
|
return nil, .Mode_Not_Implemented
|
||||||
|
|
||||||
case .Free_All:
|
case .Free_All:
|
||||||
arena.offset = 0
|
arena_free_all(arena)
|
||||||
|
|
||||||
case .Resize:
|
case .Resize:
|
||||||
return default_resize_bytes_align(byte_slice(old_memory, old_size), size, alignment, arena_allocator(arena))
|
return default_resize_bytes_align(byte_slice(old_memory, old_size), size, alignment, arena_allocator(arena))
|
||||||
|
|
||||||
case .Resize_Non_Zeroed:
|
case .Resize_Non_Zeroed:
|
||||||
return default_resize_bytes_align_non_zeroed(byte_slice(old_memory, old_size), size, alignment, arena_allocator(arena))
|
return default_resize_bytes_align_non_zeroed(byte_slice(old_memory, old_size), size, alignment, arena_allocator(arena))
|
||||||
|
|
||||||
case .Query_Features:
|
case .Query_Features:
|
||||||
set := (^Allocator_Mode_Set)(old_memory)
|
set := (^Allocator_Mode_Set)(old_memory)
|
||||||
if set != nil {
|
if set != nil {
|
||||||
set^ = {.Alloc, .Alloc_Non_Zeroed, .Free_All, .Resize, .Resize_Non_Zeroed, .Query_Features}
|
set^ = {.Alloc, .Alloc_Non_Zeroed, .Free_All, .Resize, .Resize_Non_Zeroed, .Query_Features}
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
||||||
case .Query_Info:
|
case .Query_Info:
|
||||||
return nil, .Mode_Not_Implemented
|
return nil, .Mode_Not_Implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,6 +131,8 @@ end_arena_temp_memory :: proc(tmp: Arena_Temp_Memory) {
|
|||||||
tmp.arena.temp_count -= 1
|
tmp.arena.temp_count -= 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Scratch_Allocator :: struct {
|
Scratch_Allocator :: struct {
|
||||||
data: []byte,
|
data: []byte,
|
||||||
curr_offset: int,
|
curr_offset: int,
|
||||||
|
|||||||
Reference in New Issue
Block a user