From 0d15b8670bf8364f41159efe19f09734993fb251 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 17 Sep 2025 14:47:55 -0700 Subject: [PATCH] eliminate bifurcated rw lock path based on exclusive mode; promote thread operations to base layer, use os layer as impl; first pass on moving file streaming layer to base layer's async wavefront --- src/async/async.c | 12 +- src/async/async.h | 2 +- src/base/base_entry_point.c | 69 +++++- src/base/base_inc.c | 2 +- src/base/base_inc.h | 2 +- src/base/{base_sync.c => base_threads.c} | 42 +++- src/base/{base_sync.h => base_threads.h} | 39 ++- src/ctrl/ctrl_core.c | 76 +++--- src/ctrl/ctrl_core.h | 2 +- src/dasm_cache/dasm_cache.c | 20 +- src/dasm_cache/dasm_cache.h | 2 +- src/dbgi/dbgi.c | 50 ++-- src/dbgi/dbgi.h | 4 +- src/demon/linux/demon_core_linux.c | 4 +- src/demon/win32/demon_core_win32.c | 6 +- src/file_stream/file_stream.c | 287 ++++++----------------- src/file_stream/file_stream.h | 23 -- src/geo_cache/geo_cache.c | 22 +- src/geo_cache/geo_cache.h | 2 +- src/hash_store/hash_store.c | 34 +-- src/hash_store/hash_store.h | 2 +- src/mutable_text/mutable_text.c | 8 +- src/mutable_text/mutable_text.h | 2 +- src/os/core/linux/os_core_linux.c | 91 +++---- src/os/core/linux/os_core_linux.h | 4 +- src/os/core/linux/os_core_linux_old.c | 6 +- src/os/core/linux/os_core_linux_old.h | 4 +- src/os/core/os_core.c | 15 -- src/os/core/os_core.h | 33 +-- src/os/core/win32/os_core_win32.c | 72 +++--- src/os/core/win32/os_core_win32.h | 2 +- src/ptr_graph_cache/ptr_graph_cache.c | 18 +- src/ptr_graph_cache/ptr_graph_cache.h | 4 +- src/radbin/radbin.c | 6 +- src/raddbg/raddbg_main.c | 16 +- src/render/d3d11/render_d3d11.c | 24 +- src/text_cache/text_cache.c | 24 +- src/text_cache/text_cache.h | 2 +- src/texture_cache/texture_cache.c | 22 +- src/texture_cache/texture_cache.h | 2 +- 40 files changed, 450 insertions(+), 607 deletions(-) rename src/base/{base_sync.c => base_threads.c} (64%) rename src/base/{base_sync.h => base_threads.h} (63%) diff --git a/src/async/async.c b/src/async/async.c index 953f34a5..eeef9054 100644 --- a/src/async/async.c +++ b/src/async/async.c @@ -29,10 +29,10 @@ async_init(CmdLine *cmdline) async_shared->work_threads_count = Max(4, os_get_system_info()->logical_processor_count-1); } async_shared->work_threads_count = Max(4, async_shared->work_threads_count); - async_shared->work_threads = push_array(arena, OS_Handle, async_shared->work_threads_count); + async_shared->work_threads = push_array(arena, Thread, async_shared->work_threads_count); for EachIndex(idx, async_shared->work_threads_count) { - async_shared->work_threads[idx] = os_thread_launch(async_work_thread__entry_point, (void *)idx, 0); + async_shared->work_threads[idx] = thread_launch(async_work_thread__entry_point, (void *)idx); } } @@ -68,7 +68,7 @@ async_push_work_(ASYNC_WorkFunctionType *work_function, ASYNC_WorkParams *params // thread, and skip ring buffer if so. B32 queued_in_ring_buffer = 0; B32 need_to_execute_on_this_thread = 0; - OS_MutexScope(ring->ring_mutex) for(;;) + MutexScope(ring->ring_mutex) for(;;) { U64 num_available_work_threads = (async_shared->work_threads_count - ins_atomic_u64_eval(&async_shared->work_threads_live_count)); if(num_available_work_threads == 0 && async_work_thread_depth > 0) @@ -167,12 +167,12 @@ async_pop_work(void) ASYNC_Work work = {0}; B32 done = 0; ASYNC_Priority taken_priority = ASYNC_Priority_Low; - OS_MutexScope(async_shared->ring_mutex) for(;!done;) + MutexScope(async_shared->ring_mutex) for(;!done;) { for(ASYNC_Priority priority = ASYNC_Priority_High;; priority = (ASYNC_Priority)(priority - 1)) { ASYNC_Ring *ring = &async_shared->rings[priority]; - OS_MutexScope(ring->ring_mutex) + MutexScope(ring->ring_mutex) { U64 unconsumed_size = ring->ring_write_pos - ring->ring_read_pos; if(unconsumed_size >= sizeof(work)) @@ -274,7 +274,7 @@ internal void async_work_thread__entry_point(void *p) { U64 thread_idx = (U64)p; - ThreadNameF("[async] work thread #%I64u", thread_idx); + ThreadNameF("async_work_thread_%I64u", thread_idx); async_work_thread_idx = thread_idx; for(;;) { diff --git a/src/async/async.h b/src/async/async.h index b7fcc6b6..cf905e5a 100644 --- a/src/async/async.h +++ b/src/async/async.h @@ -104,7 +104,7 @@ struct ASYNC_Shared CondVar ring_cv; // rjf: work threads - OS_Handle *work_threads; + Thread *work_threads; U64 work_threads_count; U64 work_threads_live_count; }; diff --git a/src/base/base_entry_point.c b/src/base/base_entry_point.c index 36b303f7..aee68a3e 100644 --- a/src/base/base_entry_point.c +++ b/src/base/base_entry_point.c @@ -2,18 +2,23 @@ // Licensed under the MIT license (https://opensource.org/license/mit/) global U64 global_update_tick_idx = 0; -global CondVar async_tick_cond_var = {0}; -global Mutex async_tick_mutex = {0}; +global CondVar async_tick_start_cond_var = {0}; +global CondVar async_tick_stop_cond_var = {0}; +global Mutex async_tick_start_mutex = {0}; +global Mutex async_tick_stop_mutex = {0}; +global B32 global_async_exit = 0; internal void main_thread_base_entry_point(int arguments_count, char **arguments) { + ThreadNameF("main_thread"); Temp scratch = scratch_begin(0, 0); - ThreadNameF("[main thread]"); //- rjf: set up async thread group info - async_tick_cond_var = cond_var_alloc(); - async_tick_mutex = mutex_alloc(); + async_tick_start_cond_var = cond_var_alloc(); + async_tick_start_mutex = mutex_alloc(); + async_tick_stop_cond_var = cond_var_alloc(); + async_tick_stop_mutex = mutex_alloc(); //- rjf: set up telemetry #if PROFILE_TELEMETRY @@ -29,7 +34,13 @@ main_thread_base_entry_point(int arguments_count, char **arguments) #endif //- rjf: parse command line - String8List command_line_argument_strings = os_string_list_from_argcv(scratch.arena, arguments_count, arguments); + String8List command_line_argument_strings = {0}; + { + for EachIndex(idx, arguments_count) + { + str8_list_push(scratch.arena, &command_line_argument_strings, str8_cstring(arguments[idx])); + } + } CmdLine cmdline = cmd_line_from_string_list(scratch.arena, command_line_argument_strings); //- rjf: begin captures @@ -37,12 +48,9 @@ main_thread_base_entry_point(int arguments_count, char **arguments) if(capture) { ProfBeginCapture(arguments[0]); + ProfMsg(BUILD_TITLE); } -#if PROFILE_TELEMETRY - tmMessage(0, TMMF_ICON_NOTE, BUILD_TITLE); -#endif - //- rjf: initialize all included layers #if defined(ASYNC_H) && !defined(ASYNC_INIT_MANUAL) async_init(&cmdline); @@ -96,9 +104,42 @@ main_thread_base_entry_point(int arguments_count, char **arguments) rd_init(&cmdline); #endif + //- rjf: launch async threads + Thread *async_threads = 0; + U64 async_threads_count = 0; + { + U64 num_main_threads = 1; +#if defined(CTRL_CORE_H) + num_main_threads += 1; +#endif + U64 num_async_threads = os_get_system_info()->logical_processor_count; + U64 num_main_threads_clamped = Min(num_async_threads, num_main_threads); + num_async_threads -= num_main_threads_clamped; + num_async_threads = Max(1, num_async_threads); + Barrier barrier = barrier_alloc(num_async_threads); + LaneCtx *lane_ctxs = push_array(scratch.arena, LaneCtx, num_async_threads); + async_threads_count = num_async_threads; + async_threads = push_array(scratch.arena, Thread, async_threads_count); + for EachIndex(idx, num_async_threads) + { + lane_ctxs[idx].lane_idx = idx; + lane_ctxs[idx].lane_count = num_async_threads; + lane_ctxs[idx].barrier = barrier; + async_threads[idx] = thread_launch(async_thread_entry_point, &lane_ctxs[idx]); + } + } + //- rjf: call into entry point entry_point(&cmdline); + //- rjf: join async threads + ins_atomic_u32_inc_eval(&global_async_exit); + cond_var_broadcast(async_tick_start_cond_var); + for EachIndex(idx, async_threads_count) + { + thread_join(async_threads[idx], max_U64); + } + //- rjf: end captures if(capture) { @@ -143,11 +184,15 @@ update(void) internal void async_thread_entry_point(void *params) { - MutexScope(async_tick_mutex) for(;;) + LaneCtx lctx = *(LaneCtx *)params; + lane_ctx(lctx); + ThreadNameF("async_thread_%I64u", lane_idx()); + for(;!ins_atomic_u32_eval(&global_async_exit);) { - cond_var_wait(async_tick_cond_var, async_tick_mutex, max_U64); + MutexScope(async_tick_start_mutex) cond_var_wait(async_tick_start_cond_var, async_tick_start_mutex, os_now_microseconds()+100000); #if defined(FILE_STREAM_H) fs_async_tick(); #endif + cond_var_broadcast(async_tick_stop_cond_var); } } diff --git a/src/base/base_inc.c b/src/base/base_inc.c index dc6cad3c..ec199ac0 100644 --- a/src/base/base_inc.c +++ b/src/base/base_inc.c @@ -12,7 +12,7 @@ #include "base_arena.c" #include "base_math.c" #include "base_strings.c" -#include "base_sync.c" +#include "base_threads.c" #include "base_thread_context.c" #include "base_command_line.c" #include "base_markup.c" diff --git a/src/base/base_inc.h b/src/base/base_inc.h index 72d22362..4bf367da 100644 --- a/src/base/base_inc.h +++ b/src/base/base_inc.h @@ -14,7 +14,7 @@ #include "base_arena.h" #include "base_math.h" #include "base_strings.h" -#include "base_sync.h" +#include "base_threads.h" #include "base_thread_context.h" #include "base_command_line.h" #include "base_markup.h" diff --git a/src/base/base_sync.c b/src/base/base_threads.c similarity index 64% rename from src/base/base_sync.c rename to src/base/base_threads.c index daa5f462..a992ed6f 100644 --- a/src/base/base_sync.c +++ b/src/base/base_threads.c @@ -1,6 +1,29 @@ // Copyright (c) Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +//////////////////////////////// +//~ rjf: Thread Functions + +internal Thread +thread_launch(ThreadEntryPointFunctionType *f, void *p) +{ + Thread thread = os_thread_launch(f, p); + return thread; +} + +internal B32 +thread_join(Thread thread, U64 endt_us) +{ + B32 result = os_thread_join(thread, endt_us); + return result; +} + +internal void +thread_detach(Thread thread) +{ + os_thread_detach(thread); +} + //////////////////////////////// //~ rjf: Synchronization Primitive Functions @@ -15,20 +38,17 @@ internal void mutex_drop(Mutex mutex) {os_mutex_drop(mutex);} internal RWMutex rw_mutex_alloc(void) {return os_rw_mutex_alloc();} internal void rw_mutex_release(RWMutex mutex) {os_rw_mutex_release(mutex);} -internal void rw_mutex_take_r(RWMutex mutex) {os_rw_mutex_take_r(mutex);} -internal void rw_mutex_drop_r(RWMutex mutex) {os_rw_mutex_drop_r(mutex);} -internal void rw_mutex_take_w(RWMutex mutex) {os_rw_mutex_take_w(mutex);} -internal void rw_mutex_drop_w(RWMutex mutex) {os_rw_mutex_drop_w(mutex);} +internal void rw_mutex_take(RWMutex mutex, B32 write_mode) {os_rw_mutex_take(mutex, write_mode);} +internal void rw_mutex_drop(RWMutex mutex, B32 write_mode) {os_rw_mutex_drop(mutex, write_mode);} //- rjf: condition variables -internal CondVar cond_var_alloc(void) {return os_cond_var_alloc();} -internal void cond_var_release(CondVar cv) {os_cond_var_release(cv);} -internal B32 cond_var_wait(CondVar cv, Mutex mutex, U64 endt_us) {return os_cond_var_wait(cv, mutex, endt_us);} -internal B32 cond_var_wait_rw_r(CondVar cv, RWMutex mutex_rw, U64 endt_us) {return os_cond_var_wait_rw_r(cv, mutex_rw, endt_us);} -internal B32 cond_var_wait_rw_w(CondVar cv, RWMutex mutex_rw, U64 endt_us) {return os_cond_var_wait_rw_w(cv, mutex_rw, endt_us);} -internal void cond_var_signal(CondVar cv) {os_cond_var_signal(cv);} -internal void cond_var_broadcast(CondVar cv) {os_cond_var_broadcast(cv);} +internal CondVar cond_var_alloc(void) {return os_cond_var_alloc();} +internal void cond_var_release(CondVar cv) {os_cond_var_release(cv);} +internal B32 cond_var_wait(CondVar cv, Mutex mutex, U64 endt_us) {return os_cond_var_wait(cv, mutex, endt_us);} +internal B32 cond_var_wait_rw(CondVar cv, RWMutex mutex_rw, B32 write_mode, U64 endt_us) {return os_cond_var_wait_rw(cv, mutex_rw, write_mode, endt_us);} +internal void cond_var_signal(CondVar cv) {os_cond_var_signal(cv);} +internal void cond_var_broadcast(CondVar cv) {os_cond_var_broadcast(cv);} //- rjf: cross-process semaphores diff --git a/src/base/base_sync.h b/src/base/base_threads.h similarity index 63% rename from src/base/base_sync.h rename to src/base/base_threads.h index c3251037..d33712b5 100644 --- a/src/base/base_sync.h +++ b/src/base/base_threads.h @@ -1,8 +1,18 @@ // Copyright (c) Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -#ifndef BASE_SYNC_H -#define BASE_SYNC_H +#ifndef BASE_THREADS_H +#define BASE_THREADS_H + +//////////////////////////////// +//~ rjf: Thread Types + +typedef struct Thread Thread; +struct Thread +{ + U64 u64[1]; +}; +typedef void ThreadEntryPointFunctionType(void *p); //////////////////////////////// //~ rjf: Synchronization Primitive Types @@ -37,6 +47,13 @@ struct Barrier U64 u64[1]; }; +//////////////////////////////// +//~ rjf: Thread Functions + +internal Thread thread_launch(ThreadEntryPointFunctionType *f, void *p); +internal B32 thread_join(Thread thread, U64 endt_us); +internal void thread_detach(Thread thread); + //////////////////////////////// //~ rjf: Synchronization Primitive Functions @@ -49,18 +66,21 @@ internal void mutex_drop(Mutex mutex); //- rjf: reader/writer mutexes internal RWMutex rw_mutex_alloc(void); internal void rw_mutex_release(RWMutex mutex); -internal void rw_mutex_take_r(RWMutex mutex); -internal void rw_mutex_drop_r(RWMutex mutex); -internal void rw_mutex_take_w(RWMutex mutex); -internal void rw_mutex_drop_w(RWMutex mutex); +internal void rw_mutex_take(RWMutex mutex, B32 write_mode); +internal void rw_mutex_drop(RWMutex mutex, B32 write_mode); +#define rw_mutex_take_r(m) rw_mutex_take((m), (0)) +#define rw_mutex_take_w(m) rw_mutex_take((m), (1)) +#define rw_mutex_drop_r(m) rw_mutex_drop((m), (0)) +#define rw_mutex_drop_w(m) rw_mutex_drop((m), (1)) //- rjf: condition variables internal CondVar cond_var_alloc(void); internal void cond_var_release(CondVar cv); // returns false on timeout, true on signal, (max_wait_ms = max_U64) -> no timeout internal B32 cond_var_wait(CondVar cv, Mutex mutex, U64 endt_us); -internal B32 cond_var_wait_rw_r(CondVar cv, RWMutex mutex_rw, U64 endt_us); -internal B32 cond_var_wait_rw_w(CondVar cv, RWMutex mutex_rw, U64 endt_us); +internal B32 cond_var_wait_rw(CondVar cv, RWMutex mutex_rw, B32 write_mode, U64 endt_us); +#define cond_var_wait_rw_r(cv, m, endt) cond_var_wait_rw((cv), (m), (0), (endt)) +#define cond_var_wait_rw_w(cv, m, endt) cond_var_wait_rw((cv), (m), (1), (endt)) internal void cond_var_signal(CondVar cv); internal void cond_var_broadcast(CondVar cv); @@ -79,8 +99,9 @@ internal void barrier_wait(Barrier barrier); //- rjf: scope macros #define MutexScope(mutex) DeferLoop(mutex_take(mutex), mutex_drop(mutex)) +#define RWMutexScope(mutex, write_mode) DeferLoop(rw_mutex_take((mutex), (write_mode)), rw_mutex_drop((mutex), (write_mode))) #define MutexScopeR(mutex) DeferLoop(rw_mutex_take_r(mutex), rw_mutex_drop_r(mutex)) #define MutexScopeW(mutex) DeferLoop(rw_mutex_take_w(mutex), rw_mutex_drop_w(mutex)) #define MutexScopeRWPromote(mutex) DeferLoop((rw_mutex_drop_r(mutex), rw_mutex_take_w(mutex)), (rw_mutex_drop_w(mutex), rw_mutex_take_r(mutex))) -#endif // BASE_SYNC_H +#endif // BASE_THREADS_H diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index ec12c673..aa85862a 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1603,7 +1603,7 @@ ctrl_init(void) ctrl_state->u2csb_ring_mutex = mutex_alloc(); ctrl_state->u2csb_ring_cv = cond_var_alloc(); ctrl_state->ctrl_thread_log = log_alloc(); - ctrl_state->ctrl_thread = os_thread_launch(ctrl_thread__entry_point, 0, 0); + ctrl_state->ctrl_thread = thread_launch(ctrl_thread__entry_point, 0); } //////////////////////////////// @@ -1637,7 +1637,7 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 HS_Root root = {0}; { B32 node_found = 0; - OS_MutexScopeR(process_stripe->rw_mutex) + MutexScopeR(process_stripe->rw_mutex) { for(CTRL_ProcessMemoryCacheNode *n = process_slot->first; n != 0; n = n->next) { @@ -1649,7 +1649,7 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 } } } - if(!node_found) OS_MutexScopeW(process_stripe->rw_mutex) + if(!node_found) MutexScopeW(process_stripe->rw_mutex) { for(CTRL_ProcessMemoryCacheNode *n = process_slot->first; n != 0; n = n->next) { @@ -1699,7 +1699,7 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 B32 id_exists = 0; B32 id_stale = 0; B32 id_working = 0; - OS_MutexScopeR(process_stripe->rw_mutex) for(;;) + MutexScopeR(process_stripe->rw_mutex) for(;;) { for(CTRL_ProcessMemoryCacheNode *process_n = process_slot->first; process_n != 0; process_n = process_n->next) { @@ -1747,7 +1747,7 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 if(!id_exists || (id_exists && id_stale && !id_working)) { B32 node_needs_stream = 0; - OS_MutexScopeW(process_stripe->rw_mutex) + MutexScopeW(process_stripe->rw_mutex) { for(CTRL_ProcessMemoryCacheNode *process_n = process_slot->first; process_n != 0; process_n = process_n->next) { @@ -1796,7 +1796,7 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 async_push_work(ctrl_mem_stream_work); requested = 1; } - else OS_MutexScopeW(process_stripe->rw_mutex) + else MutexScopeW(process_stripe->rw_mutex) { for(CTRL_ProcessMemoryCacheNode *process_n = process_slot->first; process_n != 0; process_n = process_n->next) { @@ -2041,7 +2041,7 @@ ctrl_process_write(CTRL_Handle process, Rng1U64 range, void *src) U64 stripe_idx = slot_idx%cache->stripes_count; CTRL_ProcessMemoryCacheSlot *slot = &cache->slots[slot_idx]; CTRL_ProcessMemoryCacheStripe *stripe = &cache->stripes[stripe_idx]; - OS_MutexScopeW(stripe->rw_mutex) + MutexScopeW(stripe->rw_mutex) { for(CTRL_ProcessMemoryCacheNode *proc_n = slot->first; proc_n != 0; proc_n = proc_n->next) { @@ -2097,7 +2097,7 @@ ctrl_reg_block_from_thread(Arena *arena, CTRL_EntityCtx *ctx, CTRL_Handle handle CTRL_ThreadRegCacheSlot *slot = &cache->slots[slot_idx]; CTRL_ThreadRegCacheStripe *stripe = &cache->stripes[stripe_idx]; void *result = push_array(arena, U8, reg_block_size); - OS_MutexScopeW(stripe->rw_mutex) + MutexScopeW(stripe->rw_mutex) { // rjf: find existing node CTRL_ThreadRegCacheNode *node = 0; @@ -2203,7 +2203,7 @@ ctrl_intel_pdata_from_module_voff(Arena *arena, CTRL_Handle module_handle, U64 v U64 stripe_idx = slot_idx%ctrl_state->module_image_info_cache.stripes_count; CTRL_ModuleImageInfoCacheSlot *slot = &ctrl_state->module_image_info_cache.slots[slot_idx]; CTRL_ModuleImageInfoCacheStripe *stripe = &ctrl_state->module_image_info_cache.stripes[stripe_idx]; - OS_MutexScopeR(stripe->rw_mutex) for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next) + MutexScopeR(stripe->rw_mutex) for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next) { if(ctrl_handle_match(n->module, module_handle)) { @@ -2269,7 +2269,7 @@ ctrl_entry_point_voff_from_module(CTRL_Handle module_handle) U64 stripe_idx = slot_idx%ctrl_state->module_image_info_cache.stripes_count; CTRL_ModuleImageInfoCacheSlot *slot = &ctrl_state->module_image_info_cache.slots[slot_idx]; CTRL_ModuleImageInfoCacheStripe *stripe = &ctrl_state->module_image_info_cache.stripes[stripe_idx]; - OS_MutexScopeR(stripe->rw_mutex) for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next) + MutexScopeR(stripe->rw_mutex) for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next) { if(ctrl_handle_match(n->module, module_handle)) { @@ -2289,7 +2289,7 @@ ctrl_tls_vaddr_range_from_module(CTRL_Handle module_handle) U64 stripe_idx = slot_idx%ctrl_state->module_image_info_cache.stripes_count; CTRL_ModuleImageInfoCacheSlot *slot = &ctrl_state->module_image_info_cache.slots[slot_idx]; CTRL_ModuleImageInfoCacheStripe *stripe = &ctrl_state->module_image_info_cache.stripes[stripe_idx]; - OS_MutexScopeR(stripe->rw_mutex) for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next) + MutexScopeR(stripe->rw_mutex) for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next) { if(ctrl_handle_match(n->module, module_handle)) { @@ -2309,7 +2309,7 @@ ctrl_initial_debug_info_path_from_module(Arena *arena, CTRL_Handle module_handle U64 stripe_idx = slot_idx%ctrl_state->module_image_info_cache.stripes_count; CTRL_ModuleImageInfoCacheSlot *slot = &ctrl_state->module_image_info_cache.slots[slot_idx]; CTRL_ModuleImageInfoCacheStripe *stripe = &ctrl_state->module_image_info_cache.stripes[stripe_idx]; - OS_MutexScopeR(stripe->rw_mutex) for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next) + MutexScopeR(stripe->rw_mutex) for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next) { if(ctrl_handle_match(n->module, module_handle)) { @@ -2329,7 +2329,7 @@ ctrl_raddbg_data_from_module(Arena *arena, CTRL_Handle module_handle) U64 stripe_idx = slot_idx%ctrl_state->module_image_info_cache.stripes_count; CTRL_ModuleImageInfoCacheSlot *slot = &ctrl_state->module_image_info_cache.slots[slot_idx]; CTRL_ModuleImageInfoCacheStripe *stripe = &ctrl_state->module_image_info_cache.stripes[stripe_idx]; - OS_MutexScopeR(stripe->rw_mutex) for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next) + MutexScopeR(stripe->rw_mutex) for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next) { if(ctrl_handle_match(n->module, module_handle)) { @@ -3460,7 +3460,7 @@ ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Handle thread_handle, B32 hi B32 node_exists = 0; B32 node_stale = 1; B32 node_working = 0; - OS_MutexScopeR(stripe->rw_mutex) for(;;) + MutexScopeR(stripe->rw_mutex) for(;;) { CTRL_CallStackCacheNode *node = 0; for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) @@ -3499,7 +3499,7 @@ ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Handle thread_handle, B32 hi //- rjf: [write] node does not exist => create; request if new or stale B32 need_request = (!node_exists || node_stale); CTRL_CallStackCacheNode *node_to_request = 0; - if(can_request && need_request) OS_MutexScopeW(stripe->rw_mutex) + if(can_request && need_request) MutexScopeW(stripe->rw_mutex) { CTRL_CallStackCacheNode *node = 0; for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) @@ -3530,7 +3530,7 @@ ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Handle thread_handle, B32 hi { async_push_work(ctrl_call_stack_build_work, .priority = high_priority ? ASYNC_Priority_High : ASYNC_Priority_Low); } - else OS_MutexScopeW(stripe->rw_mutex) + else MutexScopeW(stripe->rw_mutex) { node_to_request->working_count -= 1; } @@ -3551,7 +3551,7 @@ ctrl_call_stack_tree(CTRL_Scope *scope, U64 endt_us) U64 reg_gen = ctrl_reg_gen(); U64 mem_gen = ctrl_mem_gen(); CTRL_CallStackTreeCache *cache = &ctrl_state->call_stack_tree_cache; - OS_MutexScopeR(cache->rw_mutex) for(;;) + MutexScopeR(cache->rw_mutex) for(;;) { // rjf: unpack cache/time state B32 is_stale = (cache->reg_gen != reg_gen || cache->mem_gen != mem_gen); @@ -3641,7 +3641,7 @@ ctrl_u2c_push_msgs(CTRL_MsgList *msgs, U64 endt_us) Temp scratch = scratch_begin(0, 0); String8 msgs_srlzed_baked = ctrl_serialized_string_from_msg_list(scratch.arena, msgs); B32 good = 0; - OS_MutexScope(ctrl_state->u2c_ring_mutex) for(;;) + MutexScope(ctrl_state->u2c_ring_mutex) for(;;) { U64 unconsumed_size = (ctrl_state->u2c_ring_write_pos-ctrl_state->u2c_ring_read_pos); U64 available_size = ctrl_state->u2c_ring_size-unconsumed_size; @@ -3672,7 +3672,7 @@ ctrl_u2c_pop_msgs(Arena *arena) { Temp scratch = scratch_begin(&arena, 1); String8 msgs_srlzed_baked = {0}; - OS_MutexScope(ctrl_state->u2c_ring_mutex) for(;;) + MutexScope(ctrl_state->u2c_ring_mutex) for(;;) { U64 unconsumed_size = (ctrl_state->u2c_ring_write_pos-ctrl_state->u2c_ring_read_pos); if(unconsumed_size >= sizeof(U64)) @@ -3699,7 +3699,7 @@ ctrl_c2u_push_events(CTRL_EventList *events) { if(events->count != 0) ProfScope("ctrl_c2u_push_events") { - OS_MutexScopeW(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) + MutexScopeW(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) { ctrl_entity_store_apply_events(ctrl_state->ctrl_thread_entity_store, events); } @@ -3707,7 +3707,7 @@ ctrl_c2u_push_events(CTRL_EventList *events) { Temp scratch = scratch_begin(0, 0); String8 event_srlzed = ctrl_serialized_string_from_event(scratch.arena, &n->v, ctrl_state->c2u_ring_size-sizeof(U64)); - OS_MutexScope(ctrl_state->c2u_ring_mutex) for(;;) + MutexScope(ctrl_state->c2u_ring_mutex) for(;;) { U64 unconsumed_size = (ctrl_state->c2u_ring_write_pos-ctrl_state->c2u_ring_read_pos); U64 available_size = ctrl_state->c2u_ring_size-unconsumed_size; @@ -3736,7 +3736,7 @@ ctrl_c2u_pop_events(Arena *arena) ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); CTRL_EventList events = {0}; - OS_MutexScope(ctrl_state->c2u_ring_mutex) for(;;) + MutexScope(ctrl_state->c2u_ring_mutex) for(;;) { U64 unconsumed_size = (ctrl_state->c2u_ring_write_pos-ctrl_state->c2u_ring_read_pos); if(unconsumed_size >= sizeof(U64)) @@ -3766,7 +3766,7 @@ ctrl_c2u_pop_events(Arena *arena) internal void ctrl_thread__entry_point(void *p) { - ThreadNameF("[ctrl] thread"); + ThreadNameF("ctrl_thread"); ProfBeginFunction(); DMN_CtrlCtx *ctrl_ctx = dmn_ctrl_begin(); log_select(ctrl_state->ctrl_thread_log); @@ -3896,7 +3896,7 @@ ctrl_thread__entry_point(void *p) CTRL_Entity *debug_info_path = ctrl_entity_child_from_kind(module, CTRL_EntityKind_DebugInfoPath); DI_Key old_dbgi_key = {debug_info_path->string, debug_info_path->timestamp}; di_close(&old_dbgi_key); - OS_MutexScopeW(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) + MutexScopeW(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) { ctrl_entity_equip_string(ctrl_state->ctrl_thread_entity_store, debug_info_path, path_normalized_from_string(scratch.arena, path)); } @@ -4386,7 +4386,7 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_ U64 stripe_idx = slot_idx%ctrl_state->module_image_info_cache.stripes_count; CTRL_ModuleImageInfoCacheSlot *slot = &ctrl_state->module_image_info_cache.slots[slot_idx]; CTRL_ModuleImageInfoCacheStripe *stripe = &ctrl_state->module_image_info_cache.stripes[stripe_idx]; - OS_MutexScopeW(stripe->rw_mutex) + MutexScopeW(stripe->rw_mutex) { CTRL_ModuleImageInfoCacheNode *node = 0; for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next) @@ -4427,7 +4427,7 @@ ctrl_thread__module_close(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr U64 stripe_idx = slot_idx%ctrl_state->module_image_info_cache.stripes_count; CTRL_ModuleImageInfoCacheSlot *slot = &ctrl_state->module_image_info_cache.slots[slot_idx]; CTRL_ModuleImageInfoCacheStripe *stripe = &ctrl_state->module_image_info_cache.stripes[stripe_idx]; - OS_MutexScopeW(stripe->rw_mutex) + MutexScopeW(stripe->rw_mutex) { CTRL_ModuleImageInfoCacheNode *node = 0; for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next) @@ -5068,7 +5068,7 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, U64 stripe_idx = slot_idx%cache->stripes_count; CTRL_ProcessMemoryCacheSlot *slot = &cache->slots[slot_idx]; CTRL_ProcessMemoryCacheStripe *stripe = &cache->stripes[stripe_idx]; - OS_MutexScopeW(stripe->rw_mutex) + MutexScopeW(stripe->rw_mutex) { for(CTRL_ProcessMemoryCacheNode *n = slot->first, *next = 0; n != 0; n = next) { @@ -5431,7 +5431,7 @@ ctrl_thread__launch(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) //- rjf: record (id -> entry points), so that we know custom entry points for this PID CTRL_EntityCtxRWStore *entity_ctx_rw_store = ctrl_state->ctrl_thread_entity_store; - OS_MutexScopeW(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) + MutexScopeW(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) { for(String8Node *n = msg->entry_points.first; n != 0; n = n->next) { @@ -6869,7 +6869,7 @@ internal B32 ctrl_u2ms_enqueue_req(HS_Key key, CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us) { B32 good = 0; - OS_MutexScope(ctrl_state->u2ms_ring_mutex) for(;;) + MutexScope(ctrl_state->u2ms_ring_mutex) for(;;) { U64 unconsumed_size = ctrl_state->u2ms_ring_write_pos-ctrl_state->u2ms_ring_read_pos; U64 available_size = ctrl_state->u2ms_ring_size-unconsumed_size; @@ -6892,7 +6892,7 @@ ctrl_u2ms_enqueue_req(HS_Key key, CTRL_Handle process, Rng1U64 vaddr_range, B32 internal void ctrl_u2ms_dequeue_req(HS_Key *out_key, CTRL_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated) { - OS_MutexScope(ctrl_state->u2ms_ring_mutex) for(;;) + MutexScope(ctrl_state->u2ms_ring_mutex) for(;;) { U64 unconsumed_size = ctrl_state->u2ms_ring_write_pos-ctrl_state->u2ms_ring_read_pos; if(unconsumed_size >= sizeof(*out_key)+sizeof(*out_process)+sizeof(*out_vaddr_range)+sizeof(*out_zero_terminated)) @@ -7045,7 +7045,7 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work) } //- rjf: commit new info to cache - OS_MutexScopeW(process_stripe->rw_mutex) + MutexScopeW(process_stripe->rw_mutex) { for(CTRL_ProcessMemoryCacheNode *n = process_slot->first; n != 0; n = n->next) { @@ -7093,7 +7093,7 @@ internal B32 ctrl_u2csb_enqueue_req(CTRL_Handle thread, U64 endt_us) { B32 good = 0; - OS_MutexScope(ctrl_state->u2csb_ring_mutex) for(;;) + MutexScope(ctrl_state->u2csb_ring_mutex) for(;;) { U64 unconsumed_size = ctrl_state->u2csb_ring_write_pos - ctrl_state->u2csb_ring_read_pos; U64 available_size = ctrl_state->u2csb_ring_size - unconsumed_size; @@ -7119,7 +7119,7 @@ ctrl_u2csb_enqueue_req(CTRL_Handle thread, U64 endt_us) internal void ctrl_u2csb_dequeue_req(CTRL_Handle *out_thread) { - OS_MutexScope(ctrl_state->u2csb_ring_mutex) for(;;) + MutexScope(ctrl_state->u2csb_ring_mutex) for(;;) { U64 unconsumed_size = ctrl_state->u2csb_ring_write_pos - ctrl_state->u2csb_ring_read_pos; if(unconsumed_size >= sizeof(*out_thread)) @@ -7150,7 +7150,7 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) //- rjf: produce mini entity context for just this process CTRL_EntityCtx *entity_ctx = push_array(scratch.arena, CTRL_EntityCtx, 1); - OS_MutexScopeR(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) + MutexScopeR(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) { CTRL_EntityCtx *src_ctx = &ctrl_state->ctrl_thread_entity_store->ctx; CTRL_EntityCtx *dst_ctx = entity_ctx; @@ -7263,7 +7263,7 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) { B32 found = 0; B32 committed = 0; - OS_MutexScopeW(stripe->rw_mutex) for(;;) + MutexScopeW(stripe->rw_mutex) for(;;) { // rjf: try to find node & commit for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) @@ -7311,7 +7311,7 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) } //- rjf: mark work as done - OS_MutexScopeW(stripe->rw_mutex) for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) + MutexScopeW(stripe->rw_mutex) for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) { if(ctrl_handle_match(n->thread, thread_handle)) { @@ -7345,7 +7345,7 @@ ASYNC_WORK_DEF(ctrl_call_stack_tree_build_work) CTRL_Handle *threads = 0; CTRL_Handle *threads_processes = 0; Arch *threads_arches = 0; - OS_MutexScopeR(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) + MutexScopeR(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) { CTRL_EntityCtx *ctx = &ctrl_state->ctrl_thread_entity_store->ctx; CTRL_EntityArray thread_entities = ctrl_entity_array_from_kind(ctx, CTRL_EntityKind_Thread); @@ -7434,7 +7434,7 @@ ASYNC_WORK_DEF(ctrl_call_stack_tree_build_work) CTRL_CallStackTreeCache *cache = &ctrl_state->call_stack_tree_cache; if(tree.root != &ctrl_call_stack_tree_node_nil) { - OS_MutexScopeW(cache->rw_mutex) for(;;) + MutexScopeW(cache->rw_mutex) for(;;) { if(cache->scope_touch_count == 0) { diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index c9a996d7..1ba02bc7 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -870,7 +870,7 @@ struct CTRL_State // rjf: ctrl thread state U64 ctrl_thread_run_state; String8 ctrl_thread_log_path; - OS_Handle ctrl_thread; + Thread ctrl_thread; Log *ctrl_thread_log; RWMutex ctrl_thread_entity_ctx_rw_mutex; CTRL_EntityCtxRWStore *ctrl_thread_entity_store; diff --git a/src/dasm_cache/dasm_cache.c b/src/dasm_cache/dasm_cache.c index 1fb6dcc5..6cd83d9a 100644 --- a/src/dasm_cache/dasm_cache.c +++ b/src/dasm_cache/dasm_cache.c @@ -277,7 +277,7 @@ dasm_init(void) dasm_shared->u2p_ring_base = push_array_no_zero(arena, U8, dasm_shared->u2p_ring_size); dasm_shared->u2p_ring_cv = cond_var_alloc(); dasm_shared->u2p_ring_mutex = mutex_alloc(); - dasm_shared->evictor_detector_thread = os_thread_launch(dasm_evictor_detector_thread__entry_point, 0, 0); + dasm_shared->evictor_detector_thread = thread_launch(dasm_evictor_detector_thread__entry_point, 0); } //////////////////////////////// @@ -308,7 +308,7 @@ dasm_scope_close(DASM_Scope *scope) U64 stripe_idx = slot_idx%dasm_shared->stripes_count; DASM_Slot *slot = &dasm_shared->slots[slot_idx]; DASM_Stripe *stripe = &dasm_shared->stripes[stripe_idx]; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(DASM_Node *n = slot->first; n != 0; n = n->next) { @@ -353,7 +353,7 @@ dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params) //- rjf: try to get existing results B32 found = 0; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(DASM_Node *n = slot->first; n != 0; n = n->next) { @@ -373,7 +373,7 @@ dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params) B32 node_is_new = 0; U64 *node_working_count = 0; HS_Root root = {0}; - OS_MutexScopeW(stripe->rw_mutex) + MutexScopeW(stripe->rw_mutex) { DASM_Node *node = 0; for(DASM_Node *n = slot->first; n != 0; n = n->next) @@ -450,7 +450,7 @@ internal B32 dasm_u2p_enqueue_req(HS_Root root, U128 hash, DASM_Params *params, U64 endt_us) { B32 good = 0; - OS_MutexScope(dasm_shared->u2p_ring_mutex) for(;;) + MutexScope(dasm_shared->u2p_ring_mutex) for(;;) { U64 unconsumed_size = dasm_shared->u2p_ring_write_pos - dasm_shared->u2p_ring_read_pos; U64 available_size = dasm_shared->u2p_ring_size - unconsumed_size; @@ -485,7 +485,7 @@ dasm_u2p_enqueue_req(HS_Root root, U128 hash, DASM_Params *params, U64 endt_us) internal void dasm_u2p_dequeue_req(Arena *arena, HS_Root *root_out, U128 *hash_out, DASM_Params *params_out) { - OS_MutexScope(dasm_shared->u2p_ring_mutex) for(;;) + MutexScope(dasm_shared->u2p_ring_mutex) for(;;) { U64 unconsumed_size = dasm_shared->u2p_ring_write_pos - dasm_shared->u2p_ring_read_pos; if(unconsumed_size >= sizeof(*hash_out)+sizeof(U64)+sizeof(Arch)+sizeof(DASM_StyleFlags)+sizeof(DASM_Syntax)+sizeof(U64)+sizeof(U64)+sizeof(U64)) @@ -722,7 +722,7 @@ ASYNC_WORK_DEF(dasm_parse_work) } //- rjf: commit results to cache - OS_MutexScopeW(stripe->rw_mutex) + MutexScopeW(stripe->rw_mutex) { for(DASM_Node *n = slot->first; n != 0; n = n->next) { @@ -757,7 +757,7 @@ ASYNC_WORK_DEF(dasm_parse_work) internal void dasm_evictor_detector_thread__entry_point(void *p) { - ThreadNameF("[dasm] evictor/detector thread"); + ThreadNameF("dasm_evictor_detector_thread"); for(;;) { U64 change_gen = fs_change_gen(); @@ -773,7 +773,7 @@ dasm_evictor_detector_thread__entry_point(void *p) DASM_Slot *slot = &dasm_shared->slots[slot_idx]; DASM_Stripe *stripe = &dasm_shared->stripes[stripe_idx]; B32 slot_has_work = 0; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(DASM_Node *n = slot->first; n != 0; n = n->next) { @@ -794,7 +794,7 @@ dasm_evictor_detector_thread__entry_point(void *p) } } } - if(slot_has_work) OS_MutexScopeW(stripe->rw_mutex) + if(slot_has_work) MutexScopeW(stripe->rw_mutex) { for(DASM_Node *n = slot->first, *next = 0; n != 0; n = next) { diff --git a/src/dasm_cache/dasm_cache.h b/src/dasm_cache/dasm_cache.h index 5423ddb2..898089ed 100644 --- a/src/dasm_cache/dasm_cache.h +++ b/src/dasm_cache/dasm_cache.h @@ -263,7 +263,7 @@ struct DASM_Shared Mutex u2p_ring_mutex; // rjf: evictor/detector thread - OS_Handle evictor_detector_thread; + Thread evictor_detector_thread; }; //////////////////////////////// diff --git a/src/dbgi/dbgi.c b/src/dbgi/dbgi.c index 49aec576..aff0da46 100644 --- a/src/dbgi/dbgi.c +++ b/src/dbgi/dbgi.c @@ -238,9 +238,9 @@ di_init(void) di_shared->search_threads[idx].ring_cv = cond_var_alloc(); di_shared->search_threads[idx].ring_size = KB(64); di_shared->search_threads[idx].ring_base = push_array_no_zero(arena, U8, di_shared->search_threads[idx].ring_size); - di_shared->search_threads[idx].thread = os_thread_launch(di_search_thread__entry_point, (void *)idx, 0); + di_shared->search_threads[idx].thread = thread_launch(di_search_thread__entry_point, (void *)idx); } - di_shared->search_evictor_thread = os_thread_launch(di_search_evictor_thread__entry_point, 0, 0); + di_shared->search_evictor_thread = thread_launch(di_search_evictor_thread__entry_point, 0); } //////////////////////////////// @@ -468,7 +468,7 @@ di_open(DI_Key *key) DI_Slot *slot = &di_shared->slots[slot_idx]; DI_Stripe *stripe = &di_shared->stripes[stripe_idx]; log_infof("open_debug_info: {\"%S\", 0x%I64x}\n", key->path, key->min_timestamp); - OS_MutexScopeW(stripe->rw_mutex) + MutexScopeW(stripe->rw_mutex) { //- rjf: find existing node DI_Node *node = di_node_from_key_slot__stripe_mutex_r_guarded(slot, key); @@ -529,7 +529,7 @@ di_close(DI_Key *key) DI_Slot *slot = &di_shared->slots[slot_idx]; DI_Stripe *stripe = &di_shared->stripes[stripe_idx]; log_infof("close_debug_info: {\"%S\", 0x%I64x}\n", key->path, key->min_timestamp); - OS_MutexScopeW(stripe->rw_mutex) + MutexScopeW(stripe->rw_mutex) { //- rjf: find existing node DI_Node *node = di_node_from_key_slot__stripe_mutex_r_guarded(slot, key); @@ -591,7 +591,7 @@ di_rdi_from_key(DI_Scope *scope, DI_Key *key, B32 high_priority, U64 endt_us) U64 stripe_idx = slot_idx%di_shared->stripes_count; DI_Slot *slot = &di_shared->slots[slot_idx]; DI_Stripe *stripe = &di_shared->stripes[stripe_idx]; - ProfScope("grab node") OS_MutexScopeR(stripe->rw_mutex) for(;;) + ProfScope("grab node") MutexScopeR(stripe->rw_mutex) for(;;) { //- rjf: find existing node DI_Node *node = di_node_from_key_slot__stripe_mutex_r_guarded(slot, key); @@ -662,7 +662,7 @@ di_search_items_from_key_params_query(DI_Scope *scope, U128 key, DI_SearchParams U64 stripe_idx = slot_idx%di_shared->search_stripes_count; DI_SearchSlot * slot = &di_shared->search_slots[slot_idx]; DI_SearchStripe * stripe = &di_shared->search_stripes[stripe_idx]; - OS_MutexScopeW(stripe->rw_mutex) for(;;) + MutexScopeW(stripe->rw_mutex) for(;;) { // rjf: map key -> node DI_SearchNode *node = 0; @@ -753,7 +753,7 @@ internal B32 di_u2p_enqueue_key(DI_Key *key, U64 endt_us) { B32 sent = 0; - OS_MutexScope(di_shared->u2p_ring_mutex) for(;;) + MutexScope(di_shared->u2p_ring_mutex) for(;;) { U64 unconsumed_size = di_shared->u2p_ring_write_pos - di_shared->u2p_ring_read_pos; U64 available_size = di_shared->u2p_ring_size - unconsumed_size; @@ -782,7 +782,7 @@ di_u2p_enqueue_key(DI_Key *key, U64 endt_us) internal void di_u2p_dequeue_key(Arena *arena, DI_Key *out_key) { - OS_MutexScope(di_shared->u2p_ring_mutex) for(;;) + MutexScope(di_shared->u2p_ring_mutex) for(;;) { U64 unconsumed_size = di_shared->u2p_ring_write_pos - di_shared->u2p_ring_read_pos; if(unconsumed_size >= sizeof(out_key->path.size) + sizeof(out_key->min_timestamp)) @@ -801,7 +801,7 @@ di_u2p_dequeue_key(Arena *arena, DI_Key *out_key) internal void di_p2u_push_event(DI_Event *event) { - OS_MutexScope(di_shared->p2u_ring_mutex) for(;;) + MutexScope(di_shared->p2u_ring_mutex) for(;;) { U64 unconsumed_size = (di_shared->p2u_ring_write_pos-di_shared->p2u_ring_read_pos); U64 available_size = di_shared->p2u_ring_size-unconsumed_size; @@ -822,7 +822,7 @@ internal DI_EventList di_p2u_pop_events(Arena *arena, U64 endt_us) { DI_EventList events = {0}; - OS_MutexScope(di_shared->p2u_ring_mutex) for(;;) + MutexScope(di_shared->p2u_ring_mutex) for(;;) { U64 unconsumed_size = (di_shared->p2u_ring_write_pos-di_shared->p2u_ring_read_pos); if(unconsumed_size >= sizeof(DI_EventKind) + sizeof(U64)) @@ -1111,7 +1111,7 @@ ASYNC_WORK_DEF(di_parse_work) //////////////////////////// //- rjf: commit parsed info to cache // - OS_MutexScopeW(stripe->rw_mutex) + MutexScopeW(stripe->rw_mutex) { DI_Node *node = di_node_from_key_slot__stripe_mutex_r_guarded(slot, &key); if(node != 0) @@ -1153,7 +1153,7 @@ di_u2s_enqueue_req(U128 key, U64 endt_us) B32 result = 0; U64 thread_idx = key.u64[0]%di_shared->search_threads_count; DI_SearchThread *thread = &di_shared->search_threads[thread_idx]; - OS_MutexScope(thread->ring_mutex) for(;;) + MutexScope(thread->ring_mutex) for(;;) { U64 unconsumed_size = thread->ring_write_pos - thread->ring_read_pos; U64 available_size = thread->ring_size - unconsumed_size; @@ -1181,7 +1181,7 @@ di_u2s_dequeue_req(U64 thread_idx) { U128 key = {0}; DI_SearchThread *thread = &di_shared->search_threads[thread_idx]; - OS_MutexScope(thread->ring_mutex) for(;;) + MutexScope(thread->ring_mutex) for(;;) { U64 unconsumed_size = thread->ring_write_pos - thread->ring_read_pos; if(unconsumed_size >= sizeof(key)) @@ -1272,7 +1272,7 @@ ASYNC_WORK_DEF(di_search_work) //- rjf: every so often, check the key's write gen - if it has been bumped, then cancel if(idx%100 == 0) { - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(DI_SearchNode *n = slot->first; n != 0; n = n->next) { @@ -1385,7 +1385,7 @@ internal void di_search_thread__entry_point(void *p) { U64 thread_idx = (U64)p; - ThreadNameF("[di] search thread #%I64u", thread_idx); + ThreadNameF("di_search_thread_%I64u", thread_idx); for(;;) { Temp scratch = scratch_begin(0, 0); @@ -1402,7 +1402,7 @@ di_search_thread__entry_point(void *p) String8 query = {0}; DI_SearchParams params = {0}; U64 initial_bucket_write_gen = 0; - OS_MutexScopeW(stripe->rw_mutex) + MutexScopeW(stripe->rw_mutex) { for(DI_SearchNode *n = slot->first; n != 0; n = n->next) { @@ -1512,7 +1512,7 @@ di_search_thread__entry_point(void *p) //- rjf: commit to cache - wait on scope touches if(arena != 0) { - OS_MutexScopeW(stripe->rw_mutex) for(;;) + MutexScopeW(stripe->rw_mutex) for(;;) { B32 found = 0; B32 done = 0; @@ -1553,7 +1553,7 @@ di_search_thread__entry_point(void *p) internal void di_search_evictor_thread__entry_point(void *p) { - ThreadNameF("[di] search evictor thread"); + ThreadNameF("di_search_evictor_thread"); for(;;) { for(U64 slot_idx = 0; slot_idx < di_shared->search_slots_count; slot_idx += 1) @@ -1562,7 +1562,7 @@ di_search_evictor_thread__entry_point(void *p) DI_SearchSlot *slot = &di_shared->search_slots[slot_idx]; DI_SearchStripe *stripe = &di_shared->search_stripes[stripe_idx]; B32 slot_has_work = 0; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(DI_SearchNode *n = slot->first; n != 0; n = n->next) { @@ -1573,7 +1573,7 @@ di_search_evictor_thread__entry_point(void *p) } } } - if(slot_has_work) OS_MutexScopeW(stripe->rw_mutex) + if(slot_has_work) MutexScopeW(stripe->rw_mutex) { for(DI_SearchNode *n = slot->first, *next = 0; n != 0; n = next) { @@ -1642,7 +1642,7 @@ di_match_store_begin(DI_MatchStore *store, DI_KeyArray keys) } // rjf: store parameters if needed - if(store->params_hash != params_hash) OS_MutexScopeW(store->params_rw_mutex) + if(store->params_hash != params_hash) MutexScopeW(store->params_rw_mutex) { arena_clear(store->params_arena); store->params_hash = params_hash; @@ -1738,7 +1738,7 @@ di_match_from_name(DI_MatchStore *store, String8 name, U64 endt_us) if(completed_params_hash != store->params_hash && node->req_count == ins_atomic_u64_eval(&node->cmp_count)) { B32 sent = 0; - OS_MutexScope(store->u2m_ring_mutex) for(;;) + MutexScope(store->u2m_ring_mutex) for(;;) { U64 unconsumed_size = store->u2m_ring_write_pos - store->u2m_ring_read_pos; U64 available_size = store->u2m_ring_size - unconsumed_size; @@ -1770,7 +1770,7 @@ di_match_from_name(DI_MatchStore *store, String8 name, U64 endt_us) // rjf: if this node's state is stale, wait for it if we need to if(os_now_microseconds() < endt_us && node->req_params_hash != completed_params_hash) { - OS_MutexScopeR(store->match_rw_mutex) for(;;) + MutexScopeR(store->match_rw_mutex) for(;;) { if(node->req_params_hash == ins_atomic_u64_eval(&node->cmp_params_hash)) { @@ -1805,7 +1805,7 @@ ASYNC_WORK_DEF(di_match_work) DI_MatchNameNode *node = 0; U64 alloc_gen = 0; String8 name = {0}; - ProfScope("get next name") OS_MutexScope(store->u2m_ring_mutex) for(;;) + ProfScope("get next name") MutexScope(store->u2m_ring_mutex) for(;;) { U64 unconsumed_size = store->u2m_ring_write_pos - store->u2m_ring_read_pos; if(unconsumed_size >= sizeof(U64)) @@ -1824,7 +1824,7 @@ ASYNC_WORK_DEF(di_match_work) //- rjf: read parameters U64 params_hash = 0; DI_KeyArray params_keys = {0}; - ProfScope("read parameters") OS_MutexScopeR(store->params_rw_mutex) + ProfScope("read parameters") MutexScopeR(store->params_rw_mutex) { params_keys = di_key_array_copy(scratch.arena, &store->params_keys); params_hash = store->params_hash; diff --git a/src/dbgi/dbgi.h b/src/dbgi/dbgi.h index 48545d26..10f59b27 100644 --- a/src/dbgi/dbgi.h +++ b/src/dbgi/dbgi.h @@ -248,7 +248,7 @@ struct DI_TCTX typedef struct DI_SearchThread DI_SearchThread; struct DI_SearchThread { - OS_Handle thread; + Thread thread; Mutex ring_mutex; CondVar ring_cv; U64 ring_size; @@ -386,7 +386,7 @@ struct DI_Shared // rjf: search threads U64 search_threads_count; DI_SearchThread *search_threads; - OS_Handle search_evictor_thread; + Thread search_evictor_thread; }; //////////////////////////////// diff --git a/src/demon/linux/demon_core_linux.c b/src/demon/linux/demon_core_linux.c index 4fed12a3..8f613189 100644 --- a/src/demon/linux/demon_core_linux.c +++ b/src/demon/linux/demon_core_linux.c @@ -922,7 +922,7 @@ dmn_ctrl_begin(void) internal void dmn_ctrl_exclusive_access_begin(void) { - OS_MutexScope(dmn_lnx_state->access_mutex) + MutexScope(dmn_lnx_state->access_mutex) { dmn_lnx_state->access_run_state = 1; } @@ -931,7 +931,7 @@ dmn_ctrl_exclusive_access_begin(void) internal void dmn_ctrl_exclusive_access_end(void) { - OS_MutexScope(dmn_lnx_state->access_mutex) + MutexScope(dmn_lnx_state->access_mutex) { dmn_lnx_state->access_run_state = 0; } diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index a1a023e2..5c93e2d2 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -866,7 +866,7 @@ dmn_w32_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block) MemoryZero(zmm_d, sizeof(*zmm_d)); } } - + // CET / Shadow Stack if(xstate_mask & XSTATE_MASK_CET_U) { @@ -1204,7 +1204,7 @@ dmn_ctrl_begin(void) internal void dmn_ctrl_exclusive_access_begin(void) { - OS_MutexScope(dmn_w32_shared->access_mutex) + MutexScope(dmn_w32_shared->access_mutex) { dmn_w32_shared->access_run_state = 1; } @@ -1213,7 +1213,7 @@ dmn_ctrl_exclusive_access_begin(void) internal void dmn_ctrl_exclusive_access_end(void) { - OS_MutexScope(dmn_w32_shared->access_mutex) + MutexScope(dmn_w32_shared->access_mutex) { dmn_w32_shared->access_run_state = 0; } diff --git a/src/file_stream/file_stream.c b/src/file_stream/file_stream.c index e322ee83..c4af2cf2 100644 --- a/src/file_stream/file_stream.c +++ b/src/file_stream/file_stream.c @@ -52,11 +52,8 @@ fs_init(void) fs_shared->stripes[idx].cv = cond_var_alloc(); fs_shared->stripes[idx].rw_mutex = rw_mutex_alloc(); } - fs_shared->u2s_ring_size = KB(64); - fs_shared->u2s_ring_base = push_array_no_zero(arena, U8, fs_shared->u2s_ring_size); - fs_shared->u2s_ring_cv = cond_var_alloc(); - fs_shared->u2s_ring_mutex = mutex_alloc(); - fs_shared->detector_thread = os_thread_launch(fs_detector_thread__entry_point, 0, 0); + fs_shared->req_mutex = mutex_alloc(); + fs_shared->req_arena = arena_alloc(); } //////////////////////////////// @@ -84,23 +81,13 @@ fs_key_from_path_range(String8 path, Rng1U64 range, U64 endt_us) FS_Slot *path_slot = &fs_shared->slots[path_slot_idx]; FS_Stripe *path_stripe = &fs_shared->stripes[path_stripe_idx]; - //- rjf: get root for this path + //- rjf: get root for this path - on 1st try (read mode), try to read, on 2nd try (write mode), create node HS_Root root = {0}; - OS_MutexScopeR(path_stripe->rw_mutex) + for(B32 write_mode = 0; write_mode <= 1; write_mode += 1) { B32 node_found = 0; - for(FS_Node *n = path_slot->first; n != 0; n = n->next) + RWMutexScope(path_stripe->rw_mutex, write_mode) { - if(str8_match(n->path, path, 0)) - { - node_found = 1; - root = n->root; - break; - } - } - if(!node_found) OS_MutexScopeRWPromote(path_stripe->rw_mutex) - { - B32 node_found = 0; for(FS_Node *n = path_slot->first; n != 0; n = n->next) { if(str8_match(n->path, path, 0)) @@ -110,7 +97,7 @@ fs_key_from_path_range(String8 path, Rng1U64 range, U64 endt_us) break; } } - if(!node_found) + if(write_mode && !node_found) { FS_Node *node = push_array(path_stripe->arena, FS_Node, 1); SLLQueuePush(path_slot->first, path_slot->last, node); @@ -121,6 +108,10 @@ fs_key_from_path_range(String8 path, Rng1U64 range, U64 endt_us) root = node->root; } } + if(node_found) + { + break; + } } //- rjf: build a key for this path/range combo @@ -131,7 +122,7 @@ fs_key_from_path_range(String8 path, Rng1U64 range, U64 endt_us) if(u128_match(hs_hash_from_key(key, 0), u128_zero())) { // rjf: loop: request, check for results, return until we can't - OS_MutexScopeW(path_stripe->rw_mutex) for(;;) + RWMutexScope(path_stripe->rw_mutex, 1) for(;;) { // rjf: path -> node FS_Node *node = 0; @@ -172,22 +163,27 @@ fs_key_from_path_range(String8 path, Rng1U64 range, U64 endt_us) range_node->id = key.id; } - // rjf: try to send stream request - if(ins_atomic_u64_eval(&range_node->working_count) == 0 && - fs_u2s_enqueue_req(key, range, path, endt_us)) + // rjf: push request + if(range_node->working_count == 0) { - ins_atomic_u64_inc_eval(&range_node->working_count); - DeferLoop(rw_mutex_drop_w(path_stripe->rw_mutex), rw_mutex_take_w(path_stripe->rw_mutex)) + range_node->working_count += 1; + MutexScope(fs_shared->req_mutex) { - async_push_work(fs_stream_work, .working_counter = &range_node->working_count); + FS_RequestNode *n = push_array(fs_shared->req_arena, FS_RequestNode, 1); + SLLQueuePush(fs_shared->first_req, fs_shared->last_req, n); + fs_shared->req_count += 1; + n->v.key = key; + n->v.path = str8_copy(fs_shared->req_arena, path); + n->v.range = range; } + cond_var_broadcast(async_tick_start_cond_var); } // rjf: have time to wait? -> wait on this stripe; otherwise exit B32 have_results = !u128_match(hs_hash_from_key(key, 0), u128_zero()); if(!have_results && os_now_microseconds() < endt_us) { - cond_var_wait_rw_w(path_stripe->cv, path_stripe->rw_mutex, endt_us); + cond_var_wait_rw(path_stripe->cv, path_stripe->rw_mutex, 1, endt_us); } else { @@ -229,7 +225,7 @@ fs_properties_from_path(String8 path) U64 stripe_idx = slot_idx%fs_shared->stripes_count; FS_Slot *slot = &fs_shared->slots[slot_idx]; FS_Stripe *stripe = &fs_shared->stripes[stripe_idx]; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(FS_Node *n = slot->first; n != 0; n = n->next) { @@ -252,6 +248,51 @@ fs_async_tick(void) { Temp scratch = scratch_begin(0, 0); + //- rjf: do detection pass + { + U64 slots_per_stripe = fs_shared->slots_count/fs_shared->stripes_count; + Rng1U64 range = lane_range(fs_shared->stripes_count); + for EachInRange(stripe_idx, range) + { + FS_Stripe *stripe = &fs_shared->stripes[stripe_idx]; + MutexScopeR(stripe->rw_mutex) for(U64 slot_in_stripe_idx = 0; slot_in_stripe_idx < slots_per_stripe; slot_in_stripe_idx += 1) + { + U64 slot_idx = stripe_idx*slots_per_stripe + slot_in_stripe_idx; + FS_Slot *slot = &fs_shared->slots[slot_idx]; + for(FS_Node *n = slot->first; n != 0; n = n->next) + { + FileProperties props = os_properties_from_file_path(n->path); + if(props.modified != n->props.modified) + { + for(U64 range_slot_idx = 0; range_slot_idx < n->slots_count; range_slot_idx += 1) + { + for(FS_RangeNode *range_n = n->slots[range_slot_idx].first; + range_n != 0; + range_n = range_n->next) + { + HS_Key key = hs_key_make(n->root, range_n->id); + if(ins_atomic_u64_eval(&range_n->working_count) == 0) + { + ins_atomic_u64_inc_eval(&range_n->working_count); + MutexScope(fs_shared->req_mutex) + { + FS_RequestNode *req_n = push_array(fs_shared->req_arena, FS_RequestNode, 1); + SLLQueuePush(fs_shared->first_req, fs_shared->last_req, req_n); + fs_shared->req_count += 1; + req_n->v.key = key; + req_n->v.path = str8_copy(fs_shared->req_arena, n->path); + req_n->v.range = range; + } + cond_var_broadcast(async_tick_start_cond_var); + } + } + } + } + } + } + } + } + //- rjf: gather all requests local_persist FS_Request *reqs = 0; local_persist U64 reqs_count = 0; @@ -331,7 +372,7 @@ fs_async_tick(void) } //- rjf: commit info to cache - ProfScope("commit to cache") OS_MutexScopeW(path_stripe->rw_mutex) + ProfScope("commit to cache") MutexScopeW(path_stripe->rw_mutex) { FS_Node *node = 0; for(FS_Node *n = path_slot->first; n != 0; n = n->next) @@ -356,191 +397,3 @@ fs_async_tick(void) scratch_end(scratch); } - -//////////////////////////////// -//~ rjf: Streamer Threads - -internal B32 -fs_u2s_enqueue_req(HS_Key key, Rng1U64 range, String8 path, U64 endt_us) -{ - B32 result = 0; - path.size = Min(path.size, fs_shared->u2s_ring_size); - OS_MutexScope(fs_shared->u2s_ring_mutex) for(;;) - { - U64 unconsumed_size = fs_shared->u2s_ring_write_pos - fs_shared->u2s_ring_read_pos; - U64 available_size = fs_shared->u2s_ring_size - unconsumed_size; - U64 needed_size = sizeof(key) + sizeof(range.min) + sizeof(range.max) + sizeof(path.size) + path.size; - if(available_size >= needed_size) - { - result = 1; - fs_shared->u2s_ring_write_pos += ring_write_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_write_pos, &key); - fs_shared->u2s_ring_write_pos += ring_write_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_write_pos, &range.min); - fs_shared->u2s_ring_write_pos += ring_write_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_write_pos, &range.max); - fs_shared->u2s_ring_write_pos += ring_write_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_write_pos, &path.size); - fs_shared->u2s_ring_write_pos += ring_write(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_write_pos, path.str, path.size); - break; - } - cond_var_wait(fs_shared->u2s_ring_cv, fs_shared->u2s_ring_mutex, endt_us); - } - if(result) - { - cond_var_broadcast(fs_shared->u2s_ring_cv); - } - return result; -} - -internal void -fs_u2s_dequeue_req(Arena *arena, HS_Key *key_out, Rng1U64 *range_out, String8 *path_out) -{ - OS_MutexScope(fs_shared->u2s_ring_mutex) for(;;) - { - U64 unconsumed_size = fs_shared->u2s_ring_write_pos - fs_shared->u2s_ring_read_pos; - if(unconsumed_size >= sizeof(*key_out) + sizeof(U64)*2 + sizeof(U64)) - { - fs_shared->u2s_ring_read_pos += ring_read_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_read_pos, key_out); - fs_shared->u2s_ring_read_pos += ring_read_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_read_pos, &range_out->min); - fs_shared->u2s_ring_read_pos += ring_read_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_read_pos, &range_out->max); - fs_shared->u2s_ring_read_pos += ring_read_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_read_pos, &path_out->size); - path_out->str = push_array(arena, U8, path_out->size); - fs_shared->u2s_ring_read_pos += ring_read(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_read_pos, path_out->str, path_out->size); - break; - } - cond_var_wait(fs_shared->u2s_ring_cv, fs_shared->u2s_ring_mutex, max_U64); - } - cond_var_broadcast(fs_shared->u2s_ring_cv); -} - -ASYNC_WORK_DEF(fs_stream_work) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); - - //- rjf: get next request - HS_Key key = {0}; - Rng1U64 range = {0}; - String8 path = {0}; - fs_u2s_dequeue_req(scratch.arena, &key, &range, &path); - - //- rjf: unpack request - U64 path_hash = fs_little_hash_from_string(path); - U64 path_slot_idx = path_hash%fs_shared->slots_count; - U64 path_stripe_idx = path_slot_idx%fs_shared->stripes_count; - FS_Slot *path_slot = &fs_shared->slots[path_slot_idx]; - FS_Stripe *path_stripe = &fs_shared->stripes[path_stripe_idx]; - - //- rjf: load - ProfBegin("load \"%.*s\"", str8_varg(path)); - FileProperties pre_props = os_properties_from_file_path(path); - U64 range_size = dim_1u64(range); - U64 read_size = Min(pre_props.size - range.min, range_size); - OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite, path); - B32 file_handle_is_valid = !os_handle_match(os_handle_zero(), file); - U64 data_arena_size = read_size+ARENA_HEADER_SIZE; - data_arena_size += KB(4)-1; - data_arena_size -= data_arena_size%KB(4); - ProfBegin("allocate"); - Arena *data_arena = arena_alloc(.reserve_size = data_arena_size, .commit_size = data_arena_size); - ProfEnd(); - ProfBegin("read"); - String8 data = os_string_from_file_range(data_arena, file, r1u64(range.min, range.min+read_size)); - ProfEnd(); - os_file_close(file); - FileProperties post_props = os_properties_from_file_path(path); - - //- rjf: abort if modification timestamps or sizes differ - we did not successfully read the file - B32 read_good = (pre_props.modified == post_props.modified && - pre_props.size == post_props.size && - read_size == data.size && - (file_handle_is_valid || pre_props.flags & FilePropertyFlag_IsFolder)); - if(!read_good) - { - ProfScope("abort") - { - arena_release(data_arena); - MemoryZeroStruct(&data); - data_arena = 0; - } - } - - //- rjf: submit - else - { - ProfScope("submit") - { - hs_submit_data(key, &data_arena, data); - } - } - - //- rjf: commit info to cache - ProfScope("commit to cache") OS_MutexScopeW(path_stripe->rw_mutex) - { - FS_Node *node = 0; - for(FS_Node *n = path_slot->first; n != 0; n = n->next) - { - if(str8_match(n->path, path, 0)) - { - node = n; - break; - } - } - if(node != 0 && read_good) - { - if(node->props.modified != 0) - { - ins_atomic_u64_inc_eval(&fs_shared->change_gen); - } - node->props = post_props; - } - } - cond_var_broadcast(path_stripe->cv); - - ProfEnd(); - scratch_end(scratch); - ProfEnd(); - return 0; -} - -//////////////////////////////// -//~ rjf: Change Detector Thread - -internal void -fs_detector_thread__entry_point(void *p) -{ - ThreadNameF("[fs] detector thread"); - for(;;) - { - U64 slots_per_stripe = fs_shared->slots_count/fs_shared->stripes_count; - for(U64 stripe_idx = 0; stripe_idx < fs_shared->stripes_count; stripe_idx += 1) - { - FS_Stripe *stripe = &fs_shared->stripes[stripe_idx]; - OS_MutexScopeR(stripe->rw_mutex) for(U64 slot_in_stripe_idx = 0; slot_in_stripe_idx < slots_per_stripe; slot_in_stripe_idx += 1) - { - U64 slot_idx = stripe_idx*slots_per_stripe + slot_in_stripe_idx; - FS_Slot *slot = &fs_shared->slots[slot_idx]; - for(FS_Node *n = slot->first; n != 0; n = n->next) - { - FileProperties props = os_properties_from_file_path(n->path); - if(props.modified != n->props.modified) - { - for(U64 range_slot_idx = 0; range_slot_idx < n->slots_count; range_slot_idx += 1) - { - for(FS_RangeNode *range_n = n->slots[range_slot_idx].first; - range_n != 0; - range_n = range_n->next) - { - HS_Key key = hs_key_make(n->root, range_n->id); - if(ins_atomic_u64_eval(&range_n->working_count) == 0 && - fs_u2s_enqueue_req(key, r1u64(key.id.u128[0].u64[0], key.id.u128[0].u64[1]), n->path, os_now_microseconds()+100000)) - { - ins_atomic_u64_inc_eval(&range_n->working_count); - async_push_work(fs_stream_work, .working_counter = &range_n->working_count); - } - } - } - } - } - } - } - os_sleep_milliseconds(100); - } -} diff --git a/src/file_stream/file_stream.h b/src/file_stream/file_stream.h index dae0393b..e549fa52 100644 --- a/src/file_stream/file_stream.h +++ b/src/file_stream/file_stream.h @@ -91,17 +91,6 @@ struct FS_Shared FS_RequestNode *first_req; FS_RequestNode *last_req; U64 req_count; - - // rjf: user -> streamer ring buffer - U64 u2s_ring_size; - U8 *u2s_ring_base; - U64 u2s_ring_write_pos; - U64 u2s_ring_read_pos; - CondVar u2s_ring_cv; - Mutex u2s_ring_mutex; - - // rjf: change detector threads - OS_Handle detector_thread; }; //////////////////////////////// @@ -137,16 +126,4 @@ internal FileProperties fs_properties_from_path(String8 path); internal void fs_async_tick(void); -//////////////////////////////// -//~ rjf: Streaming Work - -internal B32 fs_u2s_enqueue_req(HS_Key key, Rng1U64 range, String8 path, U64 endt_us); -internal void fs_u2s_dequeue_req(Arena *arena, HS_Key *key_out, Rng1U64 *range_out, String8 *path_out); -ASYNC_WORK_DEF(fs_stream_work); - -//////////////////////////////// -//~ rjf: Change Detector Thread - -internal void fs_detector_thread__entry_point(void *p); - #endif // FILE_STREAM_H diff --git a/src/geo_cache/geo_cache.c b/src/geo_cache/geo_cache.c index 4aced2ba..f42e152d 100644 --- a/src/geo_cache/geo_cache.c +++ b/src/geo_cache/geo_cache.c @@ -28,7 +28,7 @@ geo_init(void) geo_shared->u2x_ring_base = push_array_no_zero(arena, U8, geo_shared->u2x_ring_size); geo_shared->u2x_ring_cv = cond_var_alloc(); geo_shared->u2x_ring_mutex = mutex_alloc(); - geo_shared->evictor_thread = os_thread_launch(geo_evictor_thread__entry_point, 0, 0); + geo_shared->evictor_thread = thread_launch(geo_evictor_thread__entry_point, 0); } //////////////////////////////// @@ -76,7 +76,7 @@ geo_scope_close(GEO_Scope *scope) U64 stripe_idx = slot_idx%geo_shared->stripes_count; GEO_Slot *slot = &geo_shared->slots[slot_idx]; GEO_Stripe *stripe = &geo_shared->stripes[stripe_idx]; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(GEO_Node *n = slot->first; n != 0; n = n->next) { @@ -126,7 +126,7 @@ geo_buffer_from_hash(GEO_Scope *scope, U128 hash) GEO_Slot *slot = &geo_shared->slots[slot_idx]; GEO_Stripe *stripe = &geo_shared->stripes[stripe_idx]; B32 found = 0; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(GEO_Node *n = slot->first; n != 0; n = n->next) { @@ -142,7 +142,7 @@ geo_buffer_from_hash(GEO_Scope *scope, U128 hash) B32 node_is_new = 0; if(!found) { - OS_MutexScopeW(stripe->rw_mutex) + MutexScopeW(stripe->rw_mutex) { GEO_Node *node = 0; for(GEO_Node *n = slot->first; n != 0; n = n->next) @@ -203,7 +203,7 @@ internal B32 geo_u2x_enqueue_req(U128 hash, U64 endt_us) { B32 good = 0; - OS_MutexScope(geo_shared->u2x_ring_mutex) for(;;) + MutexScope(geo_shared->u2x_ring_mutex) for(;;) { U64 unconsumed_size = geo_shared->u2x_ring_write_pos-geo_shared->u2x_ring_read_pos; U64 available_size = geo_shared->u2x_ring_size-unconsumed_size; @@ -229,7 +229,7 @@ geo_u2x_enqueue_req(U128 hash, U64 endt_us) internal void geo_u2x_dequeue_req(U128 *hash_out) { - OS_MutexScope(geo_shared->u2x_ring_mutex) for(;;) + MutexScope(geo_shared->u2x_ring_mutex) for(;;) { U64 unconsumed_size = geo_shared->u2x_ring_write_pos-geo_shared->u2x_ring_read_pos; if(unconsumed_size >= sizeof(*hash_out)) @@ -259,7 +259,7 @@ ASYNC_WORK_DEF(geo_xfer_work) //- rjf: take task B32 got_task = 0; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(GEO_Node *n = slot->first; n != 0; n = n->next) { @@ -286,7 +286,7 @@ ASYNC_WORK_DEF(geo_xfer_work) } //- rjf: commit results to cache - if(got_task) OS_MutexScopeW(stripe->rw_mutex) + if(got_task) MutexScopeW(stripe->rw_mutex) { for(GEO_Node *n = slot->first; n != 0; n = n->next) { @@ -311,7 +311,7 @@ ASYNC_WORK_DEF(geo_xfer_work) internal void geo_evictor_thread__entry_point(void *p) { - ThreadNameF("[geo] evictor thread"); + ThreadNameF("geo_evictor_thread"); for(;;) { U64 check_time_us = os_now_microseconds(); @@ -324,7 +324,7 @@ geo_evictor_thread__entry_point(void *p) GEO_Slot *slot = &geo_shared->slots[slot_idx]; GEO_Stripe *stripe = &geo_shared->stripes[stripe_idx]; B32 slot_has_work = 0; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(GEO_Node *n = slot->first; n != 0; n = n->next) { @@ -339,7 +339,7 @@ geo_evictor_thread__entry_point(void *p) } } } - if(slot_has_work) OS_MutexScopeW(stripe->rw_mutex) + if(slot_has_work) MutexScopeW(stripe->rw_mutex) { for(GEO_Node *n = slot->first, *next = 0; n != 0; n = next) { diff --git a/src/geo_cache/geo_cache.h b/src/geo_cache/geo_cache.h index 1d3f0bf3..24dd4941 100644 --- a/src/geo_cache/geo_cache.h +++ b/src/geo_cache/geo_cache.h @@ -88,7 +88,7 @@ struct GEO_Shared Mutex u2x_ring_mutex; // rjf: evictor thread - OS_Handle evictor_thread; + Thread evictor_thread; }; //////////////////////////////// diff --git a/src/hash_store/hash_store.c b/src/hash_store/hash_store.c index e3d934e5..09c65180 100644 --- a/src/hash_store/hash_store.c +++ b/src/hash_store/hash_store.c @@ -103,7 +103,7 @@ hs_init(void) stripe->rw_mutex = rw_mutex_alloc(); stripe->cv = cond_var_alloc(); } - hs_shared->evictor_thread = os_thread_launch(hs_evictor_thread__entry_point, 0, 0); + hs_shared->evictor_thread = thread_launch(hs_evictor_thread__entry_point, 0); } //////////////////////////////// @@ -118,7 +118,7 @@ hs_root_alloc(void) U64 stripe_idx = slot_idx%hs_shared->root_stripes_count; HS_RootSlot *slot = &hs_shared->root_slots[slot_idx]; HS_Stripe *stripe = &hs_shared->root_stripes[stripe_idx]; - OS_MutexScopeW(stripe->rw_mutex) + MutexScopeW(stripe->rw_mutex) { HS_RootNode *node = hs_shared->root_stripes_free_nodes[stripe_idx]; if(node != 0) @@ -148,7 +148,7 @@ hs_root_release(HS_Root root) //- rjf: release root node, grab its arena / ID list Arena *root_arena = 0; HS_RootIDChunkList root_ids = {0}; - OS_MutexScopeW(stripe->rw_mutex) + MutexScopeW(stripe->rw_mutex) { for(HS_RootNode *n = slot->first; n != 0; n = n->next) { @@ -175,7 +175,7 @@ hs_root_release(HS_Root root) U64 key_stripe_idx = key_slot_idx%hs_shared->key_stripes_count; HS_KeySlot *key_slot = &hs_shared->key_slots[key_slot_idx]; HS_Stripe *key_stripe = &hs_shared->key_stripes[key_stripe_idx]; - OS_MutexScopeW(key_stripe->rw_mutex) + MutexScopeW(key_stripe->rw_mutex) { for(HS_KeyNode *n = key_slot->first; n != 0; n = n->next) { @@ -189,7 +189,7 @@ hs_root_release(HS_Root root) U64 hash_stripe_idx = hash_slot_idx%hs_shared->stripes_count; HS_Slot *hash_slot = &hs_shared->slots[hash_slot_idx]; HS_Stripe *hash_stripe = &hs_shared->stripes[hash_stripe_idx]; - OS_MutexScopeR(hash_stripe->rw_mutex) + MutexScopeR(hash_stripe->rw_mutex) { for(HS_Node *n = hash_slot->first; n != 0; n = n->next) { @@ -231,7 +231,7 @@ hs_submit_data(HS_Key key, Arena **data_arena, String8 data) HS_Stripe *stripe = &hs_shared->stripes[stripe_idx]; //- rjf: commit data to cache - if already there, just bump key refcount - ProfScope("commit data to cache - if already there, just bump key refcount") OS_MutexScopeW(stripe->rw_mutex) + ProfScope("commit data to cache - if already there, just bump key refcount") MutexScopeW(stripe->rw_mutex) { HS_Node *existing_node = 0; for(HS_Node *n = slot->first; n != 0; n = n->next) @@ -279,7 +279,7 @@ hs_submit_data(HS_Key key, Arena **data_arena, String8 data) //- rjf: commit this hash to key cache U128 key_expired_hash = {0}; - ProfScope("commit this hash to key cache") OS_MutexScopeW(key_stripe->rw_mutex) + ProfScope("commit this hash to key cache") MutexScopeW(key_stripe->rw_mutex) { // rjf: find existing key B32 key_is_new = 0; @@ -329,7 +329,7 @@ hs_submit_data(HS_Key key, Arena **data_arena, String8 data) U64 root_stripe_idx = root_slot_idx%hs_shared->root_stripes_count; HS_RootSlot *root_slot = &hs_shared->root_slots[root_slot_idx]; HS_Stripe *root_stripe = &hs_shared->root_stripes[root_stripe_idx]; - OS_MutexScopeW(root_stripe->rw_mutex) + MutexScopeW(root_stripe->rw_mutex) { for(HS_RootNode *n = root_slot->first; n != 0; n = n->next) { @@ -362,7 +362,7 @@ hs_submit_data(HS_Key key, Arena **data_arena, String8 data) U64 old_hash_stripe_idx = old_hash_slot_idx%hs_shared->stripes_count; HS_Slot *old_hash_slot = &hs_shared->slots[old_hash_slot_idx]; HS_Stripe *old_hash_stripe = &hs_shared->stripes[old_hash_stripe_idx]; - OS_MutexScopeR(old_hash_stripe->rw_mutex) + MutexScopeR(old_hash_stripe->rw_mutex) { for(HS_Node *n = old_hash_slot->first; n != 0; n = n->next) { @@ -414,7 +414,7 @@ hs_scope_close(HS_Scope *scope) U64 stripe_idx = slot_idx%hs_shared->stripes_count; HS_Slot *slot = &hs_shared->slots[slot_idx]; HS_Stripe *stripe = &hs_shared->stripes[stripe_idx]; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(HS_Node *n = slot->first; n != 0; n = n->next) { @@ -458,7 +458,7 @@ hs_hash_downstream_inc(U128 hash) U64 stripe_idx = slot_idx%hs_shared->stripes_count; HS_Slot *slot = &hs_shared->slots[slot_idx]; HS_Stripe *stripe = &hs_shared->stripes[stripe_idx]; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(HS_Node *n = slot->first; n != 0; n = n->next) { @@ -478,7 +478,7 @@ hs_hash_downstream_dec(U128 hash) U64 stripe_idx = slot_idx%hs_shared->stripes_count; HS_Slot *slot = &hs_shared->slots[slot_idx]; HS_Stripe *stripe = &hs_shared->stripes[stripe_idx]; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(HS_Node *n = slot->first; n != 0; n = n->next) { @@ -503,7 +503,7 @@ hs_hash_from_key(HS_Key key, U64 rewind_count) U64 key_stripe_idx = key_slot_idx%hs_shared->key_stripes_count; HS_KeySlot *key_slot = &hs_shared->key_slots[key_slot_idx]; HS_Stripe *key_stripe = &hs_shared->key_stripes[key_stripe_idx]; - OS_MutexScopeR(key_stripe->rw_mutex) + MutexScopeR(key_stripe->rw_mutex) { for(HS_KeyNode *n = key_slot->first; n != 0; n = n->next) { @@ -526,7 +526,7 @@ hs_data_from_hash(HS_Scope *scope, U128 hash) U64 stripe_idx = slot_idx%hs_shared->stripes_count; HS_Slot *slot = &hs_shared->slots[slot_idx]; HS_Stripe *stripe = &hs_shared->stripes[stripe_idx]; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(HS_Node *n = slot->first; n != 0; n = n->next) { @@ -548,7 +548,7 @@ hs_data_from_hash(HS_Scope *scope, U128 hash) internal void hs_evictor_thread__entry_point(void *p) { - ThreadNameF("[hs] evictor thread"); + ThreadNameF("hs_evictor_thread"); for(;;) { for(U64 slot_idx = 0; slot_idx < hs_shared->slots_count; slot_idx += 1) @@ -557,7 +557,7 @@ hs_evictor_thread__entry_point(void *p) HS_Slot *slot = &hs_shared->slots[slot_idx]; HS_Stripe *stripe = &hs_shared->stripes[stripe_idx]; B32 slot_has_work = 0; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(HS_Node *n = slot->first; n != 0; n = n->next) { @@ -571,7 +571,7 @@ hs_evictor_thread__entry_point(void *p) } } } - if(slot_has_work) OS_MutexScopeW(stripe->rw_mutex) + if(slot_has_work) MutexScopeW(stripe->rw_mutex) { for(HS_Node *n = slot->first, *next = 0; n != 0; n = next) { diff --git a/src/hash_store/hash_store.h b/src/hash_store/hash_store.h index 6bde1a44..97971ee4 100644 --- a/src/hash_store/hash_store.h +++ b/src/hash_store/hash_store.h @@ -208,7 +208,7 @@ struct HS_Shared U64 root_id_gen; // rjf: evictor thread - OS_Handle evictor_thread; + Thread evictor_thread; }; //////////////////////////////// diff --git a/src/mutable_text/mutable_text.c b/src/mutable_text/mutable_text.c index e052d5d5..10643b89 100644 --- a/src/mutable_text/mutable_text.c +++ b/src/mutable_text/mutable_text.c @@ -30,7 +30,7 @@ mtx_init(void) mtx_shared->mut_threads[idx].ring_base = push_array_no_zero(arena, U8, mtx_shared->mut_threads[idx].ring_size); mtx_shared->mut_threads[idx].cv = cond_var_alloc(); mtx_shared->mut_threads[idx].mutex = mutex_alloc(); - mtx_shared->mut_threads[idx].thread = os_thread_launch(mtx_mut_thread__entry_point, &mtx_shared->mut_threads[idx], 0); + mtx_shared->mut_threads[idx].thread = thread_launch(mtx_mut_thread__entry_point, &mtx_shared->mut_threads[idx]); } } @@ -52,7 +52,7 @@ internal void mtx_enqueue_op(MTX_MutThread *thread, HS_Key buffer_key, MTX_Op op) { // TODO(rjf): if op.replace is too big, need to split into multiple edits - OS_MutexScope(thread->mutex) for(;;) + MutexScope(thread->mutex) for(;;) { U64 unconsumed_size = thread->ring_write_pos - thread->ring_read_pos; U64 available_size = thread->ring_size - unconsumed_size; @@ -73,7 +73,7 @@ mtx_enqueue_op(MTX_MutThread *thread, HS_Key buffer_key, MTX_Op op) internal void mtx_dequeue_op(Arena *arena, MTX_MutThread *thread, HS_Key *buffer_key_out, MTX_Op *op_out) { - OS_MutexScope(thread->mutex) for(;;) + MutexScope(thread->mutex) for(;;) { U64 unconsumed_size = thread->ring_write_pos - thread->ring_read_pos; if(unconsumed_size >= sizeof(*buffer_key_out) + sizeof(op_out->range) + sizeof(op_out->replace.size)) @@ -94,7 +94,7 @@ internal void mtx_mut_thread__entry_point(void *p) { MTX_MutThread *mut_thread = (MTX_MutThread *)p; - ThreadNameF("[mtx] mut thread #%I64u", (U64)(mut_thread - mtx_shared->mut_threads)); + ThreadNameF("mtx_mut_thread_%I64u", (U64)(mut_thread - mtx_shared->mut_threads)); for(;;) { Temp scratch = scratch_begin(0, 0); diff --git a/src/mutable_text/mutable_text.h b/src/mutable_text/mutable_text.h index 2f985e85..3957f561 100644 --- a/src/mutable_text/mutable_text.h +++ b/src/mutable_text/mutable_text.h @@ -49,7 +49,7 @@ struct MTX_MutThread U64 ring_write_pos; CondVar cv; Mutex mutex; - OS_Handle thread; + Thread thread; }; //////////////////////////////// diff --git a/src/os/core/linux/os_core_linux.c b/src/os/core/linux/os_core_linux.c index 94210eab..9e01d5ef 100644 --- a/src/os/core/linux/os_core_linux.c +++ b/src/os/core/linux/os_core_linux.c @@ -121,7 +121,7 @@ internal void * os_lnx_thread_entry_point(void *ptr) { OS_LNX_Entity *entity = (OS_LNX_Entity *)ptr; - OS_ThreadFunctionType *func = entity->thread.func; + ThreadEntryPointFunctionType *func = entity->thread.func; void *thread_ptr = entity->thread.ptr; supplement_thread_base_entry_point(func, thread_ptr); return 0; @@ -801,7 +801,7 @@ os_process_kill(OS_Handle handle) //~ rjf: @os_hooks Threads (Implemented Per-OS) internal OS_Handle -os_thread_launch(OS_ThreadFunctionType *func, void *ptr, void *params) +os_thread_launch(ThreadEntryPointFunctionType *func, void *ptr, void *params) { OS_LNX_Entity *entity = os_lnx_entity_alloc(OS_LNX_EntityKind_Thread); entity->thread.func = func; @@ -911,31 +911,22 @@ os_rw_mutex_release(OS_Handle rw_mutex) } internal void -os_rw_mutex_take_r(OS_Handle rw_mutex) +os_rw_mutex_take(OS_Handle rw_mutex, B32 write_mode) { if(os_handle_match(rw_mutex, os_handle_zero())) { return; } OS_LNX_Entity *entity = (OS_LNX_Entity *)rw_mutex.u64[0]; - pthread_rwlock_rdlock(&entity->rwmutex_handle); + if(write_mode) + { + pthread_rwlock_wrlock(&entity->rwmutex_handle); + } + else + { + pthread_rwlock_rdlock(&entity->rwmutex_handle); + } } internal void -os_rw_mutex_drop_r(OS_Handle rw_mutex) -{ - if(os_handle_match(rw_mutex, os_handle_zero())) { return; } - OS_LNX_Entity *entity = (OS_LNX_Entity *)rw_mutex.u64[0]; - pthread_rwlock_unlock(&entity->rwmutex_handle); -} - -internal void -os_rw_mutex_take_w(OS_Handle rw_mutex) -{ - if(os_handle_match(rw_mutex, os_handle_zero())) { return; } - OS_LNX_Entity *entity = (OS_LNX_Entity *)rw_mutex.u64[0]; - pthread_rwlock_wrlock(&entity->rwmutex_handle); -} - -internal void -os_rw_mutex_drop_w(OS_Handle rw_mutex) +os_rw_mutex_drop(OS_Handle rw_mutex, B32 write_mode) { if(os_handle_match(rw_mutex, os_handle_zero())) { return; } OS_LNX_Entity *entity = (OS_LNX_Entity *)rw_mutex.u64[0]; @@ -995,7 +986,7 @@ os_cond_var_wait(OS_Handle cv, OS_Handle mutex, U64 endt_us) } internal B32 -os_cond_var_wait_rw_r(OS_Handle cv, OS_Handle mutex_rw, U64 endt_us) +os_cond_var_wait_rw(OS_Handle cv, OS_Handle mutex_rw, B32 write_mode, U64 endt_us) { // TODO(rjf): because pthread does not supply cv/rw natively, I had to hack // this together, but this would probably just be a lot better if we just @@ -1016,49 +1007,27 @@ os_cond_var_wait_rw_r(OS_Handle cv, OS_Handle mutex_rw, U64 endt_us) int wait_result = pthread_cond_timedwait(&cv_entity->cv.cond_handle, &cv_entity->cv.rwlock_mutex_handle, &endt_timespec); if(wait_result != ETIMEDOUT) { - pthread_rwlock_rdlock(&rw_mutex_entity->rwmutex_handle); + if(write_mode) + { + pthread_rwlock_wrlock(&rw_mutex_entity->rwmutex_handle); + } + else + { + pthread_rwlock_rdlock(&rw_mutex_entity->rwmutex_handle); + } result = 1; break; } if(wait_result == ETIMEDOUT) { - pthread_rwlock_rdlock(&rw_mutex_entity->rwmutex_handle); - break; - } - } - pthread_mutex_unlock(&cv_entity->cv.rwlock_mutex_handle); - return result; -} - -internal B32 -os_cond_var_wait_rw_w(OS_Handle cv, OS_Handle mutex_rw, U64 endt_us) -{ - // TODO(rjf): because pthread does not supply cv/rw natively, I had to hack - // this together, but this would probably just be a lot better if we just - // implemented the primitives ourselves with e.g. futexes - // - if(os_handle_match(cv, os_handle_zero())) { return 0; } - if(os_handle_match(mutex_rw, os_handle_zero())) { return 0; } - OS_LNX_Entity *cv_entity = (OS_LNX_Entity *)cv.u64[0]; - OS_LNX_Entity *rw_mutex_entity = (OS_LNX_Entity *)mutex_rw.u64[0]; - struct timespec endt_timespec; - endt_timespec.tv_sec = endt_us/Million(1); - endt_timespec.tv_nsec = Thousand(1) * (endt_us - (endt_us/Million(1))*Million(1)); - B32 result = 0; - pthread_mutex_lock(&cv_entity->cv.rwlock_mutex_handle); - pthread_rwlock_unlock(&rw_mutex_entity->rwmutex_handle); - for(;;) - { - int wait_result = pthread_cond_timedwait(&cv_entity->cv.cond_handle, &cv_entity->cv.rwlock_mutex_handle, &endt_timespec); - if(wait_result != ETIMEDOUT) - { - pthread_rwlock_wrlock(&rw_mutex_entity->rwmutex_handle); - result = 1; - break; - } - if(wait_result == ETIMEDOUT) - { - pthread_rwlock_wrlock(&rw_mutex_entity->rwmutex_handle); + if(write_mode) + { + pthread_rwlock_wrlock(&rw_mutex_entity->rwmutex_handle); + } + else + { + pthread_rwlock_rdlock(&rw_mutex_entity->rwmutex_handle); + } break; } } @@ -1229,7 +1198,7 @@ os_library_close(OS_Handle lib) //~ rjf: @os_hooks Safe Calls (Implemented Per-OS) internal void -os_safe_call(OS_ThreadFunctionType *func, OS_ThreadFunctionType *fail_handler, void *ptr) +os_safe_call(ThreadEntryPointFunctionType *func, ThreadEntryPointFunctionType *fail_handler, void *ptr) { // rjf: push handler to chain OS_LNX_SafeCallChain chain = {0}; diff --git a/src/os/core/linux/os_core_linux.h b/src/os/core/linux/os_core_linux.h index 4b345a4b..7b335fbb 100644 --- a/src/os/core/linux/os_core_linux.h +++ b/src/os/core/linux/os_core_linux.h @@ -54,7 +54,7 @@ typedef struct OS_LNX_SafeCallChain OS_LNX_SafeCallChain; struct OS_LNX_SafeCallChain { OS_LNX_SafeCallChain *next; - OS_ThreadFunctionType *fail_handler; + ThreadEntryPointFunctionType *fail_handler; void *ptr; }; @@ -81,7 +81,7 @@ struct OS_LNX_Entity struct { pthread_t handle; - OS_ThreadFunctionType *func; + ThreadEntryPointFunctionType *func; void *ptr; } thread; pthread_mutex_t mutex_handle; diff --git a/src/os/core/linux/os_core_linux_old.c b/src/os/core/linux/os_core_linux_old.c index 3e3ae763..4d492f06 100644 --- a/src/os/core/linux/os_core_linux_old.c +++ b/src/os/core/linux/os_core_linux_old.c @@ -783,7 +783,7 @@ lnx_free_entity(LNX_Entity *entity){ internal void* lnx_thread_base(void *ptr){ LNX_Entity *entity = (LNX_Entity*)ptr; - OS_ThreadFunctionType *func = entity->thread.func; + ThreadEntryPointFunctionType *func = entity->thread.func; void *thread_ptr = entity->thread.ptr; TCTX tctx_; @@ -1377,7 +1377,7 @@ os_launch_process(OS_LaunchOptions *options){ //~ rjf: @os_hooks Threads (Implemented Per-OS) internal OS_Handle -os_thread_launch(OS_ThreadFunctionType *func, void *ptr, void *params){ +os_thread_launch(ThreadEntryPointFunctionType *func, void *ptr, void *params){ // entity LNX_Entity *entity = lnx_alloc_entity(LNX_EntityKind_Thread); entity->reference_mask = 0x3; @@ -1642,7 +1642,7 @@ os_library_close(OS_Handle lib) //~ rjf: @os_hooks Dynamically-Loaded Libraries (Implemented Per-OS) internal void -os_safe_call(OS_ThreadFunctionType *func, OS_ThreadFunctionType *fail_handler, void *ptr){ +os_safe_call(ThreadEntryPointFunctionType *func, ThreadEntryPointFunctionType *fail_handler, void *ptr){ LNX_SafeCallChain chain = {0}; SLLStackPush(lnx_safe_call_chain, &chain); chain.fail_handler = fail_handler; diff --git a/src/os/core/linux/os_core_linux_old.h b/src/os/core/linux/os_core_linux_old.h index efec7159..cf133b2a 100644 --- a/src/os/core/linux/os_core_linux_old.h +++ b/src/os/core/linux/os_core_linux_old.h @@ -48,7 +48,7 @@ struct LNX_Entity{ volatile U32 reference_mask; union{ struct{ - OS_ThreadFunctionType *func; + ThreadEntryPointFunctionType *func; void *ptr; pthread_t handle; } thread; @@ -62,7 +62,7 @@ struct LNX_Entity{ struct LNX_SafeCallChain{ LNX_SafeCallChain *next; - OS_ThreadFunctionType *fail_handler; + ThreadEntryPointFunctionType *fail_handler; void *ptr; }; diff --git a/src/os/core/os_core.c b/src/os/core/os_core.c index e4cb49e6..04ede12a 100644 --- a/src/os/core/os_core.c +++ b/src/os/core/os_core.c @@ -40,21 +40,6 @@ os_handle_array_from_list(Arena *arena, OS_HandleList *list) return result; } -//////////////////////////////// -//~ rjf: Command Line Argc/Argv Helper (Helper, Implemented Once) - -internal String8List -os_string_list_from_argcv(Arena *arena, int argc, char **argv) -{ - String8List result = {0}; - for(int i = 0; i < argc; i += 1) - { - String8 str = str8_cstring(argv[i]); - str8_list_push(arena, &result, str); - } - return result; -} - //////////////////////////////// //~ rjf: Filesystem Helpers (Helpers, Implemented Once) diff --git a/src/os/core/os_core.h b/src/os/core/os_core.h index 7737602c..656ab4a4 100644 --- a/src/os/core/os_core.h +++ b/src/os/core/os_core.h @@ -128,11 +128,6 @@ struct OS_ProcessLaunchParams OS_Handle stdin_file; }; -//////////////////////////////// -//~ rjf: Thread Types - -typedef void OS_ThreadFunctionType(void *ptr); - //////////////////////////////// //~ rjf: Handle Type Functions (Helpers, Implemented Once) @@ -141,11 +136,6 @@ internal B32 os_handle_match(OS_Handle a, OS_Handle b); internal void os_handle_list_push(Arena *arena, OS_HandleList *handles, OS_Handle handle); internal OS_HandleArray os_handle_array_from_list(Arena *arena, OS_HandleList *list); -//////////////////////////////// -//~ rjf: Command Line Argc/Argv Helper (Helper, Implemented Once) - -internal String8List os_string_list_from_argcv(Arena *arena, int argc, char **argv); - //////////////////////////////// //~ rjf: Filesystem Helpers (Helpers, Implemented Once) @@ -262,9 +252,9 @@ internal B32 os_process_kill(OS_Handle handle); //////////////////////////////// //~ rjf: @os_hooks Threads (Implemented Per-OS) -internal OS_Handle os_thread_launch(OS_ThreadFunctionType *func, void *ptr, void *params); -internal B32 os_thread_join(OS_Handle handle, U64 endt_us); -internal void os_thread_detach(OS_Handle handle); +internal Thread os_thread_launch(ThreadEntryPointFunctionType *f, void *p); +internal B32 os_thread_join(Thread handle, U64 endt_us); +internal void os_thread_detach(Thread handle); //////////////////////////////// //~ rjf: @os_hooks Synchronization Primitives (Implemented Per-OS) @@ -278,18 +268,15 @@ internal void os_mutex_drop(Mutex mutex); //- rjf: reader/writer mutexes internal RWMutex os_rw_mutex_alloc(void); internal void os_rw_mutex_release(RWMutex mutex); -internal void os_rw_mutex_take_r(RWMutex mutex); -internal void os_rw_mutex_drop_r(RWMutex mutex); -internal void os_rw_mutex_take_w(RWMutex mutex); -internal void os_rw_mutex_drop_w(RWMutex mutex); +internal void os_rw_mutex_take(RWMutex mutex, B32 write_mode); +internal void os_rw_mutex_drop(RWMutex mutex, B32 write_mode); //- rjf: condition variables internal CondVar os_cond_var_alloc(void); internal void os_cond_var_release(CondVar cv); // returns false on timeout, true on signal, (max_wait_ms = max_U64) -> no timeout internal B32 os_cond_var_wait(CondVar cv, Mutex mutex, U64 endt_us); -internal B32 os_cond_var_wait_rw_r(CondVar cv, RWMutex mutex_rw, U64 endt_us); -internal B32 os_cond_var_wait_rw_w(CondVar cv, RWMutex mutex_rw, U64 endt_us); +internal B32 os_cond_var_wait_rw(CondVar cv, RWMutex mutex_rw, B32 write_mode, U64 endt_us); internal void os_cond_var_signal(CondVar cv); internal void os_cond_var_broadcast(CondVar cv); @@ -306,12 +293,6 @@ internal Barrier os_barrier_alloc(U64 count); internal void os_barrier_release(Barrier barrier); internal void os_barrier_wait(Barrier barrier); -//- rjf: scope macros -#define OS_MutexScope(mutex) DeferLoop(os_mutex_take(mutex), os_mutex_drop(mutex)) -#define OS_MutexScopeR(mutex) DeferLoop(os_rw_mutex_take_r(mutex), os_rw_mutex_drop_r(mutex)) -#define OS_MutexScopeW(mutex) DeferLoop(os_rw_mutex_take_w(mutex), os_rw_mutex_drop_w(mutex)) -#define OS_MutexScopeRWPromote(mutex) DeferLoop((os_rw_mutex_drop_r(mutex), os_rw_mutex_take_w(mutex)), (os_rw_mutex_drop_w(mutex), os_rw_mutex_take_r(mutex))) - //////////////////////////////// //~ rjf: @os_hooks Dynamically-Loaded Libraries (Implemented Per-OS) @@ -322,7 +303,7 @@ internal VoidProc *os_library_load_proc(OS_Handle lib, String8 name); //////////////////////////////// //~ rjf: @os_hooks Safe Calls (Implemented Per-OS) -internal void os_safe_call(OS_ThreadFunctionType *func, OS_ThreadFunctionType *fail_handler, void *ptr); +internal void os_safe_call(ThreadEntryPointFunctionType *func, ThreadEntryPointFunctionType *fail_handler, void *ptr); //////////////////////////////// //~ rjf: @os_hooks GUIDs (Implemented Per-OS) diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index d90d68ff..0e29fad9 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -144,7 +144,7 @@ internal DWORD os_w32_thread_entry_point(void *ptr) { OS_W32_Entity *entity = (OS_W32_Entity *)ptr; - OS_ThreadFunctionType *func = entity->thread.func; + ThreadEntryPointFunctionType *func = entity->thread.func; void *thread_ptr = entity->thread.ptr; supplement_thread_base_entry_point(func, thread_ptr); return 0; @@ -1103,19 +1103,19 @@ os_process_detach(OS_Handle handle) //////////////////////////////// //~ rjf: @os_hooks Threads (Implemented Per-OS) -internal OS_Handle -os_thread_launch(OS_ThreadFunctionType *func, void *ptr, void *params) +internal Thread +os_thread_launch(ThreadEntryPointFunctionType *f, void *p) { OS_W32_Entity *entity = os_w32_entity_alloc(OS_W32_EntityKind_Thread); - entity->thread.func = func; - entity->thread.ptr = ptr; + entity->thread.func = f; + entity->thread.ptr = p; entity->thread.handle = CreateThread(0, 0, os_w32_thread_entry_point, entity, 0, &entity->thread.tid); - OS_Handle result = {IntFromPtr(entity)}; + Thread result = {IntFromPtr(entity)}; return result; } internal B32 -os_thread_join(OS_Handle handle, U64 endt_us) +os_thread_join(Thread handle, U64 endt_us) { DWORD sleep_ms = os_w32_sleep_ms_from_endt_us(endt_us); OS_W32_Entity *entity = (OS_W32_Entity *)PtrFromInt(handle.u64[0]); @@ -1130,7 +1130,7 @@ os_thread_join(OS_Handle handle, U64 endt_us) } internal void -os_thread_detach(OS_Handle thread) +os_thread_detach(Thread thread) { OS_W32_Entity *entity = (OS_W32_Entity*)PtrFromInt(thread.u64[0]); if(entity != 0) @@ -1194,31 +1194,31 @@ os_rw_mutex_release(RWMutex rw_mutex) } internal void -os_rw_mutex_take_r(RWMutex rw_mutex) +os_rw_mutex_take(RWMutex rw_mutex, B32 write_mode) { OS_W32_Entity *entity = (OS_W32_Entity*)PtrFromInt(rw_mutex.u64[0]); - AcquireSRWLockShared(&entity->rw_mutex); + if(write_mode) + { + AcquireSRWLockExclusive(&entity->rw_mutex); + } + else + { + AcquireSRWLockShared(&entity->rw_mutex); + } } internal void -os_rw_mutex_drop_r(RWMutex rw_mutex) +os_rw_mutex_drop(RWMutex rw_mutex, B32 write_mode) { OS_W32_Entity *entity = (OS_W32_Entity*)PtrFromInt(rw_mutex.u64[0]); - ReleaseSRWLockShared(&entity->rw_mutex); -} - -internal void -os_rw_mutex_take_w(RWMutex rw_mutex) -{ - OS_W32_Entity *entity = (OS_W32_Entity*)PtrFromInt(rw_mutex.u64[0]); - AcquireSRWLockExclusive(&entity->rw_mutex); -} - -internal void -os_rw_mutex_drop_w(RWMutex rw_mutex) -{ - OS_W32_Entity *entity = (OS_W32_Entity*)PtrFromInt(rw_mutex.u64[0]); - ReleaseSRWLockExclusive(&entity->rw_mutex); + if(write_mode) + { + ReleaseSRWLockExclusive(&entity->rw_mutex); + } + else + { + ReleaseSRWLockShared(&entity->rw_mutex); + } } //- rjf: condition variables @@ -1254,7 +1254,7 @@ os_cond_var_wait(CondVar cv, Mutex mutex, U64 endt_us) } internal B32 -os_cond_var_wait_rw_r(CondVar cv, RWMutex mutex_rw, U64 endt_us) +os_cond_var_wait_rw(CondVar cv, RWMutex mutex_rw, B32 write_mode, U64 endt_us) { U32 sleep_ms = os_w32_sleep_ms_from_endt_us(endt_us); BOOL result = 0; @@ -1263,21 +1263,7 @@ os_cond_var_wait_rw_r(CondVar cv, RWMutex mutex_rw, U64 endt_us) OS_W32_Entity *entity = (OS_W32_Entity*)PtrFromInt(cv.u64[0]); OS_W32_Entity *mutex_entity = (OS_W32_Entity*)PtrFromInt(mutex_rw.u64[0]); result = SleepConditionVariableSRW(&entity->cv, &mutex_entity->rw_mutex, sleep_ms, - CONDITION_VARIABLE_LOCKMODE_SHARED); - } - return result; -} - -internal B32 -os_cond_var_wait_rw_w(CondVar cv, RWMutex mutex_rw, U64 endt_us) -{ - U32 sleep_ms = os_w32_sleep_ms_from_endt_us(endt_us); - BOOL result = 0; - if(sleep_ms > 0) - { - OS_W32_Entity *entity = (OS_W32_Entity*)PtrFromInt(cv.u64[0]); - OS_W32_Entity *mutex_entity = (OS_W32_Entity*)PtrFromInt(mutex_rw.u64[0]); - result = SleepConditionVariableSRW(&entity->cv, &mutex_entity->rw_mutex, sleep_ms, 0); + write_mode ? 0 : CONDITION_VARIABLE_LOCKMODE_SHARED); } return result; } @@ -1413,7 +1399,7 @@ os_library_close(OS_Handle lib) //~ rjf: @os_hooks Safe Calls (Implemented Per-OS) internal void -os_safe_call(OS_ThreadFunctionType *func, OS_ThreadFunctionType *fail_handler, void *ptr) +os_safe_call(ThreadEntryPointFunctionType *func, ThreadEntryPointFunctionType *fail_handler, void *ptr) { __try { diff --git a/src/os/core/win32/os_core_win32.h b/src/os/core/win32/os_core_win32.h index 8a7f65e8..777961c0 100644 --- a/src/os/core/win32/os_core_win32.h +++ b/src/os/core/win32/os_core_win32.h @@ -62,7 +62,7 @@ struct OS_W32_Entity { struct { - OS_ThreadFunctionType *func; + ThreadEntryPointFunctionType *func; void *ptr; HANDLE handle; DWORD tid; diff --git a/src/ptr_graph_cache/ptr_graph_cache.c b/src/ptr_graph_cache/ptr_graph_cache.c index 7d52ab78..37e9b554 100644 --- a/src/ptr_graph_cache/ptr_graph_cache.c +++ b/src/ptr_graph_cache/ptr_graph_cache.c @@ -25,12 +25,12 @@ ptg_init(void) ptg_shared->u2b_ring_cv = cond_var_alloc(); ptg_shared->u2b_ring_mutex = mutex_alloc(); ptg_shared->builder_thread_count = Clamp(1, os_get_system_info()->logical_processor_count-1, 4); - ptg_shared->builder_threads = push_array(arena, OS_Handle, ptg_shared->builder_thread_count); + ptg_shared->builder_threads = push_array(arena, Thread, ptg_shared->builder_thread_count); for(U64 idx = 0; idx < ptg_shared->builder_thread_count; idx += 1) { - ptg_shared->builder_threads[idx] = os_thread_launch(ptg_builder_thread__entry_point, (void *)idx, 0); + ptg_shared->builder_threads[idx] = thread_launch(ptg_builder_thread__entry_point, (void *)idx); } - ptg_shared->evictor_thread = os_thread_launch(ptg_evictor_thread__entry_point, 0, 0); + ptg_shared->evictor_thread = thread_launch(ptg_evictor_thread__entry_point, 0); } //////////////////////////////// @@ -122,7 +122,7 @@ internal B32 ptg_u2b_enqueue_req(PTG_Key *key, U64 endt_us) { B32 good = 0; - OS_MutexScope(ptg_shared->u2b_ring_mutex) for(;;) + MutexScope(ptg_shared->u2b_ring_mutex) for(;;) { U64 unconsumed_size = ptg_shared->u2b_ring_write_pos-ptg_shared->u2b_ring_read_pos; U64 available_size = ptg_shared->u2b_ring_size-unconsumed_size; @@ -148,7 +148,7 @@ ptg_u2b_enqueue_req(PTG_Key *key, U64 endt_us) internal void ptg_u2b_dequeue_req(PTG_Key *key_out) { - OS_MutexScope(ptg_shared->u2b_ring_mutex) for(;;) + MutexScope(ptg_shared->u2b_ring_mutex) for(;;) { U64 unconsumed_size = ptg_shared->u2b_ring_write_pos-ptg_shared->u2b_ring_read_pos; if(unconsumed_size >= sizeof(*key_out)) @@ -180,7 +180,7 @@ ptg_builder_thread__entry_point(void *p) //- rjf: take task B32 got_task = 0; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(PTG_GraphNode *n = slot->first; n != 0; n = n->next) { @@ -200,7 +200,7 @@ ptg_builder_thread__entry_point(void *p) //- rjf: commit results to cache - if(got_task) OS_MutexScopeW(stripe->rw_mutex) + if(got_task) MutexScopeW(stripe->rw_mutex) { for(PTG_GraphNode *n = slot->first; n != 0; n = n->next) { @@ -236,7 +236,7 @@ ptg_evictor_thread__entry_point(void *p) PTG_GraphSlot *slot = &ptg_shared->slots[slot_idx]; PTG_GraphStripe *stripe = &ptg_shared->stripes[stripe_idx]; B32 slot_has_work = 0; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(PTG_GraphNode *n = slot->first; n != 0; n = n->next) { @@ -251,7 +251,7 @@ ptg_evictor_thread__entry_point(void *p) } } } - if(slot_has_work) OS_MutexScopeW(stripe->rw_mutex) + if(slot_has_work) MutexScopeW(stripe->rw_mutex) { for(PTG_GraphNode *n = slot->first, *next = 0; n != 0; n = next) { diff --git a/src/ptr_graph_cache/ptr_graph_cache.h b/src/ptr_graph_cache/ptr_graph_cache.h index 37e18ce9..43befd6b 100644 --- a/src/ptr_graph_cache/ptr_graph_cache.h +++ b/src/ptr_graph_cache/ptr_graph_cache.h @@ -181,10 +181,10 @@ struct PTG_Shared // rjf: builder threads U64 builder_thread_count; - OS_Handle *builder_threads; + Thread *builder_threads; // rjf: evictor thread - OS_Handle evictor_thread; + Thread evictor_thread; }; //////////////////////////////// diff --git a/src/radbin/radbin.c b/src/radbin/radbin.c index fc59c69c..64bde605 100644 --- a/src/radbin/radbin.c +++ b/src/radbin/radbin.c @@ -23,7 +23,7 @@ rb_entry_point(CmdLine *cmdline) threads_count = threads_count_from_cmdline; } } - OS_Handle *threads = push_array(scratch.arena, OS_Handle, threads_count); + Thread *threads = push_array(scratch.arena, Thread, threads_count); RB_ThreadParams *threads_params = push_array(scratch.arena, RB_ThreadParams, threads_count); Barrier barrier = barrier_alloc(threads_count); for EachIndex(idx, threads_count) @@ -32,11 +32,11 @@ rb_entry_point(CmdLine *cmdline) threads_params[idx].lane_ctx.lane_idx = idx; threads_params[idx].lane_ctx.lane_count = threads_count; threads_params[idx].lane_ctx.barrier = barrier; - threads[idx] = os_thread_launch(rb_thread_entry_point, &threads_params[idx], 0); + threads[idx] = thread_launch(rb_thread_entry_point, &threads_params[idx]); } for EachIndex(idx, threads_count) { - os_thread_join(threads[idx], max_U64); + thread_join(threads[idx], max_U64); } scratch_end(scratch); } diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 588673d3..eeda6184 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -357,7 +357,7 @@ global CondVar ipc_s2m_ring_cv = {0}; internal void ipc_signaler_thread__entry_point(void *p) { - ThreadNameF("[rd] ipc signaler thread"); + ThreadNameF("rd_ipc_signaler_thread"); for(;;) { if(os_semaphore_take(ipc_sender2main_signal_semaphore, max_U64)) @@ -367,7 +367,7 @@ ipc_signaler_thread__entry_point(void *p) IPCInfo *ipc_info = (IPCInfo *)ipc_sender2main_shared_memory_base; String8 msg = str8((U8 *)(ipc_info+1), ipc_info->msg_size); msg.size = Min(msg.size, IPC_SHARED_MEMORY_BUFFER_SIZE - sizeof(IPCInfo)); - OS_MutexScope(ipc_s2m_ring_mutex) for(;;) + MutexScope(ipc_s2m_ring_mutex) for(;;) { U64 unconsumed_size = ipc_s2m_ring_write_pos - ipc_s2m_ring_read_pos; U64 available_size = (sizeof(ipc_s2m_ring_buffer) - unconsumed_size); @@ -535,7 +535,7 @@ entry_point(CmdLine *cmd_line) if(ipc_sender2main_shared_memory_base != 0) { MemoryZeroStruct(ipc_info); - os_thread_launch(ipc_signaler_thread__entry_point, 0, 0); + thread_launch(ipc_signaler_thread__entry_point, 0); } scratch_end(scratch); @@ -551,7 +551,7 @@ entry_point(CmdLine *cmd_line) Temp scratch = scratch_begin(0, 0); B32 consumed = 0; String8 msg = {0}; - OS_MutexScope(ipc_s2m_ring_mutex) + MutexScope(ipc_s2m_ring_mutex) { U64 unconsumed_size = ipc_s2m_ring_write_pos - ipc_s2m_ring_read_pos; if(unconsumed_size >= sizeof(U64)) @@ -711,7 +711,13 @@ entry_point(CmdLine *cmd_line) IPCInfo *ipc_info = (IPCInfo *)ipc_sender2main_shared_memory_base; U8 *buffer = (U8 *)(ipc_info+1); U64 buffer_max = IPC_SHARED_MEMORY_BUFFER_SIZE - sizeof(IPCInfo); - String8List parts = os_string_list_from_argcv(scratch.arena, cmd_line->argc - 1, cmd_line->argv + 1); + String8List parts = {0}; + { + for EachIndex(idx, cmd_line->argc-1) + { + str8_list_push(scratch.arena, &parts, str8_cstring(cmd_line->argv[idx+1])); + } + } StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")}; String8 msg = str8_list_join(scratch.arena, &parts, &join); ipc_info->msg_size = Min(buffer_max, msg.size); diff --git a/src/render/d3d11/render_d3d11.c b/src/render/d3d11/render_d3d11.c index ac9e8a54..444199cf 100644 --- a/src/render/d3d11/render_d3d11.c +++ b/src/render/d3d11/render_d3d11.c @@ -487,7 +487,7 @@ r_window_equip(OS_Handle handle) { ProfBeginFunction(); R_Handle result = {0}; - OS_MutexScopeW(r_d3d11_state->device_rw_mutex) + MutexScopeW(r_d3d11_state->device_rw_mutex) { //- rjf: allocate per-window-state R_D3D11_Window *window = r_d3d11_state->first_free_window; @@ -559,7 +559,7 @@ r_hook void r_window_unequip(OS_Handle handle, R_Handle equip_handle) { ProfBeginFunction(); - OS_MutexScopeW(r_d3d11_state->device_rw_mutex) + MutexScopeW(r_d3d11_state->device_rw_mutex) { R_D3D11_Window *window = r_d3d11_window_from_handle(equip_handle); window->stage_color_srv->lpVtbl->Release(window->stage_color_srv); @@ -588,7 +588,7 @@ r_tex2d_alloc(R_ResourceKind kind, Vec2S32 size, R_Tex2DFormat format, void *dat //- rjf: allocate R_D3D11_Tex2D *texture = 0; - OS_MutexScopeW(r_d3d11_state->device_rw_mutex) + MutexScopeW(r_d3d11_state->device_rw_mutex) { texture = r_d3d11_state->first_free_tex2d; if(texture == 0) @@ -675,7 +675,7 @@ r_hook void r_tex2d_release(R_Handle handle) { ProfBeginFunction(); - OS_MutexScopeW(r_d3d11_state->device_rw_mutex) + MutexScopeW(r_d3d11_state->device_rw_mutex) { R_D3D11_Tex2D *texture = r_d3d11_tex2d_from_handle(handle); if(texture != &r_d3d11_tex2d_nil) @@ -711,7 +711,7 @@ r_hook void r_fill_tex2d_region(R_Handle handle, Rng2S32 subrect, void *data) { ProfBeginFunction(); - OS_MutexScopeW(r_d3d11_state->device_rw_mutex) + MutexScopeW(r_d3d11_state->device_rw_mutex) { R_D3D11_Tex2D *texture = r_d3d11_tex2d_from_handle(handle); if(texture != &r_d3d11_tex2d_nil) @@ -739,7 +739,7 @@ r_buffer_alloc(R_ResourceKind kind, U64 size, void *data) //- rjf: allocate R_D3D11_Buffer *buffer = 0; - OS_MutexScopeW(r_d3d11_state->device_rw_mutex) + MutexScopeW(r_d3d11_state->device_rw_mutex) { buffer = r_d3d11_state->first_free_buffer; if(buffer == 0) @@ -798,7 +798,7 @@ r_hook void r_buffer_release(R_Handle handle) { ProfBeginFunction(); - OS_MutexScopeW(r_d3d11_state->device_rw_mutex) + MutexScopeW(r_d3d11_state->device_rw_mutex) { R_D3D11_Buffer *buffer = r_d3d11_buffer_from_handle(handle); SLLStackPush(r_d3d11_state->first_to_free_buffer, buffer); @@ -811,7 +811,7 @@ r_buffer_release(R_Handle handle) r_hook void r_begin_frame(void) { - OS_MutexScopeW(r_d3d11_state->device_rw_mutex) + MutexScopeW(r_d3d11_state->device_rw_mutex) { // NOTE(rjf): no-op } @@ -820,7 +820,7 @@ r_begin_frame(void) r_hook void r_end_frame(void) { - OS_MutexScopeW(r_d3d11_state->device_rw_mutex) + MutexScopeW(r_d3d11_state->device_rw_mutex) { for(R_D3D11_FlushBuffer *buffer = r_d3d11_state->first_buffer_to_flush; buffer != 0; buffer = buffer->next) { @@ -858,7 +858,7 @@ r_hook void r_window_begin_frame(OS_Handle window, R_Handle window_equip) { ProfBeginFunction(); - OS_MutexScopeW(r_d3d11_state->device_rw_mutex) + MutexScopeW(r_d3d11_state->device_rw_mutex) { R_D3D11_Window *wnd = r_d3d11_window_from_handle(window_equip); ID3D11DeviceContext1 *d_ctx = r_d3d11_state->device_ctx; @@ -990,7 +990,7 @@ r_hook void r_window_end_frame(OS_Handle window, R_Handle window_equip) { ProfBeginFunction(); - OS_MutexScopeW(r_d3d11_state->device_rw_mutex) + MutexScopeW(r_d3d11_state->device_rw_mutex) { R_D3D11_Window *wnd = r_d3d11_window_from_handle(window_equip); ID3D11DeviceContext1 *d_ctx = r_d3d11_state->device_ctx; @@ -1060,7 +1060,7 @@ r_hook void r_window_submit(OS_Handle window, R_Handle window_equip, R_PassList *passes) { ProfBeginFunction(); - OS_MutexScopeW(r_d3d11_state->device_rw_mutex) + MutexScopeW(r_d3d11_state->device_rw_mutex) { //////////////////////////// //- rjf: unpack arguments diff --git a/src/text_cache/text_cache.c b/src/text_cache/text_cache.c index 15c2f21e..0a17218a 100644 --- a/src/text_cache/text_cache.c +++ b/src/text_cache/text_cache.c @@ -1614,7 +1614,7 @@ txt_init(void) txt_shared->u2p_ring_base = push_array_no_zero(arena, U8, txt_shared->u2p_ring_size); txt_shared->u2p_ring_cv = cond_var_alloc(); txt_shared->u2p_ring_mutex = mutex_alloc(); - txt_shared->evictor_thread = os_thread_launch(txt_evictor_thread__entry_point, 0, 0); + txt_shared->evictor_thread = thread_launch(txt_evictor_thread__entry_point, 0); } //////////////////////////////// @@ -1662,7 +1662,7 @@ txt_scope_close(TXT_Scope *scope) U64 stripe_idx = slot_idx%txt_shared->stripes_count; TXT_Slot *slot = &txt_shared->slots[slot_idx]; TXT_Stripe *stripe = &txt_shared->stripes[stripe_idx]; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(TXT_Node *n = slot->first; n != 0; n = n->next) { @@ -1713,7 +1713,7 @@ txt_text_info_from_hash_lang(TXT_Scope *scope, U128 hash, TXT_LangKind lang) TXT_Slot *slot = &txt_shared->slots[slot_idx]; TXT_Stripe *stripe = &txt_shared->stripes[stripe_idx]; B32 found = 0; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(TXT_Node *n = slot->first; n != 0; n = n->next) { @@ -1731,7 +1731,7 @@ txt_text_info_from_hash_lang(TXT_Scope *scope, U128 hash, TXT_LangKind lang) B32 node_is_new = 0; if(!found) { - OS_MutexScopeW(stripe->rw_mutex) + MutexScopeW(stripe->rw_mutex) { TXT_Node *node = 0; for(TXT_Node *n = slot->first; n != 0; n = n->next) @@ -2157,7 +2157,7 @@ internal B32 txt_u2p_enqueue_req(U128 hash, TXT_LangKind lang, U64 endt_us) { B32 good = 0; - OS_MutexScope(txt_shared->u2p_ring_mutex) for(;;) + MutexScope(txt_shared->u2p_ring_mutex) for(;;) { U64 unconsumed_size = txt_shared->u2p_ring_write_pos - txt_shared->u2p_ring_read_pos; U64 available_size = txt_shared->u2p_ring_size - unconsumed_size; @@ -2184,7 +2184,7 @@ txt_u2p_enqueue_req(U128 hash, TXT_LangKind lang, U64 endt_us) internal void txt_u2p_dequeue_req(U128 *hash_out, TXT_LangKind *lang_out) { - OS_MutexScope(txt_shared->u2p_ring_mutex) for(;;) + MutexScope(txt_shared->u2p_ring_mutex) for(;;) { U64 unconsumed_size = txt_shared->u2p_ring_write_pos - txt_shared->u2p_ring_read_pos; if(unconsumed_size >= sizeof(*hash_out) + sizeof(*lang_out)) @@ -2216,7 +2216,7 @@ ASYNC_WORK_DEF(txt_parse_work) //- rjf: take task B32 got_task = 0; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(TXT_Node *n = slot->first; n != 0; n = n->next) { @@ -2245,7 +2245,7 @@ ASYNC_WORK_DEF(txt_parse_work) //- rjf: grab pointers to working counters U64 *bytes_processed_ptr = 0; U64 *bytes_to_process_ptr = 0; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(TXT_Node *n = slot->first; n != 0; n = n->next) { @@ -2482,7 +2482,7 @@ ASYNC_WORK_DEF(txt_parse_work) } //- rjf: commit results to cache - if(got_task) OS_MutexScopeW(stripe->rw_mutex) + if(got_task) MutexScopeW(stripe->rw_mutex) { for(TXT_Node *n = slot->first; n != 0; n = n->next) { @@ -2511,7 +2511,7 @@ ASYNC_WORK_DEF(txt_parse_work) internal void txt_evictor_thread__entry_point(void *p) { - ThreadNameF("[txt] evictor thread"); + ThreadNameF("txt_evictor_thread"); for(;;) { U64 check_time_us = os_now_microseconds(); @@ -2524,7 +2524,7 @@ txt_evictor_thread__entry_point(void *p) TXT_Slot *slot = &txt_shared->slots[slot_idx]; TXT_Stripe *stripe = &txt_shared->stripes[stripe_idx]; B32 slot_has_work = 0; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(TXT_Node *n = slot->first; n != 0; n = n->next) { @@ -2539,7 +2539,7 @@ txt_evictor_thread__entry_point(void *p) } } } - if(slot_has_work) OS_MutexScopeW(stripe->rw_mutex) + if(slot_has_work) MutexScopeW(stripe->rw_mutex) { for(TXT_Node *n = slot->first, *next = 0; n != 0; n = next) { diff --git a/src/text_cache/text_cache.h b/src/text_cache/text_cache.h index db86ee70..e08494ff 100644 --- a/src/text_cache/text_cache.h +++ b/src/text_cache/text_cache.h @@ -252,7 +252,7 @@ struct TXT_Shared Mutex u2p_ring_mutex; // rjf: evictor thread - OS_Handle evictor_thread; + Thread evictor_thread; }; //////////////////////////////// diff --git a/src/texture_cache/texture_cache.c b/src/texture_cache/texture_cache.c index 71976f5b..a837f599 100644 --- a/src/texture_cache/texture_cache.c +++ b/src/texture_cache/texture_cache.c @@ -41,7 +41,7 @@ tex_init(void) tex_shared->u2x_ring_base = push_array_no_zero(arena, U8, tex_shared->u2x_ring_size); tex_shared->u2x_ring_cv = cond_var_alloc(); tex_shared->u2x_ring_mutex = mutex_alloc(); - tex_shared->evictor_thread = os_thread_launch(tex_evictor_thread__entry_point, 0, 0); + tex_shared->evictor_thread = thread_launch(tex_evictor_thread__entry_point, 0); } //////////////////////////////// @@ -89,7 +89,7 @@ tex_scope_close(TEX_Scope *scope) U64 stripe_idx = slot_idx%tex_shared->stripes_count; TEX_Slot *slot = &tex_shared->slots[slot_idx]; TEX_Stripe *stripe = &tex_shared->stripes[stripe_idx]; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(TEX_Node *n = slot->first; n != 0; n = n->next) { @@ -140,7 +140,7 @@ tex_texture_from_hash_topology(TEX_Scope *scope, U128 hash, TEX_Topology topolog TEX_Stripe *stripe = &tex_shared->stripes[stripe_idx]; B32 found = 0; B32 stale = 0; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(TEX_Node *n = slot->first; n != 0; n = n->next) { @@ -156,7 +156,7 @@ tex_texture_from_hash_topology(TEX_Scope *scope, U128 hash, TEX_Topology topolog B32 node_is_new = 0; if(!found) { - OS_MutexScopeW(stripe->rw_mutex) + MutexScopeW(stripe->rw_mutex) { TEX_Node *node = 0; for(TEX_Node *n = slot->first; n != 0; n = n->next) @@ -222,7 +222,7 @@ internal B32 tex_u2x_enqueue_req(U128 hash, TEX_Topology top, U64 endt_us) { B32 good = 0; - OS_MutexScope(tex_shared->u2x_ring_mutex) for(;;) + MutexScope(tex_shared->u2x_ring_mutex) for(;;) { U64 unconsumed_size = tex_shared->u2x_ring_write_pos-tex_shared->u2x_ring_read_pos; U64 available_size = tex_shared->u2x_ring_size-unconsumed_size; @@ -249,7 +249,7 @@ tex_u2x_enqueue_req(U128 hash, TEX_Topology top, U64 endt_us) internal void tex_u2x_dequeue_req(U128 *hash_out, TEX_Topology *top_out) { - OS_MutexScope(tex_shared->u2x_ring_mutex) for(;;) + MutexScope(tex_shared->u2x_ring_mutex) for(;;) { U64 unconsumed_size = tex_shared->u2x_ring_write_pos-tex_shared->u2x_ring_read_pos; if(unconsumed_size >= sizeof(*hash_out)+sizeof(*top_out)) @@ -281,7 +281,7 @@ ASYNC_WORK_DEF(tex_xfer_work) //- rjf: take task B32 got_task = 0; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(TEX_Node *n = slot->first; n != 0; n = n->next) { @@ -308,7 +308,7 @@ ASYNC_WORK_DEF(tex_xfer_work) } //- rjf: commit results to cache - if(got_task) OS_MutexScopeW(stripe->rw_mutex) + if(got_task) MutexScopeW(stripe->rw_mutex) { for(TEX_Node *n = slot->first; n != 0; n = n->next) { @@ -333,7 +333,7 @@ ASYNC_WORK_DEF(tex_xfer_work) internal void tex_evictor_thread__entry_point(void *p) { - ThreadNameF("[tex] evictor thread"); + ThreadNameF("tex_evictor_thread"); for(;;) { U64 check_time_us = os_now_microseconds(); @@ -346,7 +346,7 @@ tex_evictor_thread__entry_point(void *p) TEX_Slot *slot = &tex_shared->slots[slot_idx]; TEX_Stripe *stripe = &tex_shared->stripes[stripe_idx]; B32 slot_has_work = 0; - OS_MutexScopeR(stripe->rw_mutex) + MutexScopeR(stripe->rw_mutex) { for(TEX_Node *n = slot->first; n != 0; n = n->next) { @@ -361,7 +361,7 @@ tex_evictor_thread__entry_point(void *p) } } } - if(slot_has_work) OS_MutexScopeW(stripe->rw_mutex) + if(slot_has_work) MutexScopeW(stripe->rw_mutex) { for(TEX_Node *n = slot->first, *next = 0; n != 0; n = next) { diff --git a/src/texture_cache/texture_cache.h b/src/texture_cache/texture_cache.h index 7d547a59..818a3406 100644 --- a/src/texture_cache/texture_cache.h +++ b/src/texture_cache/texture_cache.h @@ -100,7 +100,7 @@ struct TEX_Shared Mutex u2x_ring_mutex; // rjf: evictor thread - OS_Handle evictor_thread; + Thread evictor_thread; }; ////////////////////////////////