mirror of
https://github.com/Ed94/metadesk.git
synced 2026-06-13 07:52:22 -07:00
successful adapted raddbg Arena to new substrate allocator strat
This commit is contained in:
+110
-36
@@ -14,13 +14,18 @@
|
||||
Arena*
|
||||
arena_alloc_(ArenaParams* params)
|
||||
{
|
||||
SPTR const header_size = align_pow2(size_of(Arena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
||||
|
||||
// TODO(Ed): Do we need to be slapping the arena onto the memory now?
|
||||
// (its technically not needed a its no longer always backed by vmem)
|
||||
void* base = alloc(params->backing, params->block_size);
|
||||
// rjf: extract arena header & fill
|
||||
Arena* arena = (Arena*) base;
|
||||
arena->prev = nullptr;
|
||||
arena->current = arena;
|
||||
arena->backing = params->backing;
|
||||
arena->pos = size_of(Arena);
|
||||
arena->base_pos = 0;
|
||||
arena->pos = header_size;
|
||||
arena->block_size = params->block_size;
|
||||
arena->flags = params->flags;
|
||||
asan_unpoison_memory_region(base, sizeof(Arena));
|
||||
@@ -29,62 +34,63 @@ arena_alloc_(ArenaParams* params)
|
||||
|
||||
//- rjf: arena push/pop core functions
|
||||
|
||||
internal void *
|
||||
void*
|
||||
arena_push(Arena *arena, U64 size, U64 align)
|
||||
{
|
||||
SPTR header_size = size_of(Arena);
|
||||
SPTR const header_size = align_pow2(size_of(Arena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
||||
|
||||
Arena *current = arena->current;
|
||||
SPTR pos_pre = AlignPow2(current->pos, align);
|
||||
|
||||
SPTR pos_pre = align_pow2(current->pos, align);
|
||||
SPTR pos_pst = pos_pre + size;
|
||||
|
||||
// rjf: chain, if needed
|
||||
if ( current->block_size < pos_pst && !(arena->flags & ArenaFlag_NoChain) )
|
||||
if ( current->block_size < pos_pst && ! (arena->flags & ArenaFlag_NoChain) )
|
||||
{
|
||||
SSIZE res_size = current->block_size;
|
||||
|
||||
if(size + > res_size)
|
||||
{
|
||||
res_size = size + ARENA_HEADER_SIZE;
|
||||
if(size + header_size > res_size) {
|
||||
res_size = size + header_size;
|
||||
}
|
||||
|
||||
Arena *new_block = arena_alloc(
|
||||
.reserve_size = res_size,
|
||||
.commit_size = cmt_size,
|
||||
.flags = current->flags
|
||||
);
|
||||
|
||||
new_block->base_pos = current->base_pos + current->res;
|
||||
Arena* new_block = nullptr;
|
||||
|
||||
SLLStackPush_N(arena->current, new_block, prev);
|
||||
B32
|
||||
vmem_chain = (arena->flags & ArenaFlag_NoChainVirtual);
|
||||
vmem_chain &= allocator_type(arena->backing) == AllocatorType_VArena;
|
||||
if (vmem_chain) {
|
||||
SPTR const varena_header_size = align_pow2(size_of(VArena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
||||
U64 const arena_block_size = VARENA_DEFAULT_RESERVE - varena_header_size;
|
||||
|
||||
VArena* new_vm = varena_alloc(.reserve_size = VARENA_DEFAULT_RESERVE, .commit_size = VARENA_DEFAULT_COMMIT);
|
||||
new_block = arena_alloc(.backing = varena_allocator(new_vm), .block_size = arena_block_size);
|
||||
}
|
||||
else {
|
||||
U64 const arena_block_size = arena->block_size + header_size;
|
||||
|
||||
new_block = arena_alloc(.backing = arena->backing, .block_size = arena_block_size);
|
||||
}
|
||||
|
||||
new_block->base_pos = current->base_pos + current->block_size;
|
||||
|
||||
sll_stack_push_n(arena->current, new_block, prev);
|
||||
|
||||
current = new_block;
|
||||
pos_pre = AlignPow2(current->pos, align);
|
||||
pos_pre = align_pow2(current->pos, align);
|
||||
pos_pst = pos_pre + size;
|
||||
}
|
||||
|
||||
// rjf: commit new pages, if needed
|
||||
if(current->cmt < pos_pst && !(current->flags & ArenaFlag_LargePages))
|
||||
{
|
||||
U64 cmt_pst_aligned = AlignPow2(pos_pst, current->cmt_size);
|
||||
U64 cmt_pst_clamped = ClampTop(cmt_pst_aligned, current->res);
|
||||
U64 cmt_size = cmt_pst_clamped - current->cmt;
|
||||
os_commit((U8 *)current + current->cmt, cmt_size);
|
||||
current->cmt = cmt_pst_clamped;
|
||||
}
|
||||
|
||||
// rjf: push onto current block
|
||||
void *result = 0;
|
||||
if(current->cmt >= pos_pst)
|
||||
void* result = 0;
|
||||
// if(current->cmt >= pos_pst)
|
||||
{
|
||||
result = (U8 *)current+pos_pre;
|
||||
result = (U8*)current + pos_pre;
|
||||
current->pos = pos_pst;
|
||||
AsanUnpoisonMemoryRegion(result, size);
|
||||
asan_unpoison_memory_region(result, size);
|
||||
}
|
||||
|
||||
// rjf: panic on failure
|
||||
#if OS_FEATURE_GRAPHICAL
|
||||
if(Unlikely(result == 0))
|
||||
if(unlikely(result == 0))
|
||||
{
|
||||
os_graphical_message(1, str8_lit("Fatal Allocation Failure"), str8_lit("Unexpected memory allocation failure."));
|
||||
os_abort(1);
|
||||
@@ -97,16 +103,84 @@ arena_push(Arena *arena, U64 size, U64 align)
|
||||
void
|
||||
arena_pop_to(Arena *arena, U64 pos)
|
||||
{
|
||||
U64 big_pos = clamp_bot(size_of(Arena), pos);
|
||||
SPTR const header_size = align_pow2(size_of(Arena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
||||
|
||||
U64 big_pos = clamp_bot(header_size, pos);
|
||||
Arena* current = arena->current;
|
||||
for(Arena* prev = 0; current->pos >= big_pos; current = prev)
|
||||
for(Arena* prev = 0; current->base_pos >= big_pos; current = prev)
|
||||
{
|
||||
prev = current->prev;
|
||||
alloc_free(current->backing, current);
|
||||
}
|
||||
arena->current = current;
|
||||
U64 new_pos = big_pos - current->pos;
|
||||
U64 new_pos = big_pos - current->base_pos;
|
||||
assert_always(new_pos <= current->pos);
|
||||
asan_poison_memory_region((U8*)current + new_pos, (current->pos - new_pos));
|
||||
current->pos = new_pos;
|
||||
}
|
||||
|
||||
void* arena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags)
|
||||
{
|
||||
Arena* arena = rcast(Arena*, allocator_data);
|
||||
|
||||
void* allocated_ptr = nullptr;
|
||||
switch (mode)
|
||||
{
|
||||
case AllocatorMode_Alloc:
|
||||
{
|
||||
allocated_ptr = arena_push(arena, size, alignment);
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_Free:
|
||||
{
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_FreeAll:
|
||||
{
|
||||
arena_release(arena);
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_Resize:
|
||||
{
|
||||
|
||||
assert(old_memory != nullptr);
|
||||
assert(old_size > 0);
|
||||
assert_msg(old_size == size, "Requested resize when none needed");
|
||||
|
||||
size = align_pow2(size, alignment);
|
||||
old_size = align_pow2(size, alignment);
|
||||
|
||||
SPTR old_memory_offset = scast(SPTR, old_memory) + old_size;
|
||||
SPTR current_offset = arena->pos;
|
||||
|
||||
assert_msg(old_memory_offset == current_offset, "Cannot resize existing allocation in VArena unless it was the last allocated");
|
||||
|
||||
B32 requested_shrink = size >= old_size;
|
||||
if (requested_shrink) {
|
||||
|
||||
arena->pos -= size;
|
||||
allocated_ptr = old_memory;
|
||||
break;
|
||||
}
|
||||
|
||||
allocated_ptr = old_memory;
|
||||
arena->pos += size;
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_QueryType:
|
||||
{
|
||||
return (void*) AllocatorType_Arena;
|
||||
}
|
||||
break;
|
||||
|
||||
case AllocatorMode_QuerySupport:
|
||||
{
|
||||
return (void*) (AllocatorQuery_Alloc | AllocatorQuery_Resize | AllocatorQuery_FreeAll);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-8
@@ -8,11 +8,6 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Constants
|
||||
|
||||
#define ARENA_HEADER_SIZE 64
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Types
|
||||
|
||||
@@ -52,11 +47,12 @@ struct Arena
|
||||
Arena* prev; // previous arena in chain
|
||||
Arena* current; // current arena in chain
|
||||
AllocatorInfo backing;
|
||||
SSIZE base_pos;
|
||||
SSIZE pos;
|
||||
SSIZE block_size;
|
||||
ArenaFlags flags;
|
||||
};
|
||||
static_assert(size_of(Arena) <= ARENA_HEADER_SIZE, "sizeof(Arena) <= ARENA_HEADER_SIZE");
|
||||
// static_assert(size_of(Arena) <= ARENA_HEADER_SIZE, "sizeof(Arena) <= ARENA_HEADER_SIZE");
|
||||
|
||||
typedef struct TempArena TempArena;
|
||||
struct TempArena
|
||||
@@ -120,9 +116,8 @@ arena_release(Arena* arena) {
|
||||
|
||||
inline U64
|
||||
arena_pos(Arena *arena) {
|
||||
U64 const header_size = size_of(Arena);
|
||||
Arena* current = arena->current;
|
||||
U64 pos = current + header_size + current->pos;
|
||||
U64 pos = current->base_pos + current->pos;
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
+51
-51
@@ -27,57 +27,57 @@
|
||||
internal void
|
||||
entry_point(CmdLine *cmdline)
|
||||
{
|
||||
//////////////////////////////
|
||||
//- rjf: set up state
|
||||
//
|
||||
MG_MsgList msgs = {0};
|
||||
mg_arena = arena_alloc(.reserve_size = GB(64), .commit_size = MB(64));
|
||||
mg_state = push_array(mg_arena, MG_State, 1);
|
||||
mg_state->slots_count = 256;
|
||||
mg_state->slots = push_array(mg_arena, MG_LayerSlot, mg_state->slots_count);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: extract paths
|
||||
//
|
||||
String8 build_dir_path = os_get_process_info()->binary_path;
|
||||
String8 project_dir_path = str8_chop_last_slash(build_dir_path);
|
||||
String8 code_dir_path = push_str8f(mg_arena, "%S/src", project_dir_path);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: search code directories for all files to consider
|
||||
//
|
||||
String8List file_paths = {0};
|
||||
DeferLoop(printf("searching %.*s...", str8_varg(code_dir_path)), printf(" %i files found\n", (int)file_paths.node_count))
|
||||
{
|
||||
typedef struct Task Task;
|
||||
struct Task
|
||||
{
|
||||
Task *next;
|
||||
String8 path;
|
||||
};
|
||||
Task start_task = {0, code_dir_path};
|
||||
Task *first_task = &start_task;
|
||||
Task *last_task = &start_task;
|
||||
for(Task *task = first_task; task != 0; task = task->next)
|
||||
{
|
||||
OS_FileIter *it = os_file_iter_begin(mg_arena, task->path, 0);
|
||||
for(OS_FileInfo info = {0}; os_file_iter_next(mg_arena, it, &info);)
|
||||
{
|
||||
String8 file_path = push_str8f(mg_arena, "%S/%S", task->path, info.name);
|
||||
if(info.props.flags & FilePropertyFlag_IsFolder)
|
||||
{
|
||||
Task *next_task = push_array(mg_arena, Task, 1);
|
||||
SLLQueuePush(first_task, last_task, next_task);
|
||||
next_task->path = file_path;
|
||||
}
|
||||
else
|
||||
{
|
||||
str8_list_push(mg_arena, &file_paths, file_path);
|
||||
}
|
||||
}
|
||||
os_file_iter_end(it);
|
||||
}
|
||||
}
|
||||
//////////////////////////////
|
||||
//- rjf: set up state
|
||||
//
|
||||
MG_MsgList msgs = {0};
|
||||
mg_arena = arena_alloc(.reserve_size = GB(64), .commit_size = MB(64));
|
||||
mg_state = push_array(mg_arena, MG_State, 1);
|
||||
mg_state->slots_count = 256;
|
||||
mg_state->slots = push_array(mg_arena, MG_LayerSlot, mg_state->slots_count);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: extract paths
|
||||
//
|
||||
String8 build_dir_path = os_get_process_info()->binary_path;
|
||||
String8 project_dir_path = str8_chop_last_slash(build_dir_path);
|
||||
String8 code_dir_path = push_str8f(mg_arena, "%S/src", project_dir_path);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: search code directories for all files to consider
|
||||
//
|
||||
String8List file_paths = {0};
|
||||
DeferLoop(printf("searching %.*s...", str8_varg(code_dir_path)), printf(" %i files found\n", (int)file_paths.node_count))
|
||||
{
|
||||
typedef struct Task Task;
|
||||
struct Task
|
||||
{
|
||||
Task *next;
|
||||
String8 path;
|
||||
};
|
||||
Task start_task = {0, code_dir_path};
|
||||
Task* first_task = &start_task;
|
||||
Task* last_task = &start_task;
|
||||
for(Task *task = first_task; task != 0; task = task->next)
|
||||
{
|
||||
OS_FileIter* it = os_file_iter_begin(mg_arena, task->path, 0);
|
||||
for(OS_FileInfo info = {0}; os_file_iter_next(mg_arena, it, &info);)
|
||||
{
|
||||
String8 file_path = push_str8f(mg_arena, "%S/%S", task->path, info.name);
|
||||
if(info.props.flags & FilePropertyFlag_IsFolder)
|
||||
{
|
||||
Task *next_task = push_array(mg_arena, Task, 1);
|
||||
SLLQueuePush(first_task, last_task, next_task);
|
||||
next_task->path = file_path;
|
||||
}
|
||||
else
|
||||
{
|
||||
str8_list_push(mg_arena, &file_paths, file_path);
|
||||
}
|
||||
}
|
||||
os_file_iter_end(it);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: parse all metadesk files
|
||||
|
||||
Reference in New Issue
Block a user