diff --git a/src/osx_app.m b/src/osx_app.m index 681447d..1ae74a5 100644 --- a/src/osx_app.m +++ b/src/osx_app.m @@ -480,14 +480,14 @@ void mp_install_keyboard_layout_listener() event.type = MP_EVENT_PATHDROP; mem_arena* scratch = mem_scratch(); - mem_arena_marker mark = mem_arena_mark(scratch); + mem_arena_scope scope = mem_arena_scope_begin(scratch); str8 path = str8_push_cstring(scratch, [filename UTF8String]); str8_list_push(scratch, &event.paths, path); mp_queue_event(&event); - mem_arena_clear_to(scratch, mark); + mem_arena_scope_end(scope); return(YES); } @@ -501,14 +501,14 @@ void mp_install_keyboard_layout_listener() event.type = MP_EVENT_PATHDROP; mem_arena* scratch = mem_scratch(); - mem_arena_marker mark = mem_arena_mark(scratch); + mem_arena_scope scope = mem_arena_scope_begin(scratch); str8 path = str8_push_cstring(scratch, [nsPath UTF8String]); str8_list_push(scratch, &event.paths, path); mp_queue_event(&event); - mem_arena_clear_to(scratch, mark); + mem_arena_scope_end(scope); } //TODO: drag and drop paths diff --git a/src/platform/orca_log.c b/src/platform/orca_log.c index 3e65a9c..5e1e24c 100644 --- a/src/platform/orca_log.c +++ b/src/platform/orca_log.c @@ -58,7 +58,7 @@ void platform_log_push(log_output* output, va_list ap) { mem_arena* scratch = mem_scratch(); - mem_arena_marker marker = mem_arena_mark(scratch); + mem_arena_scope tmp = mem_arena_scope_begin(scratch); orca_log_context ctx = {.arena = scratch, .list = {0}}; @@ -70,5 +70,5 @@ void platform_log_push(log_output* output, orca_log(level, str8_ip(function), str8_ip(file), line, str8_ip(string)); - mem_arena_clear_to(scratch, marker); + mem_arena_scope_end(tmp); } diff --git a/src/platform/osx_path.m b/src/platform/osx_path.m index d015358..c400c47 100644 --- a/src/platform/osx_path.m +++ b/src/platform/osx_path.m @@ -55,10 +55,3 @@ str8 path_find_canonical(mem_arena* arena, str8 path) return(result); } - -/*TODO -str8 path_find_restricted(mem_arena* arena, str8 root, str8 relPath) -{ - -} -*/ diff --git a/src/platform/platform_path.c b/src/platform/platform_path.c index cb012a8..3139375 100644 --- a/src/platform/platform_path.c +++ b/src/platform/platform_path.c @@ -56,7 +56,7 @@ str8 path_join(mem_arena* arena, str8_list elements) return(res); } -str8 path_append_relative(mem_arena* arena, str8 parent, str8 relPath) +str8 path_append(mem_arena* arena, str8 parent, str8 relPath) { //TODO: use secondary scratch arena diff --git a/src/platform/platform_path.h b/src/platform/platform_path.h index 961e680..1a386c6 100644 --- a/src/platform/platform_path.h +++ b/src/platform/platform_path.h @@ -15,11 +15,10 @@ MP_API str8 path_slice_filename(str8 path); MP_API str8_list path_split(mem_arena* arena, str8 path); MP_API str8 path_join(mem_arena* arena, str8_list elements); -MP_API str8 path_append_relative(mem_arena* arena, str8 parent, str8 relPath); +MP_API str8 path_append(mem_arena* arena, str8 parent, str8 relPath); MP_API str8 path_find_executable(mem_arena* arena); MP_API str8 path_find_resource(mem_arena* arena, str8 relPath); MP_API str8 path_find_canonical(mem_arena* arena, str8 path); -MP_API str8 path_find_restricted(mem_arena* arena, str8 root, str8 relPath); #endif //__PLATFORM_PATH_H_ diff --git a/src/util/memory.c b/src/util/memory.c index 34096f2..77e09ef 100644 --- a/src/util/memory.c +++ b/src/util/memory.c @@ -115,19 +115,18 @@ void mem_arena_clear(mem_arena* arena) arena->currentChunk = list_first_entry(&arena->chunks, mem_arena_chunk, listElt); } -mem_arena_marker mem_arena_mark(mem_arena* arena) +mem_arena_scope mem_arena_scope_begin(mem_arena* arena) { - mem_arena_marker marker = {.arena = arena, - .chunk = arena->currentChunk, - .offset = arena->currentChunk->offset}; - return(marker); + mem_arena_scope scope = {.arena = arena, + .chunk = arena->currentChunk, + .offset = arena->currentChunk->offset}; + return(scope); } -void mem_arena_clear_to(mem_arena* arena, mem_arena_marker marker) +void mem_arena_scope_end(mem_arena_scope scope) { - DEBUG_ASSERT(arena == marker.arena); - arena->currentChunk = marker.chunk; - arena->currentChunk->offset = marker.offset; + scope.arena->currentChunk = scope.chunk; + scope.arena->currentChunk->offset = scope.offset; } //-------------------------------------------------------------------------------- @@ -178,18 +177,65 @@ void mem_pool_clear(mem_pool* pool) //NOTE(martin): per-thread scratch arena //-------------------------------------------------------------------------------- -mp_thread_local mem_arena __scratchArena = {0}; +enum +{ + MEM_SCRATCH_POOL_SIZE = 8, + MEM_SCRATCH_DEFAULT_SIZE = 4096, +}; + +mp_thread_local mem_arena __scratchPool[MEM_SCRATCH_POOL_SIZE] = {0}; + + +static mem_arena* mem_scratch_at_index(int index) +{ + mem_arena* scratch = 0; + + if(index >= 0 && index < MEM_SCRATCH_POOL_SIZE) + { + if(__scratchPool[index].base == 0) + { + mem_arena_options options = {.reserve = MEM_SCRATCH_DEFAULT_SIZE}; + mem_arena_init_with_options(&__scratchPool[index], &options); + } + scratch = &__scratchPool[index]; + } + return(scratch); +} mem_arena* mem_scratch() { - if(__scratchArena.base == 0) - { - mem_arena_init(&__scratchArena); - } - return(&__scratchArena); + return(mem_scratch_at_index(0)); } -void mem_scratch_clear() +MP_API mem_arena* mem_scratch_next(mem_arena* used) { - mem_arena_clear(mem_scratch()); + mem_arena* res = 0; + if( (used >= __scratchPool) + &&(used - __scratchPool < MEM_SCRATCH_POOL_SIZE)) + { + u64 index = used - __scratchPool; + if(index + 1 < MEM_SCRATCH_POOL_SIZE) + { + res = mem_scratch_at_index(index+1); + } + } + else + { + res = mem_scratch_at_index(0); + } + return(res); +} + +MP_API mem_arena_scope mem_scratch_begin() +{ + mem_arena* scratch = mem_scratch(); + mem_arena_scope scope = mem_arena_scope_begin(scratch); + return(scope); +} + +MP_API mem_arena_scope mem_scratch_begin_next(mem_arena* used) +{ + mem_arena* scratch = mem_scratch_next(used); + mem_arena_scope scope = mem_arena_scope_begin(scratch); + return(scope); } diff --git a/src/util/memory.h b/src/util/memory.h index 5df2104..f5da56f 100644 --- a/src/util/memory.h +++ b/src/util/memory.h @@ -38,12 +38,12 @@ typedef struct mem_arena } mem_arena; -typedef struct mem_arena_marker +typedef struct mem_arena_scope { mem_arena* arena; mem_arena_chunk* chunk; u64 offset; -} mem_arena_marker; +} mem_arena_scope; typedef struct mem_arena_options { @@ -57,8 +57,9 @@ MP_API void mem_arena_release(mem_arena* arena); MP_API void* mem_arena_alloc(mem_arena* arena, u64 size); MP_API void mem_arena_clear(mem_arena* arena); -MP_API mem_arena_marker mem_arena_mark(mem_arena* arena); -MP_API void mem_arena_clear_to(mem_arena* arena, mem_arena_marker marker); + +MP_API mem_arena_scope mem_arena_scope_begin(mem_arena* arena); +MP_API void mem_arena_scope_end(mem_arena_scope scope); #define mem_arena_alloc_type(arena, type) ((type*)mem_arena_alloc(arena, sizeof(type))) #define mem_arena_alloc_array(arena, type, count) ((type*)mem_arena_alloc(arena, sizeof(type)*(count))) @@ -66,6 +67,10 @@ MP_API void mem_arena_clear_to(mem_arena* arena, mem_arena_marker marker); //-------------------------------------------------------------------------------- //NOTE(martin): memory pool //-------------------------------------------------------------------------------- + +//TODO: we could probably remove pool. Most of the time we construct pool on top of +// arenas "manually" with different free lists per object types... + typedef struct mem_pool { mem_arena arena; @@ -92,8 +97,15 @@ MP_API void mem_pool_clear(mem_pool* pool); //-------------------------------------------------------------------------------- //NOTE(martin): per-thread implicit scratch arena //-------------------------------------------------------------------------------- -MP_API void mem_scratch_clear(); MP_API mem_arena* mem_scratch(); +MP_API mem_arena* mem_scratch_next(mem_arena* used); +MP_API mem_arena_scope mem_scratch_begin(); +MP_API mem_arena_scope mem_scratch_begin_next(mem_arena* used); + +#define mem_scratch_end(scope) mem_arena_scope_end(scope) + + + #ifdef __cplusplus } // extern "C" diff --git a/src/win32_app.c b/src/win32_app.c index d9991cd..470a9a1 100644 --- a/src/win32_app.c +++ b/src/win32_app.c @@ -1118,7 +1118,7 @@ MP_API str8 mp_open_dialog(mem_arena* arena, if(filterCount && filters) { - mem_arena_marker mark = mem_arena_mark(arena); + mem_arena_scope tmp = mem_arena_scope_begin(arena); COMDLG_FILTERSPEC* filterSpecs = mem_arena_alloc_array(arena, COMDLG_FILTERSPEC, filterCount); for(int i=0; ilpVtbl->SetFileTypes(dialog, filterCount, filterSpecs); - mem_arena_clear_to(arena, mark); + mem_arena_scope_end(tmp); } if(defaultPath) { - mem_arena_marker mark = mem_arena_mark(arena); + mem_arena_scope tmp = mem_arena_scope_begin(arena); int pathWideSize = MultiByteToWideChar(CP_UTF8, 0, defaultPath, -1, NULL, 0); LPWSTR pathWide = mem_arena_alloc_array(arena, wchar_t, pathWideSize); MultiByteToWideChar(CP_UTF8, 0, defaultPath, -1, pathWide, pathWideSize); @@ -1154,7 +1154,7 @@ MP_API str8 mp_open_dialog(mem_arena* arena, hr = dialog->lpVtbl->SetFolder(dialog, item); item->lpVtbl->Release(item); } - mem_arena_clear_to(arena, mark); + mem_arena_scope_end(tmp); } hr = dialog->lpVtbl->Show(dialog, NULL); @@ -1203,7 +1203,7 @@ MP_API str8 mp_save_dialog(mem_arena* arena, { if(filterCount && filters) { - mem_arena_marker mark = mem_arena_mark(arena); + mem_arena_scope tmp = mem_arena_scope_begin(arena); COMDLG_FILTERSPEC* filterSpecs = mem_arena_alloc_array(arena, COMDLG_FILTERSPEC, filterCount); for(int i=0; ilpVtbl->SetFileTypes(dialog, filterCount, filterSpecs); - mem_arena_clear_to(arena, mark); + mem_arena_scope_end(tmp); } if(defaultPath) { - mem_arena_marker mark = mem_arena_mark(arena); + mem_arena_scope tmp = mem_arena_scope_begin(arena); int pathWideSize = MultiByteToWideChar(CP_UTF8, 0, defaultPath, -1, NULL, 0); LPWSTR pathWide = mem_arena_alloc_array(arena, wchar_t, pathWideSize); MultiByteToWideChar(CP_UTF8, 0, defaultPath, -1, pathWide, pathWideSize); @@ -1239,7 +1239,7 @@ MP_API str8 mp_save_dialog(mem_arena* arena, hr = dialog->lpVtbl->SetFolder(dialog, item); item->lpVtbl->Release(item); } - mem_arena_clear_to(arena, mark); + mem_arena_scope_end(tmp); } hr = dialog->lpVtbl->Show(dialog, NULL); @@ -1280,7 +1280,7 @@ MP_API int mp_alert_popup(const char* title, const char** options) { mem_arena* scratch = mem_scratch(); - mem_arena_marker marker = mem_arena_mark(scratch); + mem_arena_scope tmp = mem_arena_scope_begin(scratch); TASKDIALOG_BUTTON* buttons = mem_arena_alloc_array(scratch, TASKDIALOG_BUTTON, count); for(int i=0; i