mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 07:08:48 +00:00
Add Arena_Kind.Buffer to core:mem/virtual
This commit is contained in:
+41
-10
@@ -3,8 +3,9 @@ package mem_virtual
|
|||||||
import "core:mem"
|
import "core:mem"
|
||||||
|
|
||||||
Arena_Kind :: enum uint {
|
Arena_Kind :: enum uint {
|
||||||
Growing = 0, // chained memory blocks (singly linked list)
|
Growing = 0, // Chained memory blocks (singly linked list).
|
||||||
Static = 1, // fixed reservation sized
|
Static = 1, // Fixed reservation sized.
|
||||||
|
Buffer = 2, // Uses a fixed sized buffer.
|
||||||
}
|
}
|
||||||
|
|
||||||
Arena :: struct {
|
Arena :: struct {
|
||||||
@@ -28,9 +29,9 @@ DEFAULT_ARENA_STATIC_RESERVE_SIZE :: 1<<30 when size_of(uintptr) == 8 else 1<<27
|
|||||||
|
|
||||||
@(require_results)
|
@(require_results)
|
||||||
arena_init_growing :: proc(arena: ^Arena, reserved: uint = DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE) -> (err: Allocator_Error) {
|
arena_init_growing :: proc(arena: ^Arena, reserved: uint = DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE) -> (err: Allocator_Error) {
|
||||||
arena.kind = .Growing
|
arena.kind = .Growing
|
||||||
arena.curr_block = memory_block_alloc(0, reserved, {}) or_return
|
arena.curr_block = memory_block_alloc(0, reserved, {}) or_return
|
||||||
arena.total_used = 0
|
arena.total_used = 0
|
||||||
arena.total_reserved = arena.curr_block.reserved
|
arena.total_reserved = arena.curr_block.reserved
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -38,8 +39,31 @@ arena_init_growing :: proc(arena: ^Arena, reserved: uint = DEFAULT_ARENA_GROWING
|
|||||||
|
|
||||||
@(require_results)
|
@(require_results)
|
||||||
arena_init_static :: proc(arena: ^Arena, reserved: uint, commit_size: uint = DEFAULT_ARENA_STATIC_COMMIT_SIZE) -> (err: Allocator_Error) {
|
arena_init_static :: proc(arena: ^Arena, reserved: uint, commit_size: uint = DEFAULT_ARENA_STATIC_COMMIT_SIZE) -> (err: Allocator_Error) {
|
||||||
arena.kind = .Static
|
arena.kind = .Static
|
||||||
arena.curr_block = memory_block_alloc(commit_size, reserved, {}) or_return
|
arena.curr_block = memory_block_alloc(commit_size, reserved, {}) or_return
|
||||||
|
arena.total_used = 0
|
||||||
|
arena.total_reserved = arena.curr_block.reserved
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
arena_init_buffer :: proc(arena: ^Arena, buffer: []byte) -> (err: Allocator_Error) {
|
||||||
|
if len(buffer) < size_of(Memory_Block) {
|
||||||
|
return .Out_Of_Memory
|
||||||
|
}
|
||||||
|
|
||||||
|
arena.kind = .Buffer
|
||||||
|
|
||||||
|
mem.zero_slice(buffer)
|
||||||
|
|
||||||
|
block_base := raw_data(buffer)
|
||||||
|
block := (^Memory_Block)(block_base)
|
||||||
|
block.base = block_base[size_of(Memory_Block):]
|
||||||
|
block.reserved = len(buffer) - size_of(Memory_Block)
|
||||||
|
block.committed = block.reserved
|
||||||
|
block.used = 0
|
||||||
|
|
||||||
|
arena.curr_block = block
|
||||||
arena.total_used = 0
|
arena.total_used = 0
|
||||||
arena.total_reserved = arena.curr_block.reserved
|
arena.total_reserved = arena.curr_block.reserved
|
||||||
return
|
return
|
||||||
@@ -80,6 +104,11 @@ arena_alloc :: proc(arena: ^Arena, size: uint, alignment: uint, loc := #caller_l
|
|||||||
}
|
}
|
||||||
arena_init_static(arena=arena, reserved=arena.minimum_block_size, commit_size=DEFAULT_ARENA_STATIC_COMMIT_SIZE) or_return
|
arena_init_static(arena=arena, reserved=arena.minimum_block_size, commit_size=DEFAULT_ARENA_STATIC_COMMIT_SIZE) or_return
|
||||||
}
|
}
|
||||||
|
fallthrough
|
||||||
|
case .Buffer:
|
||||||
|
if arena.curr_block == nil {
|
||||||
|
return nil, .Out_Of_Memory
|
||||||
|
}
|
||||||
data, err = alloc_from_memory_block(arena.curr_block, size, alignment)
|
data, err = alloc_from_memory_block(arena.curr_block, size, alignment)
|
||||||
arena.total_used = arena.curr_block.used
|
arena.total_used = arena.curr_block.used
|
||||||
}
|
}
|
||||||
@@ -88,7 +117,7 @@ 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 {
|
arena_static_reset_to :: proc(arena: ^Arena, pos: uint, loc := #caller_location) -> bool {
|
||||||
if arena.curr_block != nil {
|
if arena.curr_block != nil {
|
||||||
assert(arena.kind == .Static, "expected a .Static arena", loc)
|
assert(arena.kind != .Growing, "expected a non .Growing arena", loc)
|
||||||
|
|
||||||
prev_pos := arena.curr_block.used
|
prev_pos := arena.curr_block.used
|
||||||
arena.curr_block.used = clamp(pos, 0, arena.curr_block.reserved)
|
arena.curr_block.used = clamp(pos, 0, arena.curr_block.reserved)
|
||||||
@@ -120,7 +149,7 @@ arena_free_all :: proc(arena: ^Arena) {
|
|||||||
arena_growing_free_last_memory_block(arena)
|
arena_growing_free_last_memory_block(arena)
|
||||||
}
|
}
|
||||||
arena.total_reserved = 0
|
arena.total_reserved = 0
|
||||||
case .Static:
|
case .Static, .Buffer:
|
||||||
arena_static_reset_to(arena, 0)
|
arena_static_reset_to(arena, 0)
|
||||||
}
|
}
|
||||||
arena.total_used = 0
|
arena.total_used = 0
|
||||||
@@ -128,7 +157,9 @@ arena_free_all :: proc(arena: ^Arena) {
|
|||||||
|
|
||||||
arena_destroy :: proc(arena: ^Arena) {
|
arena_destroy :: proc(arena: ^Arena) {
|
||||||
arena_free_all(arena)
|
arena_free_all(arena)
|
||||||
memory_block_dealloc(arena.curr_block)
|
if arena.kind != .Buffer {
|
||||||
|
memory_block_dealloc(arena.curr_block)
|
||||||
|
}
|
||||||
arena.curr_block = nil
|
arena.curr_block = nil
|
||||||
arena.total_used = 0
|
arena.total_used = 0
|
||||||
arena.total_reserved = 0
|
arena.total_reserved = 0
|
||||||
|
|||||||
@@ -128,6 +128,10 @@ alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: uint)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if block == nil {
|
||||||
|
return nil, .Out_Of_Memory
|
||||||
|
}
|
||||||
|
|
||||||
alignment_offset := calc_alignment_offset(block, uintptr(alignment))
|
alignment_offset := calc_alignment_offset(block, uintptr(alignment))
|
||||||
size, size_ok := safe_add(min_size, alignment_offset)
|
size, size_ok := safe_add(min_size, alignment_offset)
|
||||||
if !size_ok {
|
if !size_ok {
|
||||||
|
|||||||
Reference in New Issue
Block a user