mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Add Arena_Temp
This commit is contained in:
@@ -18,6 +18,7 @@ Arena :: struct {
|
|||||||
total_used: uint,
|
total_used: uint,
|
||||||
total_capacity: uint,
|
total_capacity: uint,
|
||||||
minimum_block_size: uint,
|
minimum_block_size: uint,
|
||||||
|
temp_count: uint,
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private, require_results)
|
@(private, require_results)
|
||||||
@@ -140,15 +141,20 @@ arena_init :: proc(arena: ^Arena, size: uint, backing_allocator: Allocator, loc
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// `arena_free_all` will free all but the first memory block, and then reset the memory block
|
arena_free_last_memory_block :: proc(arena: ^Arena, loc := #caller_location) {
|
||||||
arena_free_all :: proc(arena: ^Arena, loc := #caller_location) {
|
if free_block := arena.curr_block; free_block != nil {
|
||||||
for arena.curr_block != nil && arena.curr_block.prev != nil {
|
|
||||||
free_block := arena.curr_block
|
|
||||||
arena.curr_block = free_block.prev
|
arena.curr_block = free_block.prev
|
||||||
|
|
||||||
arena.total_capacity -= free_block.capacity
|
arena.total_capacity -= free_block.capacity
|
||||||
memory_block_dealloc(free_block, loc)
|
memory_block_dealloc(free_block, loc)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// `arena_free_all` will free all but the first memory block, and then reset the memory block
|
||||||
|
arena_free_all :: proc(arena: ^Arena, loc := #caller_location) {
|
||||||
|
for arena.curr_block != nil && arena.curr_block.prev != nil {
|
||||||
|
arena_free_last_memory_block(arena, loc)
|
||||||
|
}
|
||||||
|
|
||||||
if arena.curr_block != nil {
|
if arena.curr_block != nil {
|
||||||
intrinsics.mem_zero(arena.curr_block.base, arena.curr_block.used)
|
intrinsics.mem_zero(arena.curr_block.base, arena.curr_block.used)
|
||||||
@@ -225,3 +231,70 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Arena_Temp :: struct {
|
||||||
|
arena: ^Arena,
|
||||||
|
block: ^Memory_Block,
|
||||||
|
used: uint,
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
arena_temp_begin :: proc(arena: ^Arena, loc := #caller_location) -> (temp: Arena_Temp) {
|
||||||
|
assert(arena != nil, "nil arena", loc)
|
||||||
|
|
||||||
|
temp.arena = arena
|
||||||
|
temp.block = arena.curr_block
|
||||||
|
if arena.curr_block != nil {
|
||||||
|
temp.used = arena.curr_block.used
|
||||||
|
}
|
||||||
|
arena.temp_count += 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
arena_temp_end :: proc(temp: Arena_Temp, loc := #caller_location) {
|
||||||
|
assert(temp.arena != nil, "nil arena", loc)
|
||||||
|
arena := temp.arena
|
||||||
|
|
||||||
|
if temp.block != nil {
|
||||||
|
memory_block_found := false
|
||||||
|
for block := arena.curr_block; block != nil; block = block.prev {
|
||||||
|
if block == temp.block {
|
||||||
|
memory_block_found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !memory_block_found {
|
||||||
|
assert(arena.curr_block == temp.block, "memory block stored within Arena_Temp not owned by Arena", loc)
|
||||||
|
}
|
||||||
|
|
||||||
|
for arena.curr_block != temp.block {
|
||||||
|
arena_free_last_memory_block(arena)
|
||||||
|
}
|
||||||
|
|
||||||
|
if block := arena.curr_block; block != nil {
|
||||||
|
assert(block.used >= temp.used, "out of order use of arena_temp_end", loc)
|
||||||
|
amount_to_zero := min(block.used-temp.used, block.capacity-block.used)
|
||||||
|
intrinsics.mem_zero(block.base[temp.used:], amount_to_zero)
|
||||||
|
block.used = temp.used
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(arena.temp_count > 0, "double-use of arena_temp_end", loc)
|
||||||
|
arena.temp_count -= 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore the use of a `arena_temp_begin` entirely
|
||||||
|
arena_temp_ignore :: proc(temp: Arena_Temp, loc := #caller_location) {
|
||||||
|
assert(temp.arena != nil, "nil arena", loc)
|
||||||
|
arena := temp.arena
|
||||||
|
|
||||||
|
assert(arena.temp_count > 0, "double-use of arena_temp_end", loc)
|
||||||
|
arena.temp_count -= 1
|
||||||
|
}
|
||||||
|
|
||||||
|
arena_check_temp :: proc(arena: ^Arena, loc := #caller_location) {
|
||||||
|
assert(arena.temp_count == 0, "Arena_Temp not been ended", loc)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user