diff --git a/src/app.c b/src/app.c index a47565fd..6895b11b 100644 --- a/src/app.c +++ b/src/app.c @@ -124,6 +124,8 @@ void app_register_exit_callback(app_exit_callback_func *func) void app_entry_point(void) { + struct temp_arena scratch = scratch_begin_no_conflict(); + G.exit_sf = sync_flag_alloc(); G.exit_callbacks_mutex = sys_mutex_alloc(); G.exit_callbacks_arena = arena_alloc(GIGABYTE(64)); @@ -150,12 +152,12 @@ void app_entry_point(void) /* Startup logging */ { - struct temp_arena scratch = scratch_begin_no_conflict(); - struct string logfile_path = app_write_path_cat(scratch.arena, STR("log.txt")); + struct temp_arena temp = arena_temp_begin(scratch.arena); + struct string logfile_path = app_write_path_cat(temp.arena, STR("log.txt")); struct log_startup_receipt log_sr = log_startup(logfile_path); (UNUSED)log_sr; - scratch_end(scratch); logf_info("Start of logs"); + arena_temp_end(temp); } /* Create window */ @@ -163,22 +165,22 @@ void app_entry_point(void) /* Read window settings from file */ { - struct temp_arena scratch = scratch_begin_no_conflict(); + struct temp_arena temp = arena_temp_begin(scratch.arena); struct sys_window_settings window_settings = { 0 }; - struct string settings_path = app_write_path_cat(scratch.arena, STR(SETTINGS_FILENAME)); + struct string settings_path = app_write_path_cat(temp.arena, STR(SETTINGS_FILENAME)); logf_info("Looking for settings file \"%F\"", FMT_STR(settings_path)); if (sys_is_file(settings_path)) { logf_info("Settings file found"); struct sys_file settings_file = sys_file_open_read(settings_path); - struct buffer file_data = sys_file_read_all(scratch.arena, settings_file); + struct buffer file_data = sys_file_read_all(temp.arena, settings_file); sys_file_close(settings_file); logf_info("Deserializing settings file data: %F", FMT_STR(STRING_FROM_BUFFER(file_data))); struct string error = { 0 }; - struct sys_window_settings *res = settings_deserialize(scratch.arena, file_data, &error); + struct sys_window_settings *res = settings_deserialize(temp.arena, file_data, &error); if (error.len > 0) { logf_info("Failed to load settings file with error - %F", FMT_STR(error)); - struct string msg = string_format(scratch.arena, + struct string msg = string_format(temp.arena, STR( "Failed to loading settings file \"%F\":\n" "------------\n" @@ -199,7 +201,7 @@ void app_entry_point(void) string_copy_buff(BUFFER_FROM_ARRAY(window_settings.title), STR(WINDOW_TITLE)); sys_window_update_settings(&window, &window_settings); - scratch_end(scratch); + arena_temp_end(temp); } /* Startup systems */ @@ -245,12 +247,12 @@ void app_entry_point(void) /* Write window settings to file */ { - struct temp_arena scratch = scratch_begin_no_conflict(); + struct temp_arena temp = arena_temp_begin(scratch.arena); - struct string window_settings_path = app_write_path_cat(scratch.arena, STR(SETTINGS_FILENAME)); + struct string window_settings_path = app_write_path_cat(temp.arena, STR(SETTINGS_FILENAME)); struct sys_window_settings settings = sys_window_get_settings(&window); - struct buffer buff = settings_serialize(scratch.arena, &settings); + struct buffer buff = settings_serialize(temp.arena, &settings); logf_info("Serialized window settings: %F", FMT_STR(STRING_FROM_BUFFER(buff))); logf_info("Writing settings file to path \"%F\"", FMT_STR(window_settings_path)); @@ -259,11 +261,12 @@ void app_entry_point(void) sys_file_close(settings_file); logf_info("Finished writing settings file"); - scratch_end(scratch); + arena_temp_end(temp); } logf_info("Program exited normally"); + scratch_end(scratch); } void app_exit(void) diff --git a/src/ase.c b/src/ase.c index 109a392f..40a73e20 100644 --- a/src/ase.c +++ b/src/ase.c @@ -242,6 +242,8 @@ INTERNAL u16 huffman_decode(struct huffman *huffman, struct bitbuf *bb) INTERNAL void inflate(u8 *dest, u8 *encoded) { + struct temp_arena scratch = scratch_begin_no_conflict(); + __prof; struct bitbuf bb = { encoded }; @@ -273,7 +275,7 @@ INTERNAL void inflate(u8 *dest, u8 *encoded) case BLOCK_TYPE_COMPRESSED_FIXED: case BLOCK_TYPE_COMPRESSED_DYNAMIC: { - struct temp_arena scratch = scratch_begin_no_conflict(); + struct temp_arena temp = arena_temp_begin(scratch.arena); u32 lit_len_dist_table[512] = { 0 }; u32 hlit; u32 hdist; @@ -292,7 +294,7 @@ INTERNAL void inflate(u8 *dest, u8 *encoded) u32 code = g_hclen_order[i]; hclen_bl_counts[code] = consume_bits(&bb, 3); } - struct huffman dict_huffman = huffman_init(scratch.arena, 7, hclen_bl_counts, ARRAY_COUNT(hclen_bl_counts)); + struct huffman dict_huffman = huffman_init(temp.arena, 7, hclen_bl_counts, ARRAY_COUNT(hclen_bl_counts)); /* Decode dict huffman */ u32 lit_len_count = 0; @@ -337,8 +339,8 @@ INTERNAL void inflate(u8 *dest, u8 *encoded) } /* Decode */ - struct huffman lit_len_huffman = huffman_init(scratch.arena, 15, lit_len_dist_table, hlit); - struct huffman dist_huffman = huffman_init(scratch.arena, 15, lit_len_dist_table + hlit, hdist); + struct huffman lit_len_huffman = huffman_init(temp.arena, 15, lit_len_dist_table, hlit); + struct huffman dist_huffman = huffman_init(temp.arena, 15, lit_len_dist_table + hlit, hdist); while (true) { u32 lit_len = huffman_decode(&lit_len_huffman, &bb); @@ -369,7 +371,7 @@ INTERNAL void inflate(u8 *dest, u8 *encoded) } } - scratch_end(scratch); + arena_temp_end(temp); } break; case BLOCK_TYPE_RESERVED: { @@ -378,6 +380,8 @@ INTERNAL void inflate(u8 *dest, u8 *encoded) } break; } } + + scratch_end(scratch); } /* ========================== * diff --git a/src/font.c b/src/font.c index 6955c34c..62ff17a2 100644 --- a/src/font.c +++ b/src/font.c @@ -96,8 +96,9 @@ INTERNAL void font_task_params_release(struct font_task_params *p) INTERNAL WORK_TASK_FUNC_DEF(font_load_asset_task, vparams) { __prof; - struct font_task_params *params = (struct font_task_params *)vparams; struct temp_arena scratch = scratch_begin_no_conflict(); + + struct font_task_params *params = (struct font_task_params *)vparams; struct string path = string_from_cstr_len(params->path_cstr, params->path_len); f32 point_size = params->point_size; struct asset *asset = params->asset; diff --git a/src/incbin.c b/src/incbin.c index 1d294f9f..457eab06 100644 --- a/src/incbin.c +++ b/src/incbin.c @@ -26,11 +26,8 @@ struct rc_search_params { INTERNAL BOOL CALLBACK enum_func(HMODULE module, LPCWSTR type, LPCWSTR wstr_entry_name, LONG_PTR udata) { struct temp_arena scratch = scratch_begin_no_conflict(); - struct rc_search_params *params = (struct rc_search_params *)udata; - struct string entry_name_lower = string_lower(scratch.arena, string_from_wstr(scratch.arena, (LPWSTR)wstr_entry_name)); - params->found = false; params->data = BUFFER(0, 0); if (string_eq(entry_name_lower, params->name_lower)) { @@ -44,24 +41,20 @@ INTERNAL BOOL CALLBACK enum_func(HMODULE module, LPCWSTR type, LPCWSTR wstr_entr } } } - scratch_end(scratch); - return params->found; + return !params->found; } struct buffer _incbin_get(struct _incbin_rc_resource *inc) { enum inc_state state = atomic_i32_eval(&inc->state); - if (state == INCBIN_STATE_SEARCHED) { - return inc->data; - } + if (state != INCBIN_STATE_SEARCHED) { + struct temp_arena scratch = scratch_begin_no_conflict(); - if (state == INCBIN_STATE_UNSEARCHED) { - enum inc_state v = atomic_i32_eval_compare_exchange(&inc->state, state, INCBIN_STATE_SEARCHING); - if (v == state) { - struct temp_arena scratch = scratch_begin_no_conflict(); - { - /* Search */ + if (state == INCBIN_STATE_UNSEARCHED) { + enum inc_state v = atomic_i32_eval_compare_exchange(&inc->state, state, INCBIN_STATE_SEARCHING); + if (v == state) { + /* Search RC file for the resource name */ struct string name_lower = string_lower(scratch.arena, inc->rc_name); struct rc_search_params params = { .name_lower = name_lower }; EnumResourceNamesW(NULL, RT_RCDATA, &enum_func, (LONG_PTR)¶ms); @@ -73,19 +66,19 @@ struct buffer _incbin_get(struct _incbin_rc_resource *inc) inc->data = params.data; state = INCBIN_STATE_SEARCHED; atomic_i32_eval_exchange(&inc->state, state); + } else { + state = v; } - scratch_end(scratch); - } else { - state = v; } - } - /* Spin while another thread is searching */ - while (state != INCBIN_STATE_SEARCHED) { - ix_pause(); - state = atomic_i32_eval(&inc->state); - } + /* Spin while another thread searches */ + while (state != INCBIN_STATE_SEARCHED) { + ix_pause(); + state = atomic_i32_eval(&inc->state); + } + scratch_end(scratch); + } return inc->data; } diff --git a/src/incbin.h b/src/incbin.h index c62b935f..d9367f95 100644 --- a/src/incbin.h +++ b/src/incbin.h @@ -31,7 +31,6 @@ struct buffer _incbin_get(struct _incbin_rc_resource *inc); #else - /* ========================== * * Clang incbin * ========================== */ diff --git a/src/playback_wasapi.c b/src/playback_wasapi.c index 06ce6936..8b460190 100644 --- a/src/playback_wasapi.c +++ b/src/playback_wasapi.c @@ -235,17 +235,20 @@ INTERNAL void wasapi_update_end(struct wasapi_buffer *wspbuf, struct mixed_pcm_f INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(playback_thread_entry_point, arg) { + struct temp_arena scratch = scratch_begin_no_conflict(); (UNUSED)arg; + /* FIXME: If playback fails at any point and mixer stops advancing, we * need to halt mixer to prevent memory leak when sounds are played. */ while (!atomic_i32_eval(&G.playback_thread_shutdown)) { - struct temp_arena scratch = scratch_begin_no_conflict(); - + struct temp_arena temp = arena_temp_begin(scratch.arena); struct wasapi_buffer wspbuf = wasapi_update_begin(); - struct mixed_pcm_f32 pcm = mixer_update(scratch.arena, wspbuf.frames_count); + struct mixed_pcm_f32 pcm = mixer_update(temp.arena, wspbuf.frames_count); wasapi_update_end(&wspbuf, pcm); + arena_temp_end(temp); - scratch_end(scratch); } + + scratch_end(scratch); } diff --git a/src/sprite.c b/src/sprite.c index 0c8e7c0e..b39a90ff 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -800,52 +800,45 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(sprite_loader_thread_entry_point, arg) __prof; (UNUSED)arg; - b32 abort = false; - while (!abort) { - sys_mutex_lock(&G.loaders_mutex); - - if (G.loaders_shutdown) { - /* Exit thread */ - abort = true; - } else if (!G.first_loader_cmd) { - /* Wait for work */ - sys_condition_variable_wait(&G.loaders_cv, &G.loaders_mutex); - - } - - while (G.first_loader_cmd && !G.loaders_shutdown) { - /* Pull cmd from queue */ + sys_mutex_lock(&G.loaders_mutex); + { + while (!G.loaders_shutdown) { struct loader_cmd *cmd = G.first_loader_cmd; - G.first_loader_cmd = cmd->next; - if (G.last_loader_cmd == cmd) { - G.last_loader_cmd = NULL; - } - - /* Do work (temporarily unlock) */ - sys_mutex_unlock(&G.loaders_mutex); - { - struct cache_node *n = cmd->cache_node; - switch (n->kind) { - case CACHE_NODE_KIND_TEXTURE: { - cache_node_load_texture(n, cmd->tag); - } break; - case CACHE_NODE_KIND_SHEET: { - cache_node_load_sheet(n, cmd->tag); - } break; + if (cmd) { + /* Pop cmd from queue */ + G.first_loader_cmd = cmd->next; + if (G.last_loader_cmd == cmd) { + G.last_loader_cmd = NULL; } + + /* Do work (temporarily unlock) */ + sys_mutex_unlock(&G.loaders_mutex); + { + struct cache_node *n = cmd->cache_node; + switch (n->kind) { + case CACHE_NODE_KIND_TEXTURE: { + cache_node_load_texture(n, cmd->tag); + } break; + case CACHE_NODE_KIND_SHEET: { + cache_node_load_sheet(n, cmd->tag); + } break; + } + } + sys_mutex_lock(&G.loaders_mutex); + + /* Free cmd */ + cmd->next_free = G.first_free_loader_cmd; + G.first_free_loader_cmd = cmd; + + /* Cmd no longer references node */ + node_refcount_add(cmd->cache_node, -1); + } else { + /* Wait for work */ + sys_condition_variable_wait(&G.loaders_cv, &G.loaders_mutex); } - sys_mutex_lock(&G.loaders_mutex); - - /* Free cmd */ - cmd->next_free = G.first_free_loader_cmd; - G.first_free_loader_cmd = cmd; - - /* Cmd no longer references node */ - node_refcount_add(cmd->cache_node, -1); } - - sys_mutex_unlock(&G.loaders_mutex); } + sys_mutex_unlock(&G.loaders_mutex); } /* ========================== * diff --git a/src/string.c b/src/string.c index 7cd6283c..5eb855a0 100644 --- a/src/string.c +++ b/src/string.c @@ -96,6 +96,7 @@ struct string string_from_ptr(struct arena *arena, void *ptr) struct string string_from_float(struct arena *arena, f64 f, u32 precision) { + struct temp_arena scratch = scratch_begin(arena); u8 *final_text = arena_dry_push(arena, u8); u64 final_len = 0; @@ -120,8 +121,6 @@ struct string string_from_float(struct arena *arena, f64 f, u32 precision) /* Print whole part */ { - struct temp_arena scratch = scratch_begin(arena); - /* Build backwards text starting from least significant digit */ u8 *backwards_text = arena_dry_push(scratch.arena, u8); u64 backwards_text_len = 0; @@ -137,8 +136,6 @@ struct string string_from_float(struct arena *arena, f64 f, u32 precision) for (u64 i = backwards_text_len; i-- > 0;) { final_text[final_len++] = backwards_text[i]; } - - scratch_end(scratch); } /* Print decimal part */ @@ -154,6 +151,8 @@ struct string string_from_float(struct arena *arena, f64 f, u32 precision) } } + scratch_end(scratch); + return (struct string) { .len = final_len, .text = final_text diff --git a/src/work.c b/src/work.c index 40d0f401..c8d9c3ec 100644 --- a/src/work.c +++ b/src/work.c @@ -328,8 +328,8 @@ INTERNAL struct work_task *work_dequeue_task_assume_locked(struct work *work) * Work doing * ========================== */ -/* NOTE: This function will release `work` there are no more tasks once completed. - * Returns `true` if work was finished & released. */ +/* NOTE: This function will release `work` if there are no more tasks once completed. + * Returns `true` if more tasks are still present in the work after completion. */ INTERNAL b32 work_exec_single_task_maybe_release_assume_locked(struct work *work) { __prof; @@ -392,26 +392,20 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(worker_thread_entry_point, thread_data) }; sys_mutex_lock(&G.mutex); - while (true) { - while (!G.workers_shutdown && !G.scheduled_work_head) { - sys_condition_variable_wait(&G.cv, &G.mutex); - } - - while (!G.workers_shutdown && G.scheduled_work_head) { + { + while (!G.workers_shutdown) { struct work *work = G.scheduled_work_head; if (work) { __profscope(work_pool_task); --G.idle_worker_count; work_exec_single_task_maybe_release_assume_locked(work); ++G.idle_worker_count; + } else { + sys_condition_variable_wait(&G.cv, &G.mutex); } } - - if (G.workers_shutdown) { - sys_mutex_unlock(&G.mutex); - break; - } } + sys_mutex_unlock(&G.mutex); } /* ========================== *