[mem] change scratch arena API to allow using independant scratch for temporary computations and results
This commit is contained in:
parent
02bfe587c8
commit
ba125ae860
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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,
|
||||
mem_arena_scope scope = {.arena = arena,
|
||||
.chunk = arena->currentChunk,
|
||||
.offset = arena->currentChunk->offset};
|
||||
return(marker);
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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; i<filterCount; i++)
|
||||
{
|
||||
|
@ -1137,12 +1137,12 @@ MP_API str8 mp_open_dialog(mem_arena* arena,
|
|||
|
||||
hr = dialog->lpVtbl->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; i<filterCount; i++)
|
||||
{
|
||||
|
@ -1222,12 +1222,12 @@ MP_API str8 mp_save_dialog(mem_arena* arena,
|
|||
|
||||
hr = dialog->lpVtbl->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<count; i++)
|
||||
|
@ -1332,6 +1332,6 @@ MP_API int mp_alert_popup(const char* title,
|
|||
}
|
||||
}
|
||||
|
||||
mem_arena_clear_to(scratch, marker);
|
||||
mem_arena_scope_end(tmp);
|
||||
return(button);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue