mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-04 06:38:47 +00:00
Remove mutex from Growing_Arena; Add Growing_Arena_Temp
This commit is contained in:
+73
-24
@@ -1,7 +1,6 @@
|
|||||||
package mem_virtual
|
package mem_virtual
|
||||||
|
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
import sync "core:sync/sync2"
|
|
||||||
|
|
||||||
Growing_Arena :: struct {
|
Growing_Arena :: struct {
|
||||||
curr_block: ^Memory_Block,
|
curr_block: ^Memory_Block,
|
||||||
@@ -9,12 +8,10 @@ Growing_Arena :: struct {
|
|||||||
total_allocated: int,
|
total_allocated: int,
|
||||||
|
|
||||||
minimum_block_size: int,
|
minimum_block_size: int,
|
||||||
|
temp_count: int,
|
||||||
ignore_mutex: bool,
|
|
||||||
mutex: sync.Mutex,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFAULT_MINIMUM_BLOCK_SIZE :: 8*1024*1024
|
DEFAULT_MINIMUM_BLOCK_SIZE :: 1024*1024 // 1 KiB should be enough
|
||||||
DEFAULT_PAGE_SIZE := 4096
|
DEFAULT_PAGE_SIZE := 4096
|
||||||
|
|
||||||
growing_arena_alloc :: proc(arena: ^Growing_Arena, min_size: int, alignment: int) -> (data: []byte, err: mem.Allocator_Error) {
|
growing_arena_alloc :: proc(arena: ^Growing_Arena, min_size: int, alignment: int) -> (data: []byte, err: mem.Allocator_Error) {
|
||||||
@@ -30,11 +27,7 @@ growing_arena_alloc :: proc(arena: ^Growing_Arena, min_size: int, alignment: int
|
|||||||
|
|
||||||
assert(mem.is_power_of_two(uintptr(alignment)))
|
assert(mem.is_power_of_two(uintptr(alignment)))
|
||||||
|
|
||||||
mutex := &arena.mutex
|
|
||||||
if !arena.ignore_mutex {
|
|
||||||
sync.mutex_lock(mutex)
|
|
||||||
}
|
|
||||||
|
|
||||||
size := 0
|
size := 0
|
||||||
if arena.curr_block != nil {
|
if arena.curr_block != nil {
|
||||||
size = min_size + align_forward_offset(arena, alignment)
|
size = min_size + align_forward_offset(arena, alignment)
|
||||||
@@ -62,27 +55,41 @@ growing_arena_alloc :: proc(arena: ^Growing_Arena, min_size: int, alignment: int
|
|||||||
assert(curr_block.used <= curr_block.size)
|
assert(curr_block.used <= curr_block.size)
|
||||||
arena.total_used += size
|
arena.total_used += size
|
||||||
|
|
||||||
if !arena.ignore_mutex {
|
|
||||||
sync.mutex_unlock(mutex)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ptr[:min_size], nil
|
return ptr[:min_size], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
growing_arena_free_last_memory_block :: proc(arena: ^Growing_Arena) {
|
||||||
|
free_block := arena.curr_block
|
||||||
|
arena.curr_block = free_block.prev
|
||||||
|
memory_dealloc(free_block)
|
||||||
|
}
|
||||||
|
|
||||||
growing_arena_free_all :: proc(arena: ^Growing_Arena) {
|
growing_arena_free_all :: proc(arena: ^Growing_Arena) {
|
||||||
mutex := &arena.mutex
|
|
||||||
if !arena.ignore_mutex {
|
|
||||||
sync.mutex_lock(mutex)
|
|
||||||
}
|
|
||||||
for arena.curr_block != nil {
|
for arena.curr_block != nil {
|
||||||
free_block := arena.curr_block
|
growing_arena_free_last_memory_block(arena)
|
||||||
arena.curr_block = free_block.prev
|
|
||||||
memory_dealloc(free_block)
|
|
||||||
}
|
}
|
||||||
arena.total_used = 0
|
arena.total_used = 0
|
||||||
if !arena.ignore_mutex {
|
}
|
||||||
sync.mutex_unlock(mutex)
|
|
||||||
}
|
growing_arena_bootstrap_new_by_offset :: proc($T: typeid, offset_to_arena: uintptr, minimum_block_size := DEFAULT_MINIMUM_BLOCK_SIZE) -> (ptr: ^T, err: mem.Allocator_Error) {
|
||||||
|
bootstrap: Growing_Arena
|
||||||
|
bootstrap.minimum_block_size = minimum_block_size
|
||||||
|
|
||||||
|
data := growing_arena_alloc(&bootstrap, size_of(T), align_of(T)) or_return
|
||||||
|
|
||||||
|
ptr = (^T)(raw_data(data))
|
||||||
|
|
||||||
|
(^Growing_Arena)(uintptr(ptr) + offset_to_arena)^ = bootstrap
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
growing_arena_bootstrap_new_by_name :: proc($T: typeid, $field_name: string, minimum_block_size := DEFAULT_MINIMUM_BLOCK_SIZE) -> (ptr: ^T, err: mem.Allocator_Error) {
|
||||||
|
return growing_arena_bootstrap_new_by_offset(T, offset_of_by_string(T, field_name), minimum_block_size)
|
||||||
|
}
|
||||||
|
growing_arena_bootstrap_new :: proc{
|
||||||
|
growing_arena_bootstrap_new_by_offset,
|
||||||
|
growing_arena_bootstrap_new_by_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
growing_arena_allocator :: proc(arena: ^Growing_Arena) -> mem.Allocator {
|
growing_arena_allocator :: proc(arena: ^Growing_Arena) -> mem.Allocator {
|
||||||
@@ -114,4 +121,46 @@ growing_arena_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator
|
|||||||
|
|
||||||
err = .Mode_Not_Implemented
|
err = .Mode_Not_Implemented
|
||||||
return
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Growing_Arena_Temp :: struct {
|
||||||
|
arena: ^Growing_Arena,
|
||||||
|
block: ^Memory_Block,
|
||||||
|
used: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
growing_arena_temp_begin :: proc(arena: ^Growing_Arena) -> (temp: Growing_Arena_Temp) {
|
||||||
|
temp.arena = arena
|
||||||
|
temp.block = arena.curr_block
|
||||||
|
if arena.curr_block != nil {
|
||||||
|
temp.used = arena.curr_block.used
|
||||||
|
}
|
||||||
|
arena.temp_count += 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
growing_arena_temp_end :: proc(temp: Growing_Arena_Temp, loc := #caller_location) {
|
||||||
|
assert(temp.arena != nil, "nil arena", loc)
|
||||||
|
arena := temp.arena
|
||||||
|
|
||||||
|
for arena.curr_block != temp.block {
|
||||||
|
growing_arena_free_last_memory_block(arena)
|
||||||
|
}
|
||||||
|
|
||||||
|
if block := arena.curr_block; block != nil {
|
||||||
|
|
||||||
|
assert(block.used >= temp.used, "out of order use of growing_arena_temp_end", loc)
|
||||||
|
amount_to_zero := min(block.used-temp.used, block.size-block.used)
|
||||||
|
|
||||||
|
block.used = temp.used
|
||||||
|
|
||||||
|
mem.zero_slice(block.base[block.used:][:amount_to_zero])
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(arena.temp_count > 0, "double-use of growing_arena_temp_end", loc)
|
||||||
|
arena.temp_count -= 1
|
||||||
|
}
|
||||||
|
|
||||||
|
growing_arena_check_temp :: proc(arena: ^Growing_Arena, loc := #caller_location) {
|
||||||
|
assert(condition = arena.temp_count == 0, loc = loc)
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user