[mem]: Add resize_non_zeroed variant to dynamic arena, and rename pool to arena

This commit is contained in:
flysand7
2024-09-07 13:10:29 +11:00
parent 03f6b9bbf6
commit b350a35b77
+76 -50
View File
@@ -880,14 +880,14 @@ _dynamic_arena_cycle_new_block :: proc(p: ^Dynamic_Arena, loc := #caller_locatio
} }
@(private, require_results) @(private, require_results)
_dynamic_arena_alloc_ptr :: proc(pool: ^Dynamic_Arena, size: int, loc := #caller_location) -> (rawptr, Allocator_Error) { _dynamic_arena_alloc_ptr :: proc(a: ^Dynamic_Arena, size: int, loc := #caller_location) -> (rawptr, Allocator_Error) {
data, err := dynamic_arena_alloc(pool, size, loc) data, err := dynamic_arena_alloc(a, size, loc)
return raw_data(data), err return raw_data(data), err
} }
@(require_results) @(require_results)
dynamic_arena_alloc :: proc(p: ^Dynamic_Arena, size: int, loc := #caller_location) -> ([]byte, Allocator_Error) { dynamic_arena_alloc :: proc(a: ^Dynamic_Arena, size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
bytes, err := dynamic_arena_alloc_non_zeroed(p, size, loc) bytes, err := dynamic_arena_alloc_non_zeroed(a, size, loc)
if bytes != nil { if bytes != nil {
zero_slice(bytes) zero_slice(bytes)
} }
@@ -895,56 +895,91 @@ dynamic_arena_alloc :: proc(p: ^Dynamic_Arena, size: int, loc := #caller_locatio
} }
@(require_results) @(require_results)
dynamic_arena_alloc_non_zeroed :: proc(p: ^Dynamic_Arena, size: int, loc := #caller_location) -> ([]byte, Allocator_Error) { dynamic_arena_alloc_non_zeroed :: proc(a: ^Dynamic_Arena, size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
n := align_formula(size, p.alignment) n := align_formula(size, a.alignment)
if n > p.block_size { if n > a.block_size {
return nil, .Invalid_Argument return nil, .Invalid_Argument
} }
if n >= p.out_band_size { if n >= a.out_band_size {
assert(p.block_allocator.procedure != nil, "Backing block allocator must be initialized", loc=loc) assert(a.block_allocator.procedure != nil, "Backing block allocator must be initialized", loc=loc)
memory, err := alloc_bytes_non_zeroed(p.block_size, p.alignment, p.block_allocator, loc) memory, err := alloc_bytes_non_zeroed(a.block_size, a.alignment, a.block_allocator, loc)
if memory != nil { if memory != nil {
append(&p.out_band_allocations, raw_data(memory), loc = loc) append(&a.out_band_allocations, raw_data(memory), loc = loc)
} }
return memory, err return memory, err
} }
if p.bytes_left < n { if a.bytes_left < n {
err := _dynamic_arena_cycle_new_block(p, loc) err := _dynamic_arena_cycle_new_block(a, loc)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if p.current_block == nil { if a.current_block == nil {
return nil, .Out_Of_Memory return nil, .Out_Of_Memory
} }
} }
memory := p.current_pos memory := a.current_pos
p.current_pos = ([^]byte)(p.current_pos)[n:] a.current_pos = ([^]byte)(a.current_pos)[n:]
p.bytes_left -= n a.bytes_left -= n
return ([^]byte)(memory)[:size], nil return ([^]byte)(memory)[:size], nil
} }
dynamic_arena_reset :: proc(p: ^Dynamic_Arena, loc := #caller_location) { dynamic_arena_reset :: proc(a: ^Dynamic_Arena, loc := #caller_location) {
if p.current_block != nil { if a.current_block != nil {
append(&p.unused_blocks, p.current_block, loc=loc) append(&a.unused_blocks, a.current_block, loc=loc)
p.current_block = nil a.current_block = nil
} }
for block in p.used_blocks { for block in a.used_blocks {
append(&p.unused_blocks, block, loc=loc) append(&a.unused_blocks, block, loc=loc)
} }
clear(&p.used_blocks) clear(&a.used_blocks)
for a in p.out_band_allocations { for a in a.out_band_allocations {
free(a, p.block_allocator, loc=loc) free(a, a.block_allocator, loc=loc)
} }
clear(&p.out_band_allocations) clear(&a.out_band_allocations)
p.bytes_left = 0 // Make new allocations call `_dynamic_arena_cycle_new_block` again. a.bytes_left = 0 // Make new allocations call `_dynamic_arena_cycle_new_block` again.
} }
dynamic_arena_free_all :: proc(p: ^Dynamic_Arena) { dynamic_arena_free_all :: proc(a: ^Dynamic_Arena, loc := #caller_location) {
dynamic_arena_reset(p) dynamic_arena_reset(a)
for block in p.unused_blocks { for block in a.unused_blocks {
free(block, p.block_allocator) free(block, a.block_allocator, loc)
} }
clear(&p.unused_blocks) clear(&a.unused_blocks)
}
dynamic_arena_resize :: proc(
a: ^Dynamic_Arena,
old_memory: rawptr,
old_size: int,
size: int,
loc := #caller_location,
) -> ([]byte, Allocator_Error) {
bytes, err := dynamic_arena_resize_non_zeroed(a, old_memory, old_size, size, loc)
if bytes != nil {
if old_memory == nil {
zero_slice(bytes)
} else if size > old_size {
zero_slice(bytes[old_size:])
}
}
return bytes, err
}
dynamic_arena_resize_non_zeroed :: proc(
a: ^Dynamic_Arena,
old_memory: rawptr,
old_size: int,
size: int,
loc := #caller_location,
) -> ([]byte, Allocator_Error) {
if old_size >= size {
return byte_slice(old_memory, size), nil
}
data, err := dynamic_arena_alloc_non_zeroed(a, size, loc)
if err == nil {
runtime.copy(data, byte_slice(old_memory, old_size))
}
return data, err
} }
dynamic_arena_allocator_proc :: proc( dynamic_arena_allocator_proc :: proc(
@@ -956,35 +991,26 @@ dynamic_arena_allocator_proc :: proc(
old_size: int, old_size: int,
loc := #caller_location, loc := #caller_location,
) -> ([]byte, Allocator_Error) { ) -> ([]byte, Allocator_Error) {
pool := (^Dynamic_Arena)(allocator_data) arena := (^Dynamic_Arena)(allocator_data)
switch mode { switch mode {
case .Alloc: case .Alloc:
return dynamic_arena_alloc(pool, size, loc) return dynamic_arena_alloc(arena, size, loc)
case .Alloc_Non_Zeroed: case .Alloc_Non_Zeroed:
return dynamic_arena_alloc_non_zeroed(pool, size, loc) return dynamic_arena_alloc_non_zeroed(arena, size, loc)
case .Free: case .Free:
return nil, .Mode_Not_Implemented return nil, .Mode_Not_Implemented
case .Free_All: case .Free_All:
dynamic_arena_free_all(pool) dynamic_arena_free_all(arena, loc)
return nil, nil case .Resize:
case .Resize, .Resize_Non_Zeroed: return dynamic_arena_resize(arena, old_memory, old_size, size, loc)
if old_size >= size { case .Resize_Non_Zeroed:
return byte_slice(old_memory, size), nil return dynamic_arena_resize_non_zeroed(arena, old_memory, old_size, size, loc)
}
data, err := dynamic_arena_alloc(pool, size)
if err == nil {
runtime.copy(data, byte_slice(old_memory, old_size))
}
return data, err
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, .Query_Info} set^ = {.Alloc, .Alloc_Non_Zeroed, .Free_All, .Resize, .Resize_Non_Zeroed, .Query_Features, .Query_Info}
} }
return nil, nil return nil, nil
case .Query_Info: case .Query_Info:
info := (^Allocator_Query_Info)(old_memory) info := (^Allocator_Query_Info)(old_memory)
if info != nil && info.pointer != nil { if info != nil && info.pointer != nil {