From 0b3e191bb2e76a529a10daf06af38a5ae0a32397 Mon Sep 17 00:00:00 2001 From: jacob Date: Fri, 21 Jun 2024 14:27:35 -0500 Subject: [PATCH] use work system for sprite loading --- src/sprite.c | 135 +++++++++++++++------------------------------------ 1 file changed, 38 insertions(+), 97 deletions(-) diff --git a/src/sprite.c b/src/sprite.c index b39a90ff..a01f5a54 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -35,10 +35,8 @@ * Loader cmd structs * ========================== */ -struct loader_cmd { - struct loader_cmd *next; - struct loader_cmd *next_free; - +struct load_cmd { + struct load_cmd *next_free; struct cache_node *cache_node; struct sprite_tag tag; u8 tag_path_buff[512]; @@ -129,16 +127,10 @@ GLOBAL struct { /* Cache */ struct cache cache; - /* Loader threads */ - b32 loaders_shutdown; - struct sys_mutex loaders_mutex; - struct sys_condition_variable loaders_cv; - struct arena loader_cmd_arena; - struct loader_cmd *first_free_loader_cmd; - struct loader_cmd *first_loader_cmd; - struct loader_cmd *last_loader_cmd; - u64 loader_threads_count; - struct sys_thread loader_threads[MAX_LOADER_THREADS]; + /* Load cmds */ + struct sys_mutex load_cmds_mutex; + struct arena load_cmds_arena; + struct load_cmd *first_free_load_cmd; /* Evictor thread */ struct atomic_u32 evictor_cycle; @@ -216,7 +208,7 @@ INTERNAL struct image_rgba generate_purple_black_image(struct arena *arena, u32 * ========================== */ INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(sprite_shutdown); -INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(sprite_loader_thread_entry_point, arg); +INTERNAL WORK_TASK_FUNC_DEF(sprite_load_task, arg); INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(sprite_evictor_thread_entry_point, arg); struct sprite_startup_receipt sprite_startup(struct renderer_startup_receipt *renderer_sr, @@ -253,24 +245,12 @@ struct sprite_startup_receipt sprite_startup(struct renderer_startup_receipt *re G.cache.buckets[i].rw_mutex = sys_rw_mutex_alloc(); } - G.loader_cmd_arena = arena_alloc(GIGABYTE(64)); - G.loaders_mutex = sys_mutex_alloc(); - G.loaders_cv = sys_condition_variable_alloc(); + G.load_cmds_arena = arena_alloc(GIGABYTE(64)); + G.load_cmds_mutex = sys_mutex_alloc(); G.evictor_mutex = sys_mutex_alloc(); G.evictor_cv = sys_condition_variable_alloc(); - { - struct temp_arena scratch = scratch_begin_no_conflict(); - G.loader_threads_count = clamp_i64(1, MAX_LOADER_THREADS, sys_num_logical_processors() - 1); - for (u64 i = 0; i < G.loader_threads_count; ++i) { - struct string thread_name = string_format(scratch.arena, - STR("[P0] Sprite loader %F"), - FMT_UINT(i)); - G.loader_threads[i] = sys_thread_alloc(sprite_loader_thread_entry_point, NULL, thread_name); - } - scratch_end(scratch); - } G.evictor_thread = sys_thread_alloc(sprite_evictor_thread_entry_point, NULL, STR("[P0] Sprite evictor")); app_register_exit_callback(&sprite_shutdown); @@ -282,14 +262,6 @@ INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(sprite_shutdown) { __prof; - /* Signal loaders shutdown */ - sys_mutex_lock(&G.loaders_mutex); - { - G.loaders_shutdown = true; - sys_condition_variable_broadcast(&G.loaders_cv); - } - sys_mutex_unlock(&G.loaders_mutex); - /* Signal evictor shutdown */ sys_mutex_lock(&G.evictor_mutex); { @@ -297,12 +269,6 @@ INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(sprite_shutdown) sys_condition_variable_broadcast(&G.evictor_cv); } sys_mutex_unlock(&G.evictor_mutex); - - - /* Wait on threads */ - for (u64 i = 0; i < G.loader_threads_count; ++i) { - sys_thread_wait_release(&G.loader_threads[i]); - } sys_thread_wait_release(&G.evictor_thread); } @@ -691,16 +657,16 @@ INTERNAL void *data_from_tag_internal(struct sprite_scope *scope, struct sprite_ } break; } } else { - sys_mutex_lock(&G.loaders_mutex); + sys_mutex_lock(&G.load_cmds_mutex); { /* Allocate cmd */ - struct loader_cmd *cmd = NULL; - if (G.first_free_loader_cmd) { - cmd = G.first_free_loader_cmd; - G.first_free_loader_cmd = cmd->next_free; + struct load_cmd *cmd = NULL; + if (G.first_free_load_cmd) { + cmd = G.first_free_load_cmd; + G.first_free_load_cmd = cmd->next_free; MEMZERO_STRUCT(cmd); } else { - cmd = arena_push_zero(&G.loader_cmd_arena, struct loader_cmd); + cmd = arena_push_zero(&G.load_cmds_arena, struct load_cmd); } /* Initialize cmd */ @@ -712,17 +678,13 @@ INTERNAL void *data_from_tag_internal(struct sprite_scope *scope, struct sprite_ MEMCPY(cmd->tag.path.text, tag.path.text, copy_len); } - /* Add cmd to queue */ - *(G.last_loader_cmd ? &G.last_loader_cmd->next : &G.first_loader_cmd) = cmd; - G.last_loader_cmd = cmd; - /* Cmd holds reference to node */ node_refcount_add(n, 1); - /* Signal work ready */ - sys_condition_variable_signal(&G.loaders_cv); + /* Push work */ + work_push_task(&sprite_load_task, cmd, WORK_PRIORITY_NORMAL); } - sys_mutex_unlock(&G.loaders_mutex); + sys_mutex_unlock(&G.load_cmds_mutex); } } @@ -792,53 +754,32 @@ struct sprite_sheet_frame sprite_sheet_get_frame(struct sprite_sheet *sheet, u32 } /* ========================== * - * Loader thread + * Load task * ========================== */ -INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(sprite_loader_thread_entry_point, arg) +INTERNAL WORK_TASK_FUNC_DEF(sprite_load_task, arg) { __prof; - (UNUSED)arg; + struct load_cmd *cmd = (struct load_cmd *)arg; - sys_mutex_lock(&G.loaders_mutex); - { - while (!G.loaders_shutdown) { - struct loader_cmd *cmd = G.first_loader_cmd; - 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); - } - } + 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_unlock(&G.loaders_mutex); + + /* Free cmd */ + node_refcount_add(n, -1); + sys_mutex_lock(&G.load_cmds_mutex); + { + cmd->next_free = G.first_free_load_cmd; + G.first_free_load_cmd = cmd; + } + sys_mutex_unlock(&G.load_cmds_mutex); } /* ========================== *