mirror of
https://github.com/Ed94/WATL_Exercise.git
synced 2025-08-05 14:52:44 -07:00
progress
This commit is contained in:
257
C/watl.v0.msvc.c
257
C/watl.v0.msvc.c
@@ -123,36 +123,36 @@ def_struct(tmpl(Slice,type)) { \
|
|||||||
type* ptr; \
|
type* ptr; \
|
||||||
SSIZE len; \
|
SSIZE len; \
|
||||||
}
|
}
|
||||||
|
#define slice_assert(slice) do { assert((slice).ptr != nullptr); assert((slice).len > 0); } while(0)
|
||||||
|
#define slice_end(slice) ((slice).ptr + (slice).len)
|
||||||
|
#define size_of_slice_type(slice) size_of( * (slice).ptr )
|
||||||
|
|
||||||
typedef def_Slice(void);
|
typedef def_Slice(void);
|
||||||
typedef def_Slice(Byte);
|
typedef def_Slice(Byte);
|
||||||
|
#define slice_byte(slice) (Slice_Byte){cast(Byte*, (slice).ptr), (slice).len * size_of_slice_type(slice)}
|
||||||
#define slice_fmem(mem) (Slice_Byte){ mem, size_of(mem) }
|
#define slice_fmem(mem) (Slice_Byte){ mem, size_of(mem) }
|
||||||
|
|
||||||
#define slice_assert(slice) do { assert((slice).ptr != nullptr); assert((slice).len > 0); } while(0)
|
|
||||||
|
|
||||||
#define slice_byte(slice) (Slice_Byte){cast(Byte*, (slice).ptr), (slice).len * size_of_slice_type(slice)}
|
|
||||||
#define size_of_slice_type(slice) size_of( * (slice).ptr )
|
|
||||||
|
|
||||||
void slice__copy(Slice_Byte dest, SSIZE dest_typewidth, Slice_Byte src, SSIZE src_typewidth);
|
void slice__copy(Slice_Byte dest, SSIZE dest_typewidth, Slice_Byte src, SSIZE src_typewidth);
|
||||||
void slice__zero(Slice_Byte mem, SSIZE typewidth);
|
void slice__zero(Slice_Byte mem, SSIZE typewidth);
|
||||||
|
|
||||||
#define slice_copy(dest, src) slice__copy(slice_byte(dest), size_of_slice_type(dest), slice_byte(src), size_of_slice_type(src))
|
#define slice_copy(dest, src) slice__copy(slice_byte(dest), size_of_slice_type(dest), slice_byte(src), size_of_slice_type(src))
|
||||||
#define slice_zero(slice) slice__zero(slice_byte(slice), size_of_slice_type(slice))
|
#define slice_zero(slice) slice__zero(slice_byte(slice), size_of_slice_type(slice))
|
||||||
|
|
||||||
#define slice_end(slice) ((slice).ptr + (slice).len)
|
|
||||||
|
|
||||||
#define slice_iter(container, iter) \
|
#define slice_iter(container, iter) \
|
||||||
typeof((container).ptr) iter = (container).ptr; \
|
typeof((container).ptr) iter = (container).ptr; \
|
||||||
iter != slice_end(container); \
|
iter != slice_end(container); \
|
||||||
++ iter
|
++ iter
|
||||||
|
|
||||||
#define slice_arg_from_array(type, ...) & (tmpl(Slice,type)) { \
|
#define slice_arg_from_array(type, ...) & (tmpl(Slice,type)) { \
|
||||||
.ptr = farray_init(type, __VA_ARGS__), \
|
.ptr = farray_init(type, __VA_ARGS__), \
|
||||||
.len = farray_len( farray_init(type, __VA_ARGS__)) \
|
.len = farray_len( farray_init(type, __VA_ARGS__)) \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define sll_stack_push_n(f, n, next) do { (n)->next = (f); (f) = (n); } while(0)
|
||||||
#pragma endregion Memory
|
#pragma endregion Memory
|
||||||
|
|
||||||
|
#pragma region Math
|
||||||
|
#define min(A, B) (((A) < (B)) ? (A) : (B))
|
||||||
|
#define max(A, B) (((A) > (B)) ? (A) : (B))
|
||||||
|
#pragma endregion Math
|
||||||
|
|
||||||
#pragma region Strings
|
#pragma region Strings
|
||||||
typedef unsigned char UTF8;
|
typedef unsigned char UTF8;
|
||||||
typedef def_Slice(UTF8);
|
typedef def_Slice(UTF8);
|
||||||
@@ -256,7 +256,7 @@ void farena_rewind(FArena* arena, AllocatorSP save_point);
|
|||||||
AllocatorSP farena_save (FArena arena);
|
AllocatorSP farena_save (FArena arena);
|
||||||
|
|
||||||
void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out);
|
void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out);
|
||||||
#define farena_allocator(arena) (AllocatorInfo){ farena_allocator_proc, & arena }
|
#define ainfo_farena(arena) (AllocatorInfo){ .proc = farena_allocator_proc, .data = & arena }
|
||||||
|
|
||||||
#define farena_push(arena, type, ...) \
|
#define farena_push(arena, type, ...) \
|
||||||
cast(type*, farena__push(arena, size_of(type), 1, opt_args(Opts_farena_push, lit(stringify(type)), __VA_ARGS__))).ptr
|
cast(type*, farena__push(arena, size_of(type), 1, opt_args(Opts_farena_push, lit(stringify(type)), __VA_ARGS__))).ptr
|
||||||
@@ -269,17 +269,24 @@ cast(type*, farena__push(arena, size_of(type), 1, opt_args(Opts_farena_push, lit
|
|||||||
typedef def_struct(OS_SystemInfo) {
|
typedef def_struct(OS_SystemInfo) {
|
||||||
SSIZE target_page_size;
|
SSIZE target_page_size;
|
||||||
};
|
};
|
||||||
|
typedef def_struct(Opts_vmem) {
|
||||||
|
void* base_addr;
|
||||||
|
B32 no_large_pages;
|
||||||
|
};
|
||||||
void os_init();
|
void os_init();
|
||||||
OS_SystemInfo* os_system_info();
|
OS_SystemInfo* os_system_info();
|
||||||
|
|
||||||
|
inline B32 os__vmem_commit(void* vm, SSIZE size, Opts_vmem* opts);
|
||||||
|
inline void os_vmem_release(void* vm, SSIZE size);
|
||||||
|
|
||||||
|
#define os_vmem_reserve(size, ...) os__vmem_reserve(size, opt_args(Opts_vmem, __VA_ARGS__))
|
||||||
|
#define os_vmem_commit(vm, size, ...) os__vmem_commit(vm, size, opt_args(Opts_vmem, __VA_ARGS__))
|
||||||
#pragma endregion OS
|
#pragma endregion OS
|
||||||
|
|
||||||
#pragma region VArena (Virutal Address Space Arena)
|
#pragma region VArena (Virutal Address Space Arena)
|
||||||
typedef def_struct(Opts_varena) {
|
typedef Opts_farena Opts_varena;
|
||||||
Str8 type_name;
|
|
||||||
SSIZE alignment;
|
|
||||||
};
|
|
||||||
typedef def_enum(U32, VArenaFlags) {
|
typedef def_enum(U32, VArenaFlags) {
|
||||||
VArenaFlag_Placeholder,
|
VArenaFlag_NoLargePages = (1 << 0),
|
||||||
};
|
};
|
||||||
typedef def_struct(VArena) {
|
typedef def_struct(VArena) {
|
||||||
SSIZE reserve_start;
|
SSIZE reserve_start;
|
||||||
@@ -298,21 +305,54 @@ typedef def_struct(Opts_varena_make) {
|
|||||||
VArena* varena__make(Opts_varena_make* opts);
|
VArena* varena__make(Opts_varena_make* opts);
|
||||||
#define varena_make(...) varena__make(opt_args(Opts_varena_make, __VA_ARGS__))
|
#define varena_make(...) varena__make(opt_args(Opts_varena_make, __VA_ARGS__))
|
||||||
|
|
||||||
void varena_commit (VArena* arena, SSIZE commit_size);
|
|
||||||
Slice_Byte varena__push (VArena* arena, SSIZE amount, SSIZE type_width, Opts_varena* opts);
|
Slice_Byte varena__push (VArena* arena, SSIZE amount, SSIZE type_width, Opts_varena* opts);
|
||||||
void varena_release(VArena* arena);
|
void varena_release(VArena* arena);
|
||||||
void varnea_rewind (VArena* arena, AllocatorSP save_point);
|
void varena_rewind (VArena* arena, AllocatorSP save_point);
|
||||||
AllocatorSP varnea_save (VArena* arena);
|
AllocatorSP varnea_save (VArena arena);
|
||||||
|
|
||||||
void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out);
|
void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out);
|
||||||
|
#define ainfo_varena(varena) (AllocatorInfo) { .proc = varena_allocator_proc, .data = varena }
|
||||||
|
|
||||||
#define varena_push(arena, type, ...) \
|
#define varena_push(arena, type, ...) \
|
||||||
cast(type*, varena__push(arena, 1, size_of(type), opt_args(Opts_varena, lit(stringify(type)), __VA_ARGS__) ).ptr)
|
cast(type*, varena__push(arena, 1, size_of(type), opt_args(Opts_varena, lit(stringify(type)), __VA_ARGS__) ).ptr)
|
||||||
|
|
||||||
#define varena_push_array(arena, type, amount, ...) \
|
#define varena_push_array(arena, type, amount, ...) \
|
||||||
(Slice ## type){ varena__push(arena, size_of(type), amount, opt_args(Opts_varena, lit(stringify(type)), __VA_ARGS__)).ptr, amount }
|
(tmpl(Slice,type)){ varena__push(arena, size_of(type), amount, opt_args(Opts_varena, lit(stringify(type)), __VA_ARGS__)).ptr, amount }
|
||||||
#pragma endregion VArnea
|
#pragma endregion VArnea
|
||||||
|
|
||||||
|
#pragma region Arena (Casey-Ryan Composite Arenas)
|
||||||
|
typedef Opts_varena Opts_arena;
|
||||||
|
typedef def_enum(U32, ArenaFlags) {
|
||||||
|
ArenaFlag_NoLargePages = (1 << 0),
|
||||||
|
ArenaFlag_NoChain = (1 << 1),
|
||||||
|
};
|
||||||
|
typedef def_struct(Arena) {
|
||||||
|
VArena* backing;
|
||||||
|
Arena* prev;
|
||||||
|
Arena* current;
|
||||||
|
SSIZE base_pos;
|
||||||
|
SSIZE pos;
|
||||||
|
ArenaFlags flags;
|
||||||
|
};
|
||||||
|
typedef Opts_varena_make Opts_arena_make;
|
||||||
|
Arena* arena__make (Opts_arena_make* opts);
|
||||||
|
Slice_Byte arena__push (Arena* arena, SSIZE amount, SSIZE type_width, Opts_arena* opts);
|
||||||
|
void arena_release(Arena* arena);
|
||||||
|
void arena_rewind (Arena* arena, AllocatorSP save_point);
|
||||||
|
AllocatorSP arena_save (Arena* arena);
|
||||||
|
|
||||||
|
void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out);
|
||||||
|
#define ainfo_arena(arena) (AllocatorInfo){ .proc = arena_allocator_proc, .data = arena }
|
||||||
|
|
||||||
|
#define arena_make(...) arena__make(opt_args(Opts_arena_make, __VA_ARGS__))
|
||||||
|
|
||||||
|
#define arena_push(arena, type, ...) \
|
||||||
|
cast(type*, arena__push(arena, 1, size_of(type), opt_args(Opts_arena, lit(stringify(type)), __VA_ARGS__) ).ptr)
|
||||||
|
|
||||||
|
#define arena_push_array(arena, type, amount, ...) \
|
||||||
|
(tmpl(Slice,type)){ arena__push(arena, size_of(type), amount, opt_args(Opts_arena, lit(stringify(type)), __VA_ARGS__)).ptr, amount }
|
||||||
|
#pragma endregion Arena
|
||||||
|
|
||||||
#pragma region Hashing
|
#pragma region Hashing
|
||||||
void hash64_djb8(U64* hash, Slice_Byte bytes) {
|
void hash64_djb8(U64* hash, Slice_Byte bytes) {
|
||||||
for (U8 const* elem = bytes.ptr; elem != (bytes.ptr + bytes.len); ++ elem) {
|
for (U8 const* elem = bytes.ptr; elem != (bytes.ptr + bytes.len); ++ elem) {
|
||||||
@@ -837,6 +877,7 @@ __declspec(dllimport) USIZE __stdcall GetLargePageMinimum(void);
|
|||||||
__declspec(dllimport) MS_BOOL __stdcall LookupPrivilegeValueW(MS_LPWSTR lpSystemName, MS_LPWSTR lpName, MS_PLUID lpLuid);
|
__declspec(dllimport) MS_BOOL __stdcall LookupPrivilegeValueW(MS_LPWSTR lpSystemName, MS_LPWSTR lpName, MS_PLUID lpLuid);
|
||||||
__declspec(dllimport) MS_BOOL __stdcall OpenProcessToken(MS_HANDLE ProcessHandle, MS_DWORD DesiredAccess, MS_PHANDLE TokenHandle);
|
__declspec(dllimport) MS_BOOL __stdcall OpenProcessToken(MS_HANDLE ProcessHandle, MS_DWORD DesiredAccess, MS_PHANDLE TokenHandle);
|
||||||
__declspec(dllimport) MS_LPVOID __stdcall VirtualAlloc(MS_LPVOID lpAddress, USIZE dwSize, MS_DWORD flAllocationType, MS_DWORD flProtect);
|
__declspec(dllimport) MS_LPVOID __stdcall VirtualAlloc(MS_LPVOID lpAddress, USIZE dwSize, MS_DWORD flAllocationType, MS_DWORD flProtect);
|
||||||
|
__declspec(dllimport) MS_BOOL __stdcall VirtualFree (MS_LPVOID lpAddress, USIZE dwSize, MS_DWORD dwFreeType);
|
||||||
|
|
||||||
typedef def_struct(OS_Windows_State) {
|
typedef def_struct(OS_Windows_State) {
|
||||||
OS_SystemInfo system_info;
|
OS_SystemInfo system_info;
|
||||||
@@ -862,22 +903,40 @@ void os__enable_large_pages() {
|
|||||||
CloseHandle(token);
|
CloseHandle(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
inline
|
||||||
void os_init() {
|
void os_init() {
|
||||||
os__enable_large_pages();
|
os__enable_large_pages();
|
||||||
OS_SystemInfo* info = & os__windows_info.system_info;
|
OS_SystemInfo* info = & os__windows_info.system_info;
|
||||||
info->target_page_size = (SSIZE)GetLargePageMinimum();
|
info->target_page_size = (SSIZE)GetLargePageMinimum();
|
||||||
}
|
}
|
||||||
void* os_reserve(SSIZE size) { void* result = VirtualAlloc(0, size, MS_MEM_RESERVE|MS_MEM_COMMIT|MS_MEM_LARGE_PAGES, MS_PAGE_READWRITE); return result; }
|
inline void* os__vmem_reserve(SSIZE size, Opts_vmem* opts) {
|
||||||
|
assert(opts != nullptr);
|
||||||
|
void* result = VirtualAlloc(opts->base_addr, size
|
||||||
|
, MS_MEM_RESERVE|MS_MEM_COMMIT|(opts->no_large_pages == false ? MS_MEM_LARGE_PAGES : 0)
|
||||||
|
, MS_PAGE_READWRITE
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
inline B32 os__vmem_commit(void* vm, SSIZE size, Opts_vmem* opts) {
|
||||||
|
assert(opts != nullptr);
|
||||||
|
if (opts->no_large_pages == false ) { return 1; }
|
||||||
|
B32 result = (VirtualAlloc(vm, size, MS_MEM_COMMIT, MS_PAGE_READWRITE) != 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
inline void os_vmem_release(void* vm, SSIZE size) { VirtualFree(vm, 0, MS_MEM_RESERVE); }
|
||||||
#pragma endregion OS
|
#pragma endregion OS
|
||||||
|
|
||||||
#pragma region VArena (Virutal Address Space Arena)
|
#pragma region VArena (Virutal Address Space Arena)
|
||||||
VArena* varena__make(Opts_varena_make* opts) {
|
VArena* varena__make(Opts_varena_make* opts) {
|
||||||
|
assert(opts != nullptr);
|
||||||
if (opts->reserve_size == 0) { opts->reserve_size = mega(64); }
|
if (opts->reserve_size == 0) { opts->reserve_size = mega(64); }
|
||||||
if (opts->commit_size == 0) { opts->commit_size = mega(64); }
|
if (opts->commit_size == 0) { opts->commit_size = mega(64); }
|
||||||
SSIZE reserve_size = align_pow2(opts->reserve_size, os_system_info()->target_page_size);
|
SSIZE reserve_size = align_pow2(opts->reserve_size, os_system_info()->target_page_size);
|
||||||
SSIZE commit_size = align_pow2(opts->commit_size, os_system_info()->target_page_size);
|
SSIZE commit_size = align_pow2(opts->commit_size, os_system_info()->target_page_size);
|
||||||
Byte* base = os_reserve(reserve_size); os_commit(base, commit_size);
|
B32 no_large_pages = (opts->flags & VArenaFlag_NoLargePages) != 0;
|
||||||
|
Byte* base = os_vmem_reserve(opts->base_addr, reserve_size, .no_large_pages = no_large_pages);
|
||||||
assert(base != nullptr);
|
assert(base != nullptr);
|
||||||
|
os_vmem_commit(base, commit_size, .no_large_pages = no_large_pages);
|
||||||
SSIZE header_size = align_pow2(size_of(VArena), MEMORY_ALIGNMENT_DEFAULT);
|
SSIZE header_size = align_pow2(size_of(VArena), MEMORY_ALIGNMENT_DEFAULT);
|
||||||
VArena* vm = cast(VArena*, base);
|
VArena* vm = cast(VArena*, base);
|
||||||
* vm = (VArena){
|
* vm = (VArena){
|
||||||
@@ -890,22 +949,155 @@ VArena* varena__make(Opts_varena_make* opts) {
|
|||||||
};
|
};
|
||||||
return vm;
|
return vm;
|
||||||
}
|
}
|
||||||
Slice_Byte varena__push(VArena* vm, SSIZE amount, SSIZE type_width, Opts_varena* opts)
|
Slice_Byte varena__push(VArena* vm, SSIZE amount, SSIZE type_width, Opts_varena* opts) {
|
||||||
{
|
|
||||||
assert(amount != 0);
|
assert(amount != 0);
|
||||||
SSIZE alignment = opts->alignment ? opts->alignment : MEMORY_ALIGNMENT_DEFAULT;
|
SSIZE alignment = opts->alignment ? opts->alignment : MEMORY_ALIGNMENT_DEFAULT;
|
||||||
SSIZE requested_size = amount * type_width;
|
SSIZE requested_size = amount * type_width;
|
||||||
SSIZE aligned_size = align_pow2(requested_size, alignment);
|
SSIZE aligned_size = align_pow2(requested_size, alignment);
|
||||||
|
|
||||||
SSIZE current_offset = vm->reserve_start + vm->commit_used;
|
SSIZE current_offset = vm->reserve_start + vm->commit_used;
|
||||||
SSIZE to_be_used = vm->commit_used + aligned_size;
|
SSIZE to_be_used = vm->commit_used + aligned_size;
|
||||||
SSIZE reserve_left = vm->reserve - vm->committed;
|
SSIZE reserve_left = vm->reserve - vm->committed;
|
||||||
assert(to_be_used < reserve_left);
|
assert(to_be_used < reserve_left);
|
||||||
|
SSIZE header_offset = vm->reserve_start - cast(SSIZE, vm);
|
||||||
return {};
|
SSIZE commit_left = vm->committed - vm->commit_used - header_offset;
|
||||||
|
B32 exhausted = commit_left < to_be_used;
|
||||||
|
if (exhausted)
|
||||||
|
{
|
||||||
|
SSIZE next_commit_size = reserve_left > 0 ? max(vm->commit_size, to_be_used) : cast(SSIZE, align_pow2( abs(reserve_left), os_system_info()->target_page_size));
|
||||||
|
if (next_commit_size) {
|
||||||
|
Byte* next_commit_start = cast(Byte*, cast(SSIZE, vm) + vm->committed);
|
||||||
|
B32 no_large_pages = (vm->flags & VArenaFlag_NoLargePages) != 0;
|
||||||
|
B32 commit_result = os_vmem_commit(next_commit_start, next_commit_size);
|
||||||
|
if (commit_result == false) {
|
||||||
|
return (Slice_Byte){0};
|
||||||
|
}
|
||||||
|
vm->committed += next_commit_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (Slice_Byte){.ptr = cast(Byte*, current_offset), .len = requested_size};
|
||||||
|
}
|
||||||
|
inline void varena_release(VArena* arena) { os_vmem_release(arena, arena->reserve); }
|
||||||
|
inline void varena_rewind (VArena* vm, AllocatorSP sp) { assert(vm != nullptr); vm->commit_used = sp.slot; }
|
||||||
|
inline AllocatorSP varena_save(VArena vm) { return (AllocatorSP){vm.commit_used}; }
|
||||||
|
void varena__allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
||||||
|
{
|
||||||
|
VArena* vm = cast(VArena*, in.data);
|
||||||
|
switch (in.op)
|
||||||
|
{
|
||||||
|
case AllocatorOp_Alloc_NoZero:
|
||||||
|
out->allocation = varena_push_array(vm, Byte, in.requested_size);
|
||||||
|
break;
|
||||||
|
case AllocatorOp_Alloc:
|
||||||
|
out->allocation = varena_push_array(vm, Byte, in.requested_size);
|
||||||
|
slice_zero(out->allocation);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AllocatorOp_Free:
|
||||||
|
break;
|
||||||
|
case AllocatorOp_Reset:
|
||||||
|
vm->commit_used = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AllocatorOp_Grow: {
|
||||||
|
SSIZE grow_amount = in.requested_size - in.old_allocation.len;
|
||||||
|
assert(grow_amount >= 0);
|
||||||
|
SSIZE current_offset = vm->reserve_start + vm->commit_used;
|
||||||
|
assert(in.old_allocation.ptr == current_offset);
|
||||||
|
Slice_Byte allocation = varena_push_array(vm, Byte, grow_amount, .alignment = in.alignment);
|
||||||
|
assert(allocation.ptr != nullptr);
|
||||||
|
out->allocation = (Slice_Byte){ in.old_allocation.ptr, in.requested_size };
|
||||||
|
slice_zero(allocation);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AllocatorOp_Grow_NoZero: {
|
||||||
|
SSIZE grow_amount = in.requested_size - in.old_allocation.len;
|
||||||
|
assert(grow_amount >= 0);
|
||||||
|
SSIZE current_offset = vm->reserve_start + vm->commit_used;
|
||||||
|
assert(in.old_allocation.ptr == current_offset);
|
||||||
|
Slice_Byte allocation = varena_push_array(vm, Byte, grow_amount, .alignment = in.alignment);
|
||||||
|
assert(allocation.ptr != nullptr);
|
||||||
|
out->allocation = (Slice_Byte){ in.old_allocation.ptr, in.requested_size };
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case AllocatorOp_Shrink: {
|
||||||
|
SSIZE current_offset = vm->reserve_start + vm->commit_used;
|
||||||
|
SSIZE shrink_amount = in.old_allocation.len - in.requested_size;
|
||||||
|
assert(shrink_amount >= 0);
|
||||||
|
assert(in.old_allocation.ptr == current_offset);
|
||||||
|
vm->commit_used -= shrink_amount;
|
||||||
|
out->allocation = (Slice_Byte){ in.old_allocation.ptr, in.requested_size };
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AllocatorOp_Rewind:
|
||||||
|
vm->commit_used = cast(SSIZE, in.old_allocation.ptr);
|
||||||
|
case AllocatorOp_SavePoint:
|
||||||
|
out->allocation.ptr = cast(Byte*, vm->commit_used);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AllocatorOp_Query:
|
||||||
|
out->features =
|
||||||
|
AllocatorQuery_Alloc
|
||||||
|
| AllocatorQuery_Resize
|
||||||
|
| AllocatorQuery_Reset
|
||||||
|
| AllocatorQuery_Rewind
|
||||||
|
;
|
||||||
|
out->max_alloc = vm->reserve - vm->committed;
|
||||||
|
out->min_alloc = kilo(4);
|
||||||
|
out->left = out->max_alloc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#pragma endregion VArena
|
#pragma endregion VArena
|
||||||
|
|
||||||
|
#pragma region Arena (Casey-Ryan Composite Arena)
|
||||||
|
Arena* arena__make(Opts_arena_make* opts) {
|
||||||
|
assert(opts != nullptr);
|
||||||
|
SSIZE header_size = align_pow2(size_of(Arena), MEMORY_ALIGNMENT_DEFAULT);
|
||||||
|
VArena* current = varena_make(opts);
|
||||||
|
assert(current != nullptr);
|
||||||
|
Arena* arena = varena_push(current, Arena);
|
||||||
|
* arena = {
|
||||||
|
.backing = varena;
|
||||||
|
.prev = nullptr;
|
||||||
|
.current = arena;
|
||||||
|
.base_pos = 0;
|
||||||
|
.pos = header_size;
|
||||||
|
.flags = opts->flags;
|
||||||
|
}
|
||||||
|
return arena;
|
||||||
|
}
|
||||||
|
Slice_Byte arena__push(Arena* arena, SSIZE amount, SSIZE type_width, Opts_arena* opts) {
|
||||||
|
assert(opts != nullptr);
|
||||||
|
Arena* active = arena->current;
|
||||||
|
SSIZE size_requested = amount * type_width;
|
||||||
|
SSIZE alignment = opts->alignment ? opts->alignment : MEMORY_ALIGNMENT_DEFAULT;
|
||||||
|
SSIZE size_aligned = align_pow2(size_requested, alignment);
|
||||||
|
SSIZE pos_pre = align_pow2(current->pos, alignment);
|
||||||
|
SSIZE pos_pst = pos_pre + size_requested;
|
||||||
|
B32 should_chain =
|
||||||
|
((arena->flags & ArenaFlag_NoChain) == 0)
|
||||||
|
&& current->backing->reserve < pos_pst;
|
||||||
|
if (should_chain)
|
||||||
|
{
|
||||||
|
Arena* new_arena = arena_make(
|
||||||
|
.base_addr = 0,
|
||||||
|
.reserve_size = current->backing->reserve,
|
||||||
|
.commit_size = current->backing->commit_size,
|
||||||
|
.flags = current->backing->flags,
|
||||||
|
);
|
||||||
|
new_arena = current->base_pos + current->backing->reserve;
|
||||||
|
sll_stack_push_n(arena->current, new_arena, prev);
|
||||||
|
}
|
||||||
|
Byte* result = cast(Byte*, active + pos_pre);
|
||||||
|
Slice_Byte vresult = varena_push_array(arena->current->backing, Byte, size_aligned, .alignment = alignment);
|
||||||
|
arena->current->pos = pos_pst;
|
||||||
|
assert(result == vresult.ptr);
|
||||||
|
slice_assert(vresult);
|
||||||
|
return vresult;
|
||||||
|
}
|
||||||
|
#pragma endregion Arena
|
||||||
|
|
||||||
#pragma region Key Table 1-Layer Linear (KT1L)
|
#pragma region Key Table 1-Layer Linear (KT1L)
|
||||||
SSIZE kt1l__populate_slice_a2(KT1L_Byte* kt, KT1L_Info info, Slice_Byte values, SSIZE num_values ) {
|
SSIZE kt1l__populate_slice_a2(KT1L_Byte* kt, KT1L_Info info, Slice_Byte values, SSIZE num_values ) {
|
||||||
assert(kt != nullptr);
|
assert(kt != nullptr);
|
||||||
@@ -922,7 +1114,6 @@ SSIZE kt1l__populate_slice_a2(KT1L_Byte* kt, KT1L_Info info, Slice_Byte values,
|
|||||||
|
|
||||||
Slice_Byte a2_key = { a2_cursor, info.type_width };
|
Slice_Byte a2_key = { a2_cursor, info.type_width };
|
||||||
Slice_Byte a2_value = { a2_cursor + info.type_width, info.type_width };
|
Slice_Byte a2_value = { a2_cursor + info.type_width, info.type_width };
|
||||||
|
|
||||||
slice_copy(slot_value, a2_value);
|
slice_copy(slot_value, a2_value);
|
||||||
hash64_djb8(slot_key, a2_key);
|
hash64_djb8(slot_key, a2_key);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user