mirror of
https://github.com/Ed94/WATL_Exercise.git
synced 2025-08-06 07:12:42 -07:00
fleshing out odin ver more
This commit is contained in:
@@ -77,34 +77,31 @@ Raw_Slice :: struct {
|
|||||||
data: rawptr,
|
data: rawptr,
|
||||||
len: int,
|
len: int,
|
||||||
}
|
}
|
||||||
slice_assert :: proc "contextless" (s: $Type / []$SliceType) -> Type {
|
slice_assert :: proc "contextless" (s: $SliceType / []$Type) -> Type {
|
||||||
return assert(len(s) > 0) && assert(s != nil)
|
return assert(len(s) > 0) && assert(s != nil)
|
||||||
}
|
}
|
||||||
slice_end :: proc "contextless" (s : $Type / []$SliceType) -> Type {
|
slice_end :: proc "contextless" (s : $SliceType / []$Type) -> Type {
|
||||||
return s[len(s) - 1]
|
return s[len(s) - 1]
|
||||||
}
|
}
|
||||||
size_of_slice_type :: proc "contextless" (slice: $Type / []$SliceType) -> int {
|
|
||||||
return size_of(E)
|
|
||||||
}
|
|
||||||
@(require_results)
|
@(require_results)
|
||||||
slice_to_bytes :: proc "contextless" (s: []$Type) -> []byte {
|
slice_to_bytes :: proc "contextless" (s: []$Type) -> []byte {
|
||||||
return ([^]byte)(raw_data(s))[:len(s) * size_of(T)]
|
return ([^]byte)(raw_data(s))[:len(s) * size_of(Type)]
|
||||||
}
|
}
|
||||||
slice_zero :: proc "contextless" (data: $Type / []$SliceType) -> Type {
|
slice_zero :: proc "contextless" (data: $SliceType / []$Type) -> Type {
|
||||||
zero(raw_data(data), size_of(E) * len(data))
|
zero(raw_data(data), size_of(Type) * len(data))
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
slice_copy :: proc "contextless" (dst, src: $Ttype / []$SliceType) -> int {
|
slice_copy :: proc "contextless" (dst, src: $SliceType / []$Type) -> int {
|
||||||
n := max(0, min(len(dst), len(src)))
|
n := max(0, min(len(dst), len(src)))
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
intrinsics.mem_copy(raw_data(dst), raw_data(src), n*size_of(E))
|
intrinsics.mem_copy(raw_data(dst), raw_data(src), n * size_of(Type))
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
slice_copy_non_overlapping :: proc "contextless" (dst, src: $Type / []$SliceType) -> int {
|
slice_copy_non_overlapping :: proc "contextless" (dst, src: $SliceType / []$Type) -> int {
|
||||||
n := max(0, min(len(dst), len(src)))
|
n := max(0, min(len(dst), len(src)))
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
intrinsics.mem_copy_non_overlapping(raw_data(dst), raw_data(src), n*size_of(E))
|
intrinsics.mem_copy_non_overlapping(raw_data(dst), raw_data(src), n * size_of(Type))
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
@@ -130,7 +127,7 @@ sll_queue_push_n :: proc "contextless" (first: ^$SLL_NodeType, last: ^SLL_NodeTy
|
|||||||
}
|
}
|
||||||
//#endregion("Memory")
|
//#endregion("Memory")
|
||||||
|
|
||||||
//#region Allocator Interface
|
//#region("Allocator Interface")
|
||||||
AllocatorOp :: enum u32 {
|
AllocatorOp :: enum u32 {
|
||||||
Alloc_NoZero = 0, // If Alloc exist, so must No_Zero
|
Alloc_NoZero = 0, // If Alloc exist, so must No_Zero
|
||||||
Alloc,
|
Alloc,
|
||||||
@@ -144,15 +141,15 @@ AllocatorOp :: enum u32 {
|
|||||||
Query, // Must always be implemented
|
Query, // Must always be implemented
|
||||||
}
|
}
|
||||||
AllocatorQueryFlag :: enum u64 {
|
AllocatorQueryFlag :: enum u64 {
|
||||||
AllocatorQuery_Alloc,
|
Alloc,
|
||||||
AllocatorQuery_Free,
|
Free,
|
||||||
// Wipe the allocator's state
|
// Wipe the allocator's state
|
||||||
AllocatorQuery_Reset,
|
Reset,
|
||||||
// Supports both grow and shrink
|
// Supports both grow and shrink
|
||||||
AllocatorQuery_Shrink,
|
Shrink,
|
||||||
AllocatorQuery_Grow,
|
Grow,
|
||||||
// Ability to rewind to a save point (ex: arenas, stack), must also be able to save such a point
|
// Ability to rewind to a save point (ex: arenas, stack), must also be able to save such a point
|
||||||
AllocatorQuery_Rewind,
|
Rewind,
|
||||||
}
|
}
|
||||||
AllocatorQueryFlags :: bit_set[AllocatorQueryFlag; u64]
|
AllocatorQueryFlags :: bit_set[AllocatorQueryFlag; u64]
|
||||||
AllocatorSP :: struct {
|
AllocatorSP :: struct {
|
||||||
@@ -164,7 +161,10 @@ AllocatorProc_In :: struct {
|
|||||||
data: rawptr,
|
data: rawptr,
|
||||||
requested_size: int,
|
requested_size: int,
|
||||||
alignment: int,
|
alignment: int,
|
||||||
old_allocation: []byte,
|
using _ : struct #raw_union {
|
||||||
|
old_allocation: []byte,
|
||||||
|
save_point : AllocatorSP,
|
||||||
|
},
|
||||||
op: AllocatorOp,
|
op: AllocatorOp,
|
||||||
}
|
}
|
||||||
AllocatorProc_Out :: struct {
|
AllocatorProc_Out :: struct {
|
||||||
@@ -178,7 +178,7 @@ AllocatorProc_Out :: struct {
|
|||||||
min_alloc: int,
|
min_alloc: int,
|
||||||
continuity_break: b32,
|
continuity_break: b32,
|
||||||
}
|
}
|
||||||
AlllocatorQueryInfo :: struct {
|
AllocatorQueryInfo :: struct {
|
||||||
save_point: AllocatorSP,
|
save_point: AllocatorSP,
|
||||||
features: AllocatorQueryFlags,
|
features: AllocatorQueryFlags,
|
||||||
left: int,
|
left: int,
|
||||||
@@ -194,38 +194,106 @@ AllocatorInfo :: struct {
|
|||||||
|
|
||||||
MEMORY_ALIGNMENT_DEFAULT :: 2 * size_of(rawptr)
|
MEMORY_ALIGNMENT_DEFAULT :: 2 * size_of(rawptr)
|
||||||
|
|
||||||
allocator_query :: proc(ainfo: AllocatorInfo) -> AlllocatorQueryInfo {
|
allocator_query :: proc(ainfo: AllocatorInfo) -> AllocatorQueryInfo {
|
||||||
return {}
|
assert(ainfo.procedure != nil)
|
||||||
|
out: AllocatorQueryInfo; ainfo.procedure({data = ainfo.data, op = .Query}, transmute(^AllocatorProc_Out) & out)
|
||||||
|
return out
|
||||||
}
|
}
|
||||||
mem_free :: proc(ainfo: AllocatorInfo, mem: []byte) {
|
mem_free :: proc(ainfo: AllocatorInfo, mem: []byte) {
|
||||||
|
assert(ainfo.procedure != nil)
|
||||||
|
ainfo.procedure({data = ainfo.data, op = .Free, old_allocation = mem}, & {})
|
||||||
}
|
}
|
||||||
mem_reset :: proc(ainfo: AllocatorInfo) {
|
mem_reset :: proc(ainfo: AllocatorInfo) {
|
||||||
|
assert(ainfo.procedure != nil)
|
||||||
|
ainfo.procedure({data = ainfo.data, op = .Reset}, &{})
|
||||||
}
|
}
|
||||||
mem_rewind :: proc(ainfo: AllocatorInfo, save_point: AllocatorSP) {
|
mem_rewind :: proc(ainfo: AllocatorInfo, save_point: AllocatorSP) {
|
||||||
|
assert(ainfo.procedure != nil)
|
||||||
|
ainfo.procedure({data = ainfo.data, op = .Rewind, save_point = save_point}, & {})
|
||||||
}
|
}
|
||||||
mem_save_point :: proc(ainfo: AllocatorInfo) -> AllocatorSP {
|
mem_save_point :: proc(ainfo: AllocatorInfo) -> AllocatorSP {
|
||||||
return {}
|
assert(ainfo.procedure != nil)
|
||||||
|
out: AllocatorProc_Out
|
||||||
|
ainfo.procedure({data = ainfo.data, op = .SavePoint}, & out)
|
||||||
|
return out.save_point
|
||||||
}
|
}
|
||||||
mem_alloc :: proc(ainfo: AllocatorInfo, size: int, alignment: int = MEMORY_ALIGNMENT_DEFAULT, no_zero: b32 = false) -> []byte {
|
mem_alloc :: proc(ainfo: AllocatorInfo, size: int, alignment: int = MEMORY_ALIGNMENT_DEFAULT, no_zero: b32 = false) -> []byte {
|
||||||
return {}
|
assert(ainfo.procedure != nil)
|
||||||
|
input := AllocatorProc_In {
|
||||||
|
data = ainfo.data,
|
||||||
|
op = no_zero ? .Alloc_NoZero : .Alloc,
|
||||||
|
requested_size = size,
|
||||||
|
alignment = alignment,
|
||||||
|
}
|
||||||
|
output: AllocatorProc_Out
|
||||||
|
ainfo.procedure(input, & output)
|
||||||
|
return output.allocation
|
||||||
}
|
}
|
||||||
mem_grow :: proc(ainfo: AllocatorInfo, mem: []byte, size: int, alignment: int = MEMORY_ALIGNMENT_DEFAULT, no_zero: b32 = false) -> []byte {
|
mem_grow :: proc(ainfo: AllocatorInfo, mem: []byte, size: int, alignment: int = MEMORY_ALIGNMENT_DEFAULT, no_zero: b32 = false) -> []byte {
|
||||||
return {}
|
assert(ainfo.procedure != nil)
|
||||||
|
input := AllocatorProc_In {
|
||||||
|
data = ainfo.data,
|
||||||
|
op = no_zero ? .Grow_NoZero : .Grow,
|
||||||
|
requested_size = size,
|
||||||
|
alignment = alignment,
|
||||||
|
old_allocation = mem,
|
||||||
|
}
|
||||||
|
output: AllocatorProc_Out
|
||||||
|
ainfo.procedure(input, & output)
|
||||||
|
return output.allocation
|
||||||
}
|
}
|
||||||
mem_resize :: proc(ainfo: AllocatorInfo, mem: []byte, size: int, alignment: int = MEMORY_ALIGNMENT_DEFAULT, no_zero: b32 = false) -> []byte {
|
mem_resize :: proc(ainfo: AllocatorInfo, mem: []byte, size: int, alignment: int = MEMORY_ALIGNMENT_DEFAULT, no_zero: b32 = false) -> []byte {
|
||||||
return {}
|
assert(ainfo.procedure != nil)
|
||||||
|
input := AllocatorProc_In {
|
||||||
|
data = ainfo.data,
|
||||||
|
op = len(mem) < size ? .Shrink : no_zero ? .Grow_NoZero : .Grow,
|
||||||
|
requested_size = size,
|
||||||
|
alignment = alignment,
|
||||||
|
old_allocation = mem,
|
||||||
|
}
|
||||||
|
output: AllocatorProc_Out
|
||||||
|
ainfo.procedure(input, & output)
|
||||||
|
return output.allocation
|
||||||
}
|
}
|
||||||
mem_shrink :: proc(ainfo: AllocatorInfo, mem: []byte, size: int, alignment: int = MEMORY_ALIGNMENT_DEFAULT, no_zero: b32 = false) -> []byte {
|
mem_shrink :: proc(ainfo: AllocatorInfo, mem: []byte, size: int, alignment: int = MEMORY_ALIGNMENT_DEFAULT, no_zero: b32 = false) -> []byte {
|
||||||
return {}
|
assert(ainfo.procedure != nil)
|
||||||
|
input := AllocatorProc_In {
|
||||||
|
data = ainfo.data,
|
||||||
|
op = .Shrink,
|
||||||
|
requested_size = size,
|
||||||
|
alignment = alignment,
|
||||||
|
old_allocation = mem,
|
||||||
|
}
|
||||||
|
output: AllocatorProc_Out
|
||||||
|
ainfo.procedure(input, & output)
|
||||||
|
return output.allocation
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc_type :: proc(ainfo: AllocatorInfo, $Type: typeid) -> ^Type {
|
alloc_type :: proc(ainfo: AllocatorInfo, $Type: typeid, alignment: int = MEMORY_ALIGNMENT_DEFAULT, no_zero: b32 = false) -> ^Type {
|
||||||
return nil
|
assert(ainfo.procedure != nil)
|
||||||
|
input := AllocatorProc_In {
|
||||||
|
data = ainfo.data,
|
||||||
|
op = no_zero ? .Alloc_NoZero : .Alloc,
|
||||||
|
requested_size = size_of(Type),
|
||||||
|
alignment = alignment,
|
||||||
|
}
|
||||||
|
output: AllocatorProc_Out
|
||||||
|
ainfo.procedure(input, & output)
|
||||||
|
return transmute(^Type) raw_data(output.allocation)
|
||||||
}
|
}
|
||||||
alloc_slice :: proc(ainfo: AllocatorInfo, $Type: typeid, num : int) -> []Type {
|
alloc_slice :: proc(ainfo: AllocatorInfo, $SliceType: []$Type, num : int) -> []Type {
|
||||||
return {}
|
assert(ainfo.procedure != nil)
|
||||||
|
input := AllocatorProc_In {
|
||||||
|
data = ainfo.data,
|
||||||
|
op = no_zero ? .Alloc_NoZero : .Alloc,
|
||||||
|
requested_size = size_of(Type) * num,
|
||||||
|
alignment = alignment,
|
||||||
|
}
|
||||||
|
output: AllocatorProc_Out
|
||||||
|
ainfo.procedure(input, & output)
|
||||||
|
return transmute([]Type) Raw_Slice { raw_data(output.allocation), num }
|
||||||
}
|
}
|
||||||
//#endregion Allocator Interface
|
//#endregion("Allocator Interface")
|
||||||
|
|
||||||
//#region("Strings")
|
//#region("Strings")
|
||||||
Raw_String :: struct {
|
Raw_String :: struct {
|
||||||
@@ -234,7 +302,6 @@ Raw_String :: struct {
|
|||||||
}
|
}
|
||||||
//#endregion("Strings")
|
//#endregion("Strings")
|
||||||
|
|
||||||
|
|
||||||
//#region("FArena")
|
//#region("FArena")
|
||||||
FArena :: struct {
|
FArena :: struct {
|
||||||
mem: []byte,
|
mem: []byte,
|
||||||
@@ -287,7 +354,7 @@ VArena :: struct {
|
|||||||
commit_used: int,
|
commit_used: int,
|
||||||
flags: VArenaFlags,
|
flags: VArenaFlags,
|
||||||
}
|
}
|
||||||
varena_make :: proc(base_addr, reserve_size, commit_size: int, flags: VArenaFlags) -> VArena {
|
varena_make :: proc(reserve_size, commit_size: int, base_addr: int = 0, flags: VArenaFlags) -> ^VArena {
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
varena_push :: proc(va: ^VArena, $Type: typeid, amount: int, alignment: int = MEMORY_ALIGNMENT_DEFAULT) -> []Type {
|
varena_push :: proc(va: ^VArena, $Type: typeid, amount: int, alignment: int = MEMORY_ALIGNMENT_DEFAULT) -> []Type {
|
||||||
@@ -320,13 +387,23 @@ Arena :: struct {
|
|||||||
pos: int,
|
pos: int,
|
||||||
flags: ArenaFlags,
|
flags: ArenaFlags,
|
||||||
}
|
}
|
||||||
arena_make :: proc()
|
arena_make :: proc(reserve_size, commit_size: int, base_addr: int = 0, flags: ArenaFlags) -> ^Arena {
|
||||||
arena_push :: proc()
|
return nil
|
||||||
arena_release :: proc()
|
}
|
||||||
arena_reset :: proc()
|
arena_push :: proc(arena: ^Arena, $Type: typeid, amount: int, alignment: int = MEMORY_ALIGNMENT_DEFAULT) -> []Type {
|
||||||
arena_rewind :: proc()
|
return {}
|
||||||
arena_save :: proc()
|
}
|
||||||
arena_allocator_proc :: proc(input: AllocatorProc_In, output: AllocatorProc_Out)
|
arena_release :: proc(arena: ^Arena) {
|
||||||
|
}
|
||||||
|
arena_reset :: proc(arena: ^Arena) {
|
||||||
|
}
|
||||||
|
arena_rewind :: proc(arena: ^Arena, save_point: AllocatorSP) {
|
||||||
|
}
|
||||||
|
arena_save :: proc(arena: ^Arena) -> AllocatorSP {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
arena_allocator_proc :: proc(input: AllocatorProc_In, output: AllocatorProc_Out) {
|
||||||
|
}
|
||||||
//#endregion("Arena (Casey-Ryan Composite Arena")
|
//#endregion("Arena (Casey-Ryan Composite Arena")
|
||||||
|
|
||||||
//#region("Hashing")
|
//#region("Hashing")
|
||||||
@@ -362,7 +439,7 @@ KT1CX_Cell :: struct($type: typeid, $depth: int) {
|
|||||||
slots: [depth]KT1CX_Slot(type),
|
slots: [depth]KT1CX_Slot(type),
|
||||||
next: ^KT1CX_Cell(type, depth),
|
next: ^KT1CX_Cell(type, depth),
|
||||||
}
|
}
|
||||||
KT1CX :: struct($type: typeid, $depth: int, $cell: typeid / KT1CX_Cell(type, depth)) {
|
KT1CX :: struct($cell: typeid / KT1CX_Cell($type, $depth)) {
|
||||||
cell_pool: []cell,
|
cell_pool: []cell,
|
||||||
table: []cell,
|
table: []cell,
|
||||||
}
|
}
|
||||||
@@ -448,7 +525,7 @@ Str8Cache_CELL_DEPTH :: 4
|
|||||||
|
|
||||||
KT1CX_Slot_Str8 :: KT1CX_Slot(string)
|
KT1CX_Slot_Str8 :: KT1CX_Slot(string)
|
||||||
KT1CX_Cell_Str8 :: KT1CX_Cell(string, Str8Cache_CELL_DEPTH)
|
KT1CX_Cell_Str8 :: KT1CX_Cell(string, Str8Cache_CELL_DEPTH)
|
||||||
KT1CX_Str8 :: KT1CX(string, Str8Cache_CELL_DEPTH, KT1CX_Cell_Str8)
|
KT1CX_Str8 :: KT1CX(KT1CX_Cell_Str8)
|
||||||
Str8Cache :: struct {
|
Str8Cache :: struct {
|
||||||
str_reserve: AllocatorInfo,
|
str_reserve: AllocatorInfo,
|
||||||
cell_reserve: AllocatorInfo,
|
cell_reserve: AllocatorInfo,
|
||||||
|
Reference in New Issue
Block a user