Add mutex to virtual.Arena; add virtual.arena_temp_ignore

This commit is contained in:
gingerBill
2023-01-28 11:51:58 +00:00
parent ccf4b48865
commit 8d6ce0b693
2 changed files with 26 additions and 1 deletions

View File

@@ -1,6 +1,7 @@
package mem_virtual
import "core:mem"
import "core:sync"
Arena_Kind :: enum uint {
Growing = 0, // Chained memory blocks (singly linked list).
@@ -15,6 +16,7 @@ Arena :: struct {
total_reserved: uint,
minimum_block_size: uint,
temp_count: uint,
mutex: sync.Mutex,
}
@@ -78,6 +80,8 @@ arena_alloc :: proc(arena: ^Arena, size: uint, alignment: uint, loc := #caller_l
return nil, nil
}
sync.mutex_guard(&arena.mutex)
switch arena.kind {
case .Growing:
if arena.curr_block == nil || (safe_add(arena.curr_block.used, size) or_else 0) > arena.curr_block.reserved {
@@ -116,6 +120,8 @@ arena_alloc :: proc(arena: ^Arena, size: uint, alignment: uint, loc := #caller_l
}
arena_static_reset_to :: proc(arena: ^Arena, pos: uint, loc := #caller_location) -> bool {
sync.mutex_guard(&arena.mutex)
if arena.curr_block != nil {
assert(arena.kind != .Growing, "expected a non .Growing arena", loc)
@@ -135,6 +141,7 @@ arena_static_reset_to :: proc(arena: ^Arena, pos: uint, loc := #caller_location)
}
arena_growing_free_last_memory_block :: proc(arena: ^Arena, loc := #caller_location) {
sync.mutex_guard(&arena.mutex)
if free_block := arena.curr_block; free_block != nil {
assert(arena.kind == .Growing, "expected a .Growing arena", loc)
arena.curr_block = free_block.prev
@@ -145,6 +152,7 @@ arena_growing_free_last_memory_block :: proc(arena: ^Arena, loc := #caller_locat
arena_free_all :: proc(arena: ^Arena) {
switch arena.kind {
case .Growing:
sync.mutex_guard(&arena.mutex)
for arena.curr_block != nil {
arena_growing_free_last_memory_block(arena)
}
@@ -287,6 +295,8 @@ Arena_Temp :: struct {
@(require_results)
arena_temp_begin :: proc(arena: ^Arena, loc := #caller_location) -> (temp: Arena_Temp) {
assert(arena != nil, "nil arena", loc)
sync.mutex_guard(&arena.mutex)
temp.arena = arena
temp.block = arena.curr_block
if arena.curr_block != nil {
@@ -299,6 +309,7 @@ arena_temp_begin :: proc(arena: ^Arena, loc := #caller_location) -> (temp: Arena
arena_temp_end :: proc(temp: Arena_Temp, loc := #caller_location) {
assert(temp.arena != nil, "nil arena", loc)
arena := temp.arena
sync.mutex_guard(&arena.mutex)
memory_block_found := false
for block := arena.curr_block; block != nil; block = block.prev {
@@ -326,6 +337,16 @@ arena_temp_end :: proc(temp: Arena_Temp, loc := #caller_location) {
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
sync.mutex_guard(&arena.mutex)
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)
}

View File

@@ -7,6 +7,7 @@ DEFAULT_PAGE_SIZE := uint(4096)
Allocator_Error :: mem.Allocator_Error
@(require_results)
reserve :: proc "contextless" (size: uint) -> (data: []byte, err: Allocator_Error) {
return _reserve(size)
}
@@ -15,6 +16,7 @@ commit :: proc "contextless" (data: rawptr, size: uint) -> Allocator_Error {
return _commit(data, size)
}
@(require_results)
reserve_and_commit :: proc "contextless" (size: uint) -> (data: []byte, err: Allocator_Error) {
data = reserve(size) or_return
commit(raw_data(data), size) or_return
@@ -57,6 +59,7 @@ Memory_Block_Flag :: enum u32 {
Memory_Block_Flags :: distinct bit_set[Memory_Block_Flag; u32]
@(require_results)
memory_block_alloc :: proc(committed, reserved: uint, flags: Memory_Block_Flags) -> (block: ^Memory_Block, err: Allocator_Error) {
align_formula :: proc "contextless" (size, align: uint) -> uint {
result := size + align-1
@@ -100,6 +103,7 @@ memory_block_alloc :: proc(committed, reserved: uint, flags: Memory_Block_Flags)
return &pmblock.block, nil
}
@(require_results)
alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: uint) -> (data: []byte, err: Allocator_Error) {
calc_alignment_offset :: proc "contextless" (block: ^Memory_Block, alignment: uintptr) -> uint {
alignment_offset := uint(0)
@@ -160,7 +164,7 @@ memory_block_dealloc :: proc(block_to_free: ^Memory_Block) {
@(private)
@(private, require_results)
safe_add :: #force_inline proc "contextless" (x, y: uint) -> (uint, bool) {
z, did_overflow := intrinsics.overflow_add(x, y)
return z, !did_overflow