mirror of
https://github.com/Ed94/metadesk.git
synced 2026-08-05 23:28:45 +00:00
memory fixes
This commit is contained in:
+50
-29
@@ -21,12 +21,16 @@ arena__alloc(ArenaParams* optional_params)
|
|||||||
|
|
||||||
U64 const varena_reserve_size = VARENA_DEFAULT_RESERVE;
|
U64 const varena_reserve_size = VARENA_DEFAULT_RESERVE;
|
||||||
|
|
||||||
|
B32 is_virtual = allocator_type(params.backing) & AllocatorType_VArena;
|
||||||
|
params.flags |= ArenaFlag_Virtual * is_virtual;
|
||||||
|
|
||||||
|
|
||||||
if (params.backing.proc == nullptr) params.backing = default_allocator();
|
if (params.backing.proc == nullptr) params.backing = default_allocator();
|
||||||
if (params.block_size == 0 ) params.block_size = ARENA_DEFAULT_BLOCK_SIZE;
|
if (params.block_size == 0 ) params.block_size = ARENA_DEFAULT_BLOCK_SIZE;
|
||||||
|
|
||||||
// TODO(Ed): Do we need to be slapping the arena onto the memory now?
|
SSIZE alloc_size = is_virtual ? header_size : params.block_size;
|
||||||
// (its technically not needed a its no longer always backed by vmem)
|
|
||||||
void* base = alloc(params.backing, params.block_size);
|
void* base = alloc(params.backing, alloc_size);
|
||||||
// rjf: extract arena header & fill
|
// rjf: extract arena header & fill
|
||||||
Arena* arena = (Arena*) base;
|
Arena* arena = (Arena*) base;
|
||||||
arena->prev = nullptr;
|
arena->prev = nullptr;
|
||||||
@@ -43,58 +47,61 @@ arena__alloc(ArenaParams* optional_params)
|
|||||||
//- rjf: arena push/pop core functions
|
//- rjf: arena push/pop core functions
|
||||||
|
|
||||||
void*
|
void*
|
||||||
arena_push(Arena *arena, SSIZE size, SSIZE align)
|
arena_push(Arena* arena, SSIZE size, SSIZE align)
|
||||||
{
|
{
|
||||||
SPTR const header_size = align_pow2(size_of(Arena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
SPTR const header_size = align_pow2(size_of(Arena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
||||||
|
|
||||||
Arena *current = arena->current;
|
Arena* current = arena->current;
|
||||||
|
SPTR curr_sptr = scast(SPTR, current);
|
||||||
|
|
||||||
SPTR pos_pre = align_pow2(current->pos, align);
|
SSIZE aligned_size = align_pow2(size, align);
|
||||||
SPTR pos_pst = pos_pre + size;
|
|
||||||
|
SPTR pos_pre = current->pos;
|
||||||
|
SPTR pos_pst = pos_pre + aligned_size;
|
||||||
|
|
||||||
|
B32 is_virtual = arena->flags & ArenaFlag_Virtual;
|
||||||
|
|
||||||
// rjf: chain, if needed
|
// 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 + header_size > res_size) {
|
|
||||||
res_size = size + header_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
Arena* new_block = nullptr;
|
Arena* new_block = nullptr;
|
||||||
|
|
||||||
B32
|
B32 vmem_chain = is_virtual && (arena->flags & ArenaFlag_NoChainVirtual);
|
||||||
vmem_chain = (arena->flags & ArenaFlag_NoChainVirtual);
|
|
||||||
vmem_chain &= allocator_type(arena->backing) == AllocatorType_VArena;
|
|
||||||
if (vmem_chain) {
|
if (vmem_chain) {
|
||||||
SPTR const varena_header_size = align_pow2(size_of(VArena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
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;
|
SPTR 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);
|
VArena* vcurrent = rcast(VArena*, arena->backing.data);
|
||||||
|
|
||||||
|
VArena* new_vm = varena_alloc(.reserve_size = vcurrent->reserve, .commit_size = vcurrent->commit_size);
|
||||||
new_block = arena_alloc(.backing = varena_allocator(new_vm), .block_size = arena_block_size);
|
new_block = arena_alloc(.backing = varena_allocator(new_vm), .block_size = arena_block_size);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
U64 const arena_block_size = arena->block_size + header_size;
|
SPTR const arena_block_size = arena->block_size + header_size;
|
||||||
|
|
||||||
new_block = arena_alloc(.backing = arena->backing, .block_size = arena_block_size);
|
new_block = arena_alloc(.backing = arena->backing, .block_size = arena_block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
new_block->base_pos = current->base_pos + current->block_size;
|
new_block->base_pos = current->base_pos + current->block_size;
|
||||||
|
|
||||||
sll_stack_push_n(arena->current, new_block, prev);
|
sll_stack_push_n(arena->current, new_block, prev);
|
||||||
|
|
||||||
current = new_block;
|
current = new_block;
|
||||||
pos_pre = align_pow2(current->pos, align);
|
pos_pre = current->pos;
|
||||||
pos_pst = pos_pre + size;
|
pos_pst = pos_pre + aligned_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// rjf: push onto current block
|
// rjf: push onto current block
|
||||||
void* result = 0;
|
void* result = 0;
|
||||||
// if(current->cmt >= pos_pst)
|
|
||||||
{
|
{
|
||||||
result = (U8*)current + pos_pre;
|
result = scast(void*, curr_sptr + pos_pre);
|
||||||
current->pos = pos_pst;
|
current->pos = pos_pst;
|
||||||
asan_unpoison_memory_region(result, size);
|
asan_unpoison_memory_region(result, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_virtual) {
|
||||||
|
// Sync virtual arena
|
||||||
|
void* vresult = alloc_align(arena->backing, size, align);
|
||||||
|
assert(vresult == result);
|
||||||
|
}
|
||||||
|
|
||||||
// rjf: panic on failure
|
// rjf: panic on failure
|
||||||
#if OS_FEATURE_GRAPHICAL
|
#if OS_FEATURE_GRAPHICAL
|
||||||
@@ -113,18 +120,32 @@ arena_pop_to(Arena *arena, SSIZE pos)
|
|||||||
{
|
{
|
||||||
SPTR const header_size = align_pow2(size_of(Arena), MD_DEFAULT_MEMORY_ALIGNMENT);
|
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;
|
||||||
Arena* current = arena->current;
|
AllocatorInfo backing = current->backing;
|
||||||
|
B32 is_virtual = allocator_type(backing) & AllocatorType_VArena;
|
||||||
|
|
||||||
|
SSIZE big_pos = clamp_bot(header_size, pos);
|
||||||
|
// If base position is larger than the position to pop to:
|
||||||
|
// We are in a previous arena and msut free the current
|
||||||
for(Arena* prev = 0; current->base_pos >= big_pos; current = prev)
|
for(Arena* prev = 0; current->base_pos >= big_pos; current = prev)
|
||||||
{
|
{
|
||||||
prev = current->prev;
|
prev = current->prev;
|
||||||
alloc_free(current->backing, current);
|
|
||||||
|
if (is_virtual) {
|
||||||
|
varena_release(rcast(VArena*, current->backing.data));
|
||||||
|
}
|
||||||
|
else if (allocator_query_support(backing) & AllocatorQuery_Free) {
|
||||||
|
alloc_free(current->backing, current);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
arena->current = current;
|
arena->current = current;
|
||||||
U64 new_pos = big_pos - current->base_pos;
|
SSIZE new_pos = big_pos - current->base_pos;
|
||||||
assert_always(new_pos <= current->pos);
|
assert_always(new_pos <= current->pos);
|
||||||
asan_poison_memory_region((U8*)current + new_pos, (current->pos - new_pos));
|
asan_poison_memory_region((U8*)current + new_pos, (current->pos - new_pos));
|
||||||
current->pos = new_pos;
|
current->pos = new_pos;
|
||||||
|
if (is_virtual) {
|
||||||
|
varena_rewind(rcast(VArena*, current->backing.data), current->pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void* arena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags)
|
void* arena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags)
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ enum
|
|||||||
// Only relevant if backing is virtual memory, will prevent allocating a new backing VArena when the current block exhausts
|
// Only relevant if backing is virtual memory, will prevent allocating a new backing VArena when the current block exhausts
|
||||||
// Will assume backing can chain multiple block_size arenas however. If there is an allocation failure it will assert.
|
// Will assume backing can chain multiple block_size arenas however. If there is an allocation failure it will assert.
|
||||||
ArenaFlag_NoChainVirtual = (1 << 1),
|
ArenaFlag_NoChainVirtual = (1 << 1),
|
||||||
|
// Backing allocator identified as VArena during initialization
|
||||||
|
ArenaFlag_Virtual = (1 << 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ArenaParams ArenaParams;
|
typedef struct ArenaParams ArenaParams;
|
||||||
|
|||||||
@@ -249,8 +249,9 @@ varena__alloc(VArenaParams params)
|
|||||||
reserve_size = align_pow2(reserve_size, os_get_system_info()->page_size);
|
reserve_size = align_pow2(reserve_size, os_get_system_info()->page_size);
|
||||||
commit_size = align_pow2(commit_size, os_get_system_info()->page_size);
|
commit_size = align_pow2(commit_size, os_get_system_info()->page_size);
|
||||||
|
|
||||||
base = os_reserve(reserve_size);
|
base = os_reserve(reserve_size);
|
||||||
os_commit(base, commit_size);
|
B32 commit_result = os_commit(base, commit_size);
|
||||||
|
assert(commit_result == 1);
|
||||||
asan_poison_memory_region(base, params.commit_size);
|
asan_poison_memory_region(base, params.commit_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,7 +303,8 @@ varena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE requested_
|
|||||||
UPTR current_offset = vm->reserve_start + vm->commit_used;
|
UPTR current_offset = vm->reserve_start + vm->commit_used;
|
||||||
UPTR size_to_allocate = requested_size;
|
UPTR size_to_allocate = requested_size;
|
||||||
UPTR to_be_used = vm->commit_used + size_to_allocate;
|
UPTR to_be_used = vm->commit_used + size_to_allocate;
|
||||||
assert(to_be_used < vm->reserve);
|
SPTR reserve_left = vm->reserve - vm->committed;
|
||||||
|
assert(to_be_used < reserve_left);
|
||||||
|
|
||||||
UPTR header_offset = vm->reserve_start - scast(UPTR, vm);
|
UPTR header_offset = vm->reserve_start - scast(UPTR, vm);
|
||||||
|
|
||||||
@@ -310,19 +312,20 @@ varena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE requested_
|
|||||||
B32 needs_more_commited = commit_left < size_to_allocate;
|
B32 needs_more_commited = commit_left < size_to_allocate;
|
||||||
if (needs_more_commited)
|
if (needs_more_commited)
|
||||||
{
|
{
|
||||||
SPTR reserve_left = vm->reserve - vm->committed;
|
|
||||||
UPTR next_commit_size;
|
UPTR next_commit_size;
|
||||||
if (vm->flags & VArenaFlag_LargePages) {
|
if (vm->flags & VArenaFlag_LargePages) {
|
||||||
next_commit_size = reserve_left > 0 ? md_max(vm->commit_size, size_to_allocate) : scast(UPTR, align_pow2( -reserve_left, os_get_system_info()->large_page_size));
|
next_commit_size = reserve_left > 0 ? md_max(vm->commit_size, size_to_allocate) : scast(UPTR, align_pow2( abs(reserve_left), os_get_system_info()->large_page_size));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
next_commit_size = reserve_left > 0 ? md_max(vm->commit_size, size_to_allocate) : scast(UPTR, align_pow2(abs(reserve_left), os_get_system_info()->page_size));
|
next_commit_size = reserve_left > 0 ? md_max(vm->commit_size, size_to_allocate) : scast(UPTR, align_pow2(abs(reserve_left), os_get_system_info()->page_size));
|
||||||
}
|
}
|
||||||
if (next_commit_size) {
|
if (next_commit_size) {
|
||||||
B32 commit_result = os_commit(vm, next_commit_size);
|
void* next_commit_start = rcast(void*, rcast(UPTR, vm) + vm->committed);
|
||||||
|
B32 commit_result = os_commit(next_commit_start, next_commit_size);
|
||||||
if (commit_result == false) {
|
if (commit_result == false) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
vm->committed += next_commit_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,11 +394,6 @@ varena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE requested_
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// case AllocatorMode_Pop:
|
|
||||||
// break;
|
|
||||||
// case AllocatorMode_Pop_To:
|
|
||||||
// break;
|
|
||||||
|
|
||||||
case AllocatorMode_QueryType:
|
case AllocatorMode_QueryType:
|
||||||
{
|
{
|
||||||
return (void*) AllocatorType_VArena;
|
return (void*) AllocatorType_VArena;
|
||||||
@@ -474,18 +472,13 @@ farena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size, SSIZ
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// case AllocatorMode_Pop:
|
|
||||||
// break;
|
|
||||||
// case AllocatorMode_Pop_To:
|
|
||||||
// break;
|
|
||||||
|
|
||||||
case AllocatorMode_QueryType:
|
case AllocatorMode_QueryType:
|
||||||
return (void*) AllocatorType_FArena;
|
return (void*) AllocatorType_FArena;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AllocatorMode_QuerySupport:
|
case AllocatorMode_QuerySupport:
|
||||||
return (void*) (AllocatorQuery_Alloc | AllocatorQuery_FreeAll | AllocatorQuery_Resize
|
return (void*) (
|
||||||
// | AllocatorQuery_Pop | AllocatorQuery_Pop_To
|
AllocatorQuery_Alloc | AllocatorQuery_FreeAll | AllocatorQuery_Resize | AllocatorQuery_ResizeGrow | AllocatorQuery_ResizeShrink
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -194,6 +194,8 @@ MD_API VArena* varena__alloc(VArenaParams params PARAM_DEFAULT);
|
|||||||
MD_API void varena_commit (VArena* vm, SSIZE commit_size);
|
MD_API void varena_commit (VArena* vm, SSIZE commit_size);
|
||||||
MD_API void varena_release(VArena* vm);
|
MD_API void varena_release(VArena* vm);
|
||||||
|
|
||||||
|
force_inline void varena_rewind(VArena* vm, SSIZE pos) { vm->commit_used = pos; }
|
||||||
|
|
||||||
MD_API void* varena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags);
|
MD_API void* varena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags);
|
||||||
|
|
||||||
#define varena_allocator(vm) (AllocatorInfo) { varena_allocator_proc, vm }
|
#define varena_allocator(vm) (AllocatorInfo) { varena_allocator_proc, vm }
|
||||||
|
|||||||
+4
-3
@@ -18,9 +18,10 @@ void init(Context* ctx)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// void deinit(Context* ctx)
|
void deinit(Context* ctx)
|
||||||
// {
|
{
|
||||||
// }
|
// Nothing for now
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Message Type Functions
|
//~ rjf: Message Type Functions
|
||||||
|
|||||||
+1
-1
@@ -271,7 +271,7 @@ nil_node()
|
|||||||
// the metadesk os runtime provided entry_point interface
|
// the metadesk os runtime provided entry_point interface
|
||||||
|
|
||||||
MD_API void init(Context* ctx);
|
MD_API void init(Context* ctx);
|
||||||
// MD_API void deinit(Context* ctx);
|
MD_API void deinit(Context* ctx); // Does nothing for now.
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Message Type Functions
|
//~ rjf: Message Type Functions
|
||||||
|
|||||||
+3
-1
@@ -264,10 +264,12 @@ MD_API String8 os_string_from_file_range__ainfo(AllocatorInfo ainfo, OS_Handle f
|
|||||||
#define os_data_from_file_path(allocator, path) _Generic(allocator, Arena*: os_data_from_file_path__arena, AllocatorInfo: os_data_from_file_path__ainfo, default: assert_generic_selection_fail) resolved_function_call(allocator, path)
|
#define os_data_from_file_path(allocator, path) _Generic(allocator, Arena*: os_data_from_file_path__arena, AllocatorInfo: os_data_from_file_path__ainfo, default: assert_generic_selection_fail) resolved_function_call(allocator, path)
|
||||||
#define os_string_from_file_range(allocator, file, range) _Generic(allocator, Arena*: os_string_from_file_range__arena, AllocatorInfo: os_string_from_file_range__ainfo, default: assert_generic_selection_fail) resolved_function_call(allocator, file, range)
|
#define os_string_from_file_range(allocator, file, range) _Generic(allocator, Arena*: os_string_from_file_range__arena, AllocatorInfo: os_string_from_file_range__ainfo, default: assert_generic_selection_fail) resolved_function_call(allocator, file, range)
|
||||||
|
|
||||||
|
force_inline String8 os_data_from_file_path__arena(Arena* arena, String8 path) { return os_data_from_file_path__ainfo(arena_allocator(arena), path); }
|
||||||
|
|
||||||
inline String8
|
inline String8
|
||||||
os_data_from_file_path__ainfo(AllocatorInfo ainfo, String8 path)
|
os_data_from_file_path__ainfo(AllocatorInfo ainfo, String8 path)
|
||||||
{
|
{
|
||||||
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, path);
|
OS_Handle file = os_file_open(OS_AccessFlag_Read | OS_AccessFlag_ShareRead, path);
|
||||||
FileProperties props = os_properties_from_file(file);
|
FileProperties props = os_properties_from_file(file);
|
||||||
String8 data = os_string_from_file_range(ainfo, file, r1u64(0, props.size));
|
String8 data = os_string_from_file_range(ainfo, file, r1u64(0, props.size));
|
||||||
os_file_close(file);
|
os_file_close(file);
|
||||||
|
|||||||
@@ -15,6 +15,5 @@ int main()
|
|||||||
gen_Context ctx = {0};
|
gen_Context ctx = {0};
|
||||||
gen_init(& ctx);
|
gen_init(& ctx);
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-6
@@ -4,9 +4,11 @@
|
|||||||
#include "metadesk.c"
|
#include "metadesk.c"
|
||||||
|
|
||||||
// This program expects to be run from the build directory (where it would be after being built)
|
// This program expects to be run from the build directory (where it would be after being built)
|
||||||
#define path_examples "../examples"
|
#define path_examples "../examples"
|
||||||
#define path_intro path_examples "/intro"
|
#define path_intro path_examples "/intro"
|
||||||
#define path_hello_world_medesk path_intro "/hello_world.mdesk"
|
#define path_hello_world_mdesk path_intro "/hello_world.mdesk"
|
||||||
|
|
||||||
|
#define text str8_lit
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@@ -14,9 +16,10 @@ int main()
|
|||||||
ctx.os_ctx.enable_large_pages = true;
|
ctx.os_ctx.enable_large_pages = true;
|
||||||
init(& ctx);
|
init(& ctx);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
printf("metadesk: got past init!");
|
printf("metadesk: got past init!");
|
||||||
|
|
||||||
// deinit(& ctx);
|
Arena* arena = arena_alloc();
|
||||||
|
String8 hello_world_mdesk = os_data_from_file_path(arena, text(path_hello_world_mdesk));
|
||||||
|
|
||||||
|
deinit(& ctx);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user