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

This commit is contained in:
Ryan Fleury
2025-09-17 14:47:55 -07:00
parent 99c989a3c3
commit 0d15b8670b
40 changed files with 450 additions and 607 deletions
+6 -6
View File
@@ -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, os_get_system_info()->logical_processor_count-1);
} }
async_shared->work_threads_count = Max(4, async_shared->work_threads_count); 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) 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. // thread, and skip ring buffer if so.
B32 queued_in_ring_buffer = 0; B32 queued_in_ring_buffer = 0;
B32 need_to_execute_on_this_thread = 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)); 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) if(num_available_work_threads == 0 && async_work_thread_depth > 0)
@@ -167,12 +167,12 @@ async_pop_work(void)
ASYNC_Work work = {0}; ASYNC_Work work = {0};
B32 done = 0; B32 done = 0;
ASYNC_Priority taken_priority = ASYNC_Priority_Low; 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)) for(ASYNC_Priority priority = ASYNC_Priority_High;; priority = (ASYNC_Priority)(priority - 1))
{ {
ASYNC_Ring *ring = &async_shared->rings[priority]; 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; U64 unconsumed_size = ring->ring_write_pos - ring->ring_read_pos;
if(unconsumed_size >= sizeof(work)) if(unconsumed_size >= sizeof(work))
@@ -274,7 +274,7 @@ internal void
async_work_thread__entry_point(void *p) async_work_thread__entry_point(void *p)
{ {
U64 thread_idx = (U64)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; async_work_thread_idx = thread_idx;
for(;;) for(;;)
{ {
+1 -1
View File
@@ -104,7 +104,7 @@ struct ASYNC_Shared
CondVar ring_cv; CondVar ring_cv;
// rjf: work threads // rjf: work threads
OS_Handle *work_threads; Thread *work_threads;
U64 work_threads_count; U64 work_threads_count;
U64 work_threads_live_count; U64 work_threads_live_count;
}; };
+57 -12
View File
@@ -2,18 +2,23 @@
// Licensed under the MIT license (https://opensource.org/license/mit/) // Licensed under the MIT license (https://opensource.org/license/mit/)
global U64 global_update_tick_idx = 0; global U64 global_update_tick_idx = 0;
global CondVar async_tick_cond_var = {0}; global CondVar async_tick_start_cond_var = {0};
global Mutex async_tick_mutex = {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 internal void
main_thread_base_entry_point(int arguments_count, char **arguments) main_thread_base_entry_point(int arguments_count, char **arguments)
{ {
ThreadNameF("main_thread");
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
ThreadNameF("[main thread]");
//- rjf: set up async thread group info //- rjf: set up async thread group info
async_tick_cond_var = cond_var_alloc(); async_tick_start_cond_var = cond_var_alloc();
async_tick_mutex = mutex_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 //- rjf: set up telemetry
#if PROFILE_TELEMETRY #if PROFILE_TELEMETRY
@@ -29,7 +34,13 @@ main_thread_base_entry_point(int arguments_count, char **arguments)
#endif #endif
//- rjf: parse command line //- 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); CmdLine cmdline = cmd_line_from_string_list(scratch.arena, command_line_argument_strings);
//- rjf: begin captures //- rjf: begin captures
@@ -37,12 +48,9 @@ main_thread_base_entry_point(int arguments_count, char **arguments)
if(capture) if(capture)
{ {
ProfBeginCapture(arguments[0]); ProfBeginCapture(arguments[0]);
ProfMsg(BUILD_TITLE);
} }
#if PROFILE_TELEMETRY
tmMessage(0, TMMF_ICON_NOTE, BUILD_TITLE);
#endif
//- rjf: initialize all included layers //- rjf: initialize all included layers
#if defined(ASYNC_H) && !defined(ASYNC_INIT_MANUAL) #if defined(ASYNC_H) && !defined(ASYNC_INIT_MANUAL)
async_init(&cmdline); async_init(&cmdline);
@@ -96,9 +104,42 @@ main_thread_base_entry_point(int arguments_count, char **arguments)
rd_init(&cmdline); rd_init(&cmdline);
#endif #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 //- rjf: call into entry point
entry_point(&cmdline); 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 //- rjf: end captures
if(capture) if(capture)
{ {
@@ -143,11 +184,15 @@ update(void)
internal void internal void
async_thread_entry_point(void *params) 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) #if defined(FILE_STREAM_H)
fs_async_tick(); fs_async_tick();
#endif #endif
cond_var_broadcast(async_tick_stop_cond_var);
} }
} }
+1 -1
View File
@@ -12,7 +12,7 @@
#include "base_arena.c" #include "base_arena.c"
#include "base_math.c" #include "base_math.c"
#include "base_strings.c" #include "base_strings.c"
#include "base_sync.c" #include "base_threads.c"
#include "base_thread_context.c" #include "base_thread_context.c"
#include "base_command_line.c" #include "base_command_line.c"
#include "base_markup.c" #include "base_markup.c"
+1 -1
View File
@@ -14,7 +14,7 @@
#include "base_arena.h" #include "base_arena.h"
#include "base_math.h" #include "base_math.h"
#include "base_strings.h" #include "base_strings.h"
#include "base_sync.h" #include "base_threads.h"
#include "base_thread_context.h" #include "base_thread_context.h"
#include "base_command_line.h" #include "base_command_line.h"
#include "base_markup.h" #include "base_markup.h"
@@ -1,6 +1,29 @@
// Copyright (c) Epic Games Tools // Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/) // 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 //~ 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 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_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_take(RWMutex mutex, B32 write_mode) {os_rw_mutex_take(mutex, write_mode);}
internal void rw_mutex_drop_r(RWMutex mutex) {os_rw_mutex_drop_r(mutex);} internal void rw_mutex_drop(RWMutex mutex, B32 write_mode) {os_rw_mutex_drop(mutex, write_mode);}
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);}
//- rjf: condition variables //- rjf: condition variables
internal CondVar cond_var_alloc(void) {return os_cond_var_alloc();} internal CondVar cond_var_alloc(void) {return os_cond_var_alloc();}
internal void cond_var_release(CondVar cv) {os_cond_var_release(cv);} 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(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(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 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_signal(CondVar cv) {os_cond_var_signal(cv);} internal void cond_var_broadcast(CondVar cv) {os_cond_var_broadcast(cv);}
internal void cond_var_broadcast(CondVar cv) {os_cond_var_broadcast(cv);}
//- rjf: cross-process semaphores //- rjf: cross-process semaphores
@@ -1,8 +1,18 @@
// Copyright (c) Epic Games Tools // Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/) // Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_SYNC_H #ifndef BASE_THREADS_H
#define BASE_SYNC_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 //~ rjf: Synchronization Primitive Types
@@ -37,6 +47,13 @@ struct Barrier
U64 u64[1]; 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 //~ rjf: Synchronization Primitive Functions
@@ -49,18 +66,21 @@ internal void mutex_drop(Mutex mutex);
//- rjf: reader/writer mutexes //- rjf: reader/writer mutexes
internal RWMutex rw_mutex_alloc(void); internal RWMutex rw_mutex_alloc(void);
internal void rw_mutex_release(RWMutex mutex); internal void rw_mutex_release(RWMutex mutex);
internal void rw_mutex_take_r(RWMutex mutex); internal void rw_mutex_take(RWMutex mutex, B32 write_mode);
internal void rw_mutex_drop_r(RWMutex mutex); internal void rw_mutex_drop(RWMutex mutex, B32 write_mode);
internal void rw_mutex_take_w(RWMutex mutex); #define rw_mutex_take_r(m) rw_mutex_take((m), (0))
internal void rw_mutex_drop_w(RWMutex mutex); #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 //- rjf: condition variables
internal CondVar cond_var_alloc(void); internal CondVar cond_var_alloc(void);
internal void cond_var_release(CondVar cv); internal void cond_var_release(CondVar cv);
// returns false on timeout, true on signal, (max_wait_ms = max_U64) -> no timeout // 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(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(CondVar cv, RWMutex mutex_rw, B32 write_mode, U64 endt_us);
internal B32 cond_var_wait_rw_w(CondVar cv, RWMutex mutex_rw, 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_signal(CondVar cv);
internal void cond_var_broadcast(CondVar cv); internal void cond_var_broadcast(CondVar cv);
@@ -79,8 +99,9 @@ internal void barrier_wait(Barrier barrier);
//- rjf: scope macros //- rjf: scope macros
#define MutexScope(mutex) DeferLoop(mutex_take(mutex), mutex_drop(mutex)) #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 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 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))) #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
+38 -38
View File
@@ -1603,7 +1603,7 @@ ctrl_init(void)
ctrl_state->u2csb_ring_mutex = mutex_alloc(); ctrl_state->u2csb_ring_mutex = mutex_alloc();
ctrl_state->u2csb_ring_cv = cond_var_alloc(); ctrl_state->u2csb_ring_cv = cond_var_alloc();
ctrl_state->ctrl_thread_log = log_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}; HS_Root root = {0};
{ {
B32 node_found = 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) 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) 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_exists = 0;
B32 id_stale = 0; B32 id_stale = 0;
B32 id_working = 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) 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)) if(!id_exists || (id_exists && id_stale && !id_working))
{ {
B32 node_needs_stream = 0; 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) 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); async_push_work(ctrl_mem_stream_work);
requested = 1; 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) 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; U64 stripe_idx = slot_idx%cache->stripes_count;
CTRL_ProcessMemoryCacheSlot *slot = &cache->slots[slot_idx]; CTRL_ProcessMemoryCacheSlot *slot = &cache->slots[slot_idx];
CTRL_ProcessMemoryCacheStripe *stripe = &cache->stripes[stripe_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) 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_ThreadRegCacheSlot *slot = &cache->slots[slot_idx];
CTRL_ThreadRegCacheStripe *stripe = &cache->stripes[stripe_idx]; CTRL_ThreadRegCacheStripe *stripe = &cache->stripes[stripe_idx];
void *result = push_array(arena, U8, reg_block_size); void *result = push_array(arena, U8, reg_block_size);
OS_MutexScopeW(stripe->rw_mutex) MutexScopeW(stripe->rw_mutex)
{ {
// rjf: find existing node // rjf: find existing node
CTRL_ThreadRegCacheNode *node = 0; 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; 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_ModuleImageInfoCacheSlot *slot = &ctrl_state->module_image_info_cache.slots[slot_idx];
CTRL_ModuleImageInfoCacheStripe *stripe = &ctrl_state->module_image_info_cache.stripes[stripe_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)) 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; 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_ModuleImageInfoCacheSlot *slot = &ctrl_state->module_image_info_cache.slots[slot_idx];
CTRL_ModuleImageInfoCacheStripe *stripe = &ctrl_state->module_image_info_cache.stripes[stripe_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)) 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; 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_ModuleImageInfoCacheSlot *slot = &ctrl_state->module_image_info_cache.slots[slot_idx];
CTRL_ModuleImageInfoCacheStripe *stripe = &ctrl_state->module_image_info_cache.stripes[stripe_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)) 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; 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_ModuleImageInfoCacheSlot *slot = &ctrl_state->module_image_info_cache.slots[slot_idx];
CTRL_ModuleImageInfoCacheStripe *stripe = &ctrl_state->module_image_info_cache.stripes[stripe_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)) 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; 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_ModuleImageInfoCacheSlot *slot = &ctrl_state->module_image_info_cache.slots[slot_idx];
CTRL_ModuleImageInfoCacheStripe *stripe = &ctrl_state->module_image_info_cache.stripes[stripe_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)) 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_exists = 0;
B32 node_stale = 1; B32 node_stale = 1;
B32 node_working = 0; B32 node_working = 0;
OS_MutexScopeR(stripe->rw_mutex) for(;;) MutexScopeR(stripe->rw_mutex) for(;;)
{ {
CTRL_CallStackCacheNode *node = 0; CTRL_CallStackCacheNode *node = 0;
for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) 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 //- rjf: [write] node does not exist => create; request if new or stale
B32 need_request = (!node_exists || node_stale); B32 need_request = (!node_exists || node_stale);
CTRL_CallStackCacheNode *node_to_request = 0; 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; CTRL_CallStackCacheNode *node = 0;
for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) 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); 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; 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 reg_gen = ctrl_reg_gen();
U64 mem_gen = ctrl_mem_gen(); U64 mem_gen = ctrl_mem_gen();
CTRL_CallStackTreeCache *cache = &ctrl_state->call_stack_tree_cache; 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 // rjf: unpack cache/time state
B32 is_stale = (cache->reg_gen != reg_gen || cache->mem_gen != mem_gen); 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); Temp scratch = scratch_begin(0, 0);
String8 msgs_srlzed_baked = ctrl_serialized_string_from_msg_list(scratch.arena, msgs); String8 msgs_srlzed_baked = ctrl_serialized_string_from_msg_list(scratch.arena, msgs);
B32 good = 0; 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 unconsumed_size = (ctrl_state->u2c_ring_write_pos-ctrl_state->u2c_ring_read_pos);
U64 available_size = ctrl_state->u2c_ring_size-unconsumed_size; 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); Temp scratch = scratch_begin(&arena, 1);
String8 msgs_srlzed_baked = {0}; 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); U64 unconsumed_size = (ctrl_state->u2c_ring_write_pos-ctrl_state->u2c_ring_read_pos);
if(unconsumed_size >= sizeof(U64)) 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") 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); 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); 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)); 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 unconsumed_size = (ctrl_state->c2u_ring_write_pos-ctrl_state->c2u_ring_read_pos);
U64 available_size = ctrl_state->c2u_ring_size-unconsumed_size; U64 available_size = ctrl_state->c2u_ring_size-unconsumed_size;
@@ -3736,7 +3736,7 @@ ctrl_c2u_pop_events(Arena *arena)
ProfBeginFunction(); ProfBeginFunction();
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
CTRL_EventList events = {0}; 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); U64 unconsumed_size = (ctrl_state->c2u_ring_write_pos-ctrl_state->c2u_ring_read_pos);
if(unconsumed_size >= sizeof(U64)) if(unconsumed_size >= sizeof(U64))
@@ -3766,7 +3766,7 @@ ctrl_c2u_pop_events(Arena *arena)
internal void internal void
ctrl_thread__entry_point(void *p) ctrl_thread__entry_point(void *p)
{ {
ThreadNameF("[ctrl] thread"); ThreadNameF("ctrl_thread");
ProfBeginFunction(); ProfBeginFunction();
DMN_CtrlCtx *ctrl_ctx = dmn_ctrl_begin(); DMN_CtrlCtx *ctrl_ctx = dmn_ctrl_begin();
log_select(ctrl_state->ctrl_thread_log); 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); 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_Key old_dbgi_key = {debug_info_path->string, debug_info_path->timestamp};
di_close(&old_dbgi_key); 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)); 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; 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_ModuleImageInfoCacheSlot *slot = &ctrl_state->module_image_info_cache.slots[slot_idx];
CTRL_ModuleImageInfoCacheStripe *stripe = &ctrl_state->module_image_info_cache.stripes[stripe_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; CTRL_ModuleImageInfoCacheNode *node = 0;
for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next) 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; 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_ModuleImageInfoCacheSlot *slot = &ctrl_state->module_image_info_cache.slots[slot_idx];
CTRL_ModuleImageInfoCacheStripe *stripe = &ctrl_state->module_image_info_cache.stripes[stripe_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; CTRL_ModuleImageInfoCacheNode *node = 0;
for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next) 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; U64 stripe_idx = slot_idx%cache->stripes_count;
CTRL_ProcessMemoryCacheSlot *slot = &cache->slots[slot_idx]; CTRL_ProcessMemoryCacheSlot *slot = &cache->slots[slot_idx];
CTRL_ProcessMemoryCacheStripe *stripe = &cache->stripes[stripe_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) 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 //- 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; 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) 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) ctrl_u2ms_enqueue_req(HS_Key key, CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us)
{ {
B32 good = 0; 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 unconsumed_size = ctrl_state->u2ms_ring_write_pos-ctrl_state->u2ms_ring_read_pos;
U64 available_size = ctrl_state->u2ms_ring_size-unconsumed_size; 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 internal void
ctrl_u2ms_dequeue_req(HS_Key *out_key, CTRL_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated) 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; 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)) 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 //- 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) 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) ctrl_u2csb_enqueue_req(CTRL_Handle thread, U64 endt_us)
{ {
B32 good = 0; 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 unconsumed_size = ctrl_state->u2csb_ring_write_pos - ctrl_state->u2csb_ring_read_pos;
U64 available_size = ctrl_state->u2csb_ring_size - unconsumed_size; 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 internal void
ctrl_u2csb_dequeue_req(CTRL_Handle *out_thread) 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; U64 unconsumed_size = ctrl_state->u2csb_ring_write_pos - ctrl_state->u2csb_ring_read_pos;
if(unconsumed_size >= sizeof(*out_thread)) 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 //- rjf: produce mini entity context for just this process
CTRL_EntityCtx *entity_ctx = push_array(scratch.arena, CTRL_EntityCtx, 1); 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 *src_ctx = &ctrl_state->ctrl_thread_entity_store->ctx;
CTRL_EntityCtx *dst_ctx = entity_ctx; CTRL_EntityCtx *dst_ctx = entity_ctx;
@@ -7263,7 +7263,7 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work)
{ {
B32 found = 0; B32 found = 0;
B32 committed = 0; B32 committed = 0;
OS_MutexScopeW(stripe->rw_mutex) for(;;) MutexScopeW(stripe->rw_mutex) for(;;)
{ {
// rjf: try to find node & commit // rjf: try to find node & commit
for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) 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 //- 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)) 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 = 0;
CTRL_Handle *threads_processes = 0; CTRL_Handle *threads_processes = 0;
Arch *threads_arches = 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_EntityCtx *ctx = &ctrl_state->ctrl_thread_entity_store->ctx;
CTRL_EntityArray thread_entities = ctrl_entity_array_from_kind(ctx, CTRL_EntityKind_Thread); 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; CTRL_CallStackTreeCache *cache = &ctrl_state->call_stack_tree_cache;
if(tree.root != &ctrl_call_stack_tree_node_nil) 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) if(cache->scope_touch_count == 0)
{ {
+1 -1
View File
@@ -870,7 +870,7 @@ struct CTRL_State
// rjf: ctrl thread state // rjf: ctrl thread state
U64 ctrl_thread_run_state; U64 ctrl_thread_run_state;
String8 ctrl_thread_log_path; String8 ctrl_thread_log_path;
OS_Handle ctrl_thread; Thread ctrl_thread;
Log *ctrl_thread_log; Log *ctrl_thread_log;
RWMutex ctrl_thread_entity_ctx_rw_mutex; RWMutex ctrl_thread_entity_ctx_rw_mutex;
CTRL_EntityCtxRWStore *ctrl_thread_entity_store; CTRL_EntityCtxRWStore *ctrl_thread_entity_store;
+10 -10
View File
@@ -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_base = push_array_no_zero(arena, U8, dasm_shared->u2p_ring_size);
dasm_shared->u2p_ring_cv = cond_var_alloc(); dasm_shared->u2p_ring_cv = cond_var_alloc();
dasm_shared->u2p_ring_mutex = mutex_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; U64 stripe_idx = slot_idx%dasm_shared->stripes_count;
DASM_Slot *slot = &dasm_shared->slots[slot_idx]; DASM_Slot *slot = &dasm_shared->slots[slot_idx];
DASM_Stripe *stripe = &dasm_shared->stripes[stripe_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) 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 //- rjf: try to get existing results
B32 found = 0; B32 found = 0;
OS_MutexScopeR(stripe->rw_mutex) MutexScopeR(stripe->rw_mutex)
{ {
for(DASM_Node *n = slot->first; n != 0; n = n->next) 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; B32 node_is_new = 0;
U64 *node_working_count = 0; U64 *node_working_count = 0;
HS_Root root = {0}; HS_Root root = {0};
OS_MutexScopeW(stripe->rw_mutex) MutexScopeW(stripe->rw_mutex)
{ {
DASM_Node *node = 0; DASM_Node *node = 0;
for(DASM_Node *n = slot->first; n != 0; n = n->next) 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) dasm_u2p_enqueue_req(HS_Root root, U128 hash, DASM_Params *params, U64 endt_us)
{ {
B32 good = 0; 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 unconsumed_size = dasm_shared->u2p_ring_write_pos - dasm_shared->u2p_ring_read_pos;
U64 available_size = dasm_shared->u2p_ring_size - unconsumed_size; 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 internal void
dasm_u2p_dequeue_req(Arena *arena, HS_Root *root_out, U128 *hash_out, DASM_Params *params_out) 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; 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)) 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 //- 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) for(DASM_Node *n = slot->first; n != 0; n = n->next)
{ {
@@ -757,7 +757,7 @@ ASYNC_WORK_DEF(dasm_parse_work)
internal void internal void
dasm_evictor_detector_thread__entry_point(void *p) dasm_evictor_detector_thread__entry_point(void *p)
{ {
ThreadNameF("[dasm] evictor/detector thread"); ThreadNameF("dasm_evictor_detector_thread");
for(;;) for(;;)
{ {
U64 change_gen = fs_change_gen(); 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_Slot *slot = &dasm_shared->slots[slot_idx];
DASM_Stripe *stripe = &dasm_shared->stripes[stripe_idx]; DASM_Stripe *stripe = &dasm_shared->stripes[stripe_idx];
B32 slot_has_work = 0; 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) 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) for(DASM_Node *n = slot->first, *next = 0; n != 0; n = next)
{ {
+1 -1
View File
@@ -263,7 +263,7 @@ struct DASM_Shared
Mutex u2p_ring_mutex; Mutex u2p_ring_mutex;
// rjf: evictor/detector thread // rjf: evictor/detector thread
OS_Handle evictor_detector_thread; Thread evictor_detector_thread;
}; };
//////////////////////////////// ////////////////////////////////
+25 -25
View File
@@ -238,9 +238,9 @@ di_init(void)
di_shared->search_threads[idx].ring_cv = cond_var_alloc(); 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_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].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_Slot *slot = &di_shared->slots[slot_idx];
DI_Stripe *stripe = &di_shared->stripes[stripe_idx]; DI_Stripe *stripe = &di_shared->stripes[stripe_idx];
log_infof("open_debug_info: {\"%S\", 0x%I64x}\n", key->path, key->min_timestamp); 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 //- rjf: find existing node
DI_Node *node = di_node_from_key_slot__stripe_mutex_r_guarded(slot, key); 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_Slot *slot = &di_shared->slots[slot_idx];
DI_Stripe *stripe = &di_shared->stripes[stripe_idx]; DI_Stripe *stripe = &di_shared->stripes[stripe_idx];
log_infof("close_debug_info: {\"%S\", 0x%I64x}\n", key->path, key->min_timestamp); 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 //- rjf: find existing node
DI_Node *node = di_node_from_key_slot__stripe_mutex_r_guarded(slot, key); 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; U64 stripe_idx = slot_idx%di_shared->stripes_count;
DI_Slot *slot = &di_shared->slots[slot_idx]; DI_Slot *slot = &di_shared->slots[slot_idx];
DI_Stripe *stripe = &di_shared->stripes[stripe_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 //- rjf: find existing node
DI_Node *node = di_node_from_key_slot__stripe_mutex_r_guarded(slot, key); 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; U64 stripe_idx = slot_idx%di_shared->search_stripes_count;
DI_SearchSlot * slot = &di_shared->search_slots[slot_idx]; DI_SearchSlot * slot = &di_shared->search_slots[slot_idx];
DI_SearchStripe * stripe = &di_shared->search_stripes[stripe_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 // rjf: map key -> node
DI_SearchNode *node = 0; DI_SearchNode *node = 0;
@@ -753,7 +753,7 @@ internal B32
di_u2p_enqueue_key(DI_Key *key, U64 endt_us) di_u2p_enqueue_key(DI_Key *key, U64 endt_us)
{ {
B32 sent = 0; 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 unconsumed_size = di_shared->u2p_ring_write_pos - di_shared->u2p_ring_read_pos;
U64 available_size = di_shared->u2p_ring_size - unconsumed_size; 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 internal void
di_u2p_dequeue_key(Arena *arena, DI_Key *out_key) 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; 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)) 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 internal void
di_p2u_push_event(DI_Event *event) 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 unconsumed_size = (di_shared->p2u_ring_write_pos-di_shared->p2u_ring_read_pos);
U64 available_size = di_shared->p2u_ring_size-unconsumed_size; 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_p2u_pop_events(Arena *arena, U64 endt_us)
{ {
DI_EventList events = {0}; 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); U64 unconsumed_size = (di_shared->p2u_ring_write_pos-di_shared->p2u_ring_read_pos);
if(unconsumed_size >= sizeof(DI_EventKind) + sizeof(U64)) if(unconsumed_size >= sizeof(DI_EventKind) + sizeof(U64))
@@ -1111,7 +1111,7 @@ ASYNC_WORK_DEF(di_parse_work)
//////////////////////////// ////////////////////////////
//- rjf: commit parsed info to cache //- 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); DI_Node *node = di_node_from_key_slot__stripe_mutex_r_guarded(slot, &key);
if(node != 0) if(node != 0)
@@ -1153,7 +1153,7 @@ di_u2s_enqueue_req(U128 key, U64 endt_us)
B32 result = 0; B32 result = 0;
U64 thread_idx = key.u64[0]%di_shared->search_threads_count; U64 thread_idx = key.u64[0]%di_shared->search_threads_count;
DI_SearchThread *thread = &di_shared->search_threads[thread_idx]; 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 unconsumed_size = thread->ring_write_pos - thread->ring_read_pos;
U64 available_size = thread->ring_size - unconsumed_size; U64 available_size = thread->ring_size - unconsumed_size;
@@ -1181,7 +1181,7 @@ di_u2s_dequeue_req(U64 thread_idx)
{ {
U128 key = {0}; U128 key = {0};
DI_SearchThread *thread = &di_shared->search_threads[thread_idx]; 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 unconsumed_size = thread->ring_write_pos - thread->ring_read_pos;
if(unconsumed_size >= sizeof(key)) 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 //- rjf: every so often, check the key's write gen - if it has been bumped, then cancel
if(idx%100 == 0) if(idx%100 == 0)
{ {
OS_MutexScopeR(stripe->rw_mutex) MutexScopeR(stripe->rw_mutex)
{ {
for(DI_SearchNode *n = slot->first; n != 0; n = n->next) for(DI_SearchNode *n = slot->first; n != 0; n = n->next)
{ {
@@ -1385,7 +1385,7 @@ internal void
di_search_thread__entry_point(void *p) di_search_thread__entry_point(void *p)
{ {
U64 thread_idx = (U64)p; U64 thread_idx = (U64)p;
ThreadNameF("[di] search thread #%I64u", thread_idx); ThreadNameF("di_search_thread_%I64u", thread_idx);
for(;;) for(;;)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
@@ -1402,7 +1402,7 @@ di_search_thread__entry_point(void *p)
String8 query = {0}; String8 query = {0};
DI_SearchParams params = {0}; DI_SearchParams params = {0};
U64 initial_bucket_write_gen = 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) 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 //- rjf: commit to cache - wait on scope touches
if(arena != 0) if(arena != 0)
{ {
OS_MutexScopeW(stripe->rw_mutex) for(;;) MutexScopeW(stripe->rw_mutex) for(;;)
{ {
B32 found = 0; B32 found = 0;
B32 done = 0; B32 done = 0;
@@ -1553,7 +1553,7 @@ di_search_thread__entry_point(void *p)
internal void internal void
di_search_evictor_thread__entry_point(void *p) di_search_evictor_thread__entry_point(void *p)
{ {
ThreadNameF("[di] search evictor thread"); ThreadNameF("di_search_evictor_thread");
for(;;) for(;;)
{ {
for(U64 slot_idx = 0; slot_idx < di_shared->search_slots_count; slot_idx += 1) 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_SearchSlot *slot = &di_shared->search_slots[slot_idx];
DI_SearchStripe *stripe = &di_shared->search_stripes[stripe_idx]; DI_SearchStripe *stripe = &di_shared->search_stripes[stripe_idx];
B32 slot_has_work = 0; 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) 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) 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 // 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); arena_clear(store->params_arena);
store->params_hash = params_hash; 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)) if(completed_params_hash != store->params_hash && node->req_count == ins_atomic_u64_eval(&node->cmp_count))
{ {
B32 sent = 0; 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 unconsumed_size = store->u2m_ring_write_pos - store->u2m_ring_read_pos;
U64 available_size = store->u2m_ring_size - unconsumed_size; 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 // 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) 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)) 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; DI_MatchNameNode *node = 0;
U64 alloc_gen = 0; U64 alloc_gen = 0;
String8 name = {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; U64 unconsumed_size = store->u2m_ring_write_pos - store->u2m_ring_read_pos;
if(unconsumed_size >= sizeof(U64)) if(unconsumed_size >= sizeof(U64))
@@ -1824,7 +1824,7 @@ ASYNC_WORK_DEF(di_match_work)
//- rjf: read parameters //- rjf: read parameters
U64 params_hash = 0; U64 params_hash = 0;
DI_KeyArray params_keys = {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_keys = di_key_array_copy(scratch.arena, &store->params_keys);
params_hash = store->params_hash; params_hash = store->params_hash;
+2 -2
View File
@@ -248,7 +248,7 @@ struct DI_TCTX
typedef struct DI_SearchThread DI_SearchThread; typedef struct DI_SearchThread DI_SearchThread;
struct DI_SearchThread struct DI_SearchThread
{ {
OS_Handle thread; Thread thread;
Mutex ring_mutex; Mutex ring_mutex;
CondVar ring_cv; CondVar ring_cv;
U64 ring_size; U64 ring_size;
@@ -386,7 +386,7 @@ struct DI_Shared
// rjf: search threads // rjf: search threads
U64 search_threads_count; U64 search_threads_count;
DI_SearchThread *search_threads; DI_SearchThread *search_threads;
OS_Handle search_evictor_thread; Thread search_evictor_thread;
}; };
//////////////////////////////// ////////////////////////////////
+2 -2
View File
@@ -922,7 +922,7 @@ dmn_ctrl_begin(void)
internal void internal void
dmn_ctrl_exclusive_access_begin(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; dmn_lnx_state->access_run_state = 1;
} }
@@ -931,7 +931,7 @@ dmn_ctrl_exclusive_access_begin(void)
internal void internal void
dmn_ctrl_exclusive_access_end(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; dmn_lnx_state->access_run_state = 0;
} }
+2 -2
View File
@@ -1204,7 +1204,7 @@ dmn_ctrl_begin(void)
internal void internal void
dmn_ctrl_exclusive_access_begin(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; dmn_w32_shared->access_run_state = 1;
} }
@@ -1213,7 +1213,7 @@ dmn_ctrl_exclusive_access_begin(void)
internal void internal void
dmn_ctrl_exclusive_access_end(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; dmn_w32_shared->access_run_state = 0;
} }
+70 -217
View File
@@ -52,11 +52,8 @@ fs_init(void)
fs_shared->stripes[idx].cv = cond_var_alloc(); fs_shared->stripes[idx].cv = cond_var_alloc();
fs_shared->stripes[idx].rw_mutex = rw_mutex_alloc(); fs_shared->stripes[idx].rw_mutex = rw_mutex_alloc();
} }
fs_shared->u2s_ring_size = KB(64); fs_shared->req_mutex = mutex_alloc();
fs_shared->u2s_ring_base = push_array_no_zero(arena, U8, fs_shared->u2s_ring_size); fs_shared->req_arena = arena_alloc();
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);
} }
//////////////////////////////// ////////////////////////////////
@@ -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_Slot *path_slot = &fs_shared->slots[path_slot_idx];
FS_Stripe *path_stripe = &fs_shared->stripes[path_stripe_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}; 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; 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) for(FS_Node *n = path_slot->first; n != 0; n = n->next)
{ {
if(str8_match(n->path, path, 0)) if(str8_match(n->path, path, 0))
@@ -110,7 +97,7 @@ fs_key_from_path_range(String8 path, Rng1U64 range, U64 endt_us)
break; break;
} }
} }
if(!node_found) if(write_mode && !node_found)
{ {
FS_Node *node = push_array(path_stripe->arena, FS_Node, 1); FS_Node *node = push_array(path_stripe->arena, FS_Node, 1);
SLLQueuePush(path_slot->first, path_slot->last, node); 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; root = node->root;
} }
} }
if(node_found)
{
break;
}
} }
//- rjf: build a key for this path/range combo //- 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())) if(u128_match(hs_hash_from_key(key, 0), u128_zero()))
{ {
// rjf: loop: request, check for results, return until we can't // 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 // rjf: path -> node
FS_Node *node = 0; 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; range_node->id = key.id;
} }
// rjf: try to send stream request // rjf: push request
if(ins_atomic_u64_eval(&range_node->working_count) == 0 && if(range_node->working_count == 0)
fs_u2s_enqueue_req(key, range, path, endt_us))
{ {
ins_atomic_u64_inc_eval(&range_node->working_count); range_node->working_count += 1;
DeferLoop(rw_mutex_drop_w(path_stripe->rw_mutex), rw_mutex_take_w(path_stripe->rw_mutex)) 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 // rjf: have time to wait? -> wait on this stripe; otherwise exit
B32 have_results = !u128_match(hs_hash_from_key(key, 0), u128_zero()); B32 have_results = !u128_match(hs_hash_from_key(key, 0), u128_zero());
if(!have_results && os_now_microseconds() < endt_us) 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 else
{ {
@@ -229,7 +225,7 @@ fs_properties_from_path(String8 path)
U64 stripe_idx = slot_idx%fs_shared->stripes_count; U64 stripe_idx = slot_idx%fs_shared->stripes_count;
FS_Slot *slot = &fs_shared->slots[slot_idx]; FS_Slot *slot = &fs_shared->slots[slot_idx];
FS_Stripe *stripe = &fs_shared->stripes[stripe_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) 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); 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 //- rjf: gather all requests
local_persist FS_Request *reqs = 0; local_persist FS_Request *reqs = 0;
local_persist U64 reqs_count = 0; local_persist U64 reqs_count = 0;
@@ -331,7 +372,7 @@ fs_async_tick(void)
} }
//- rjf: commit info to cache //- 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; FS_Node *node = 0;
for(FS_Node *n = path_slot->first; n != 0; n = n->next) for(FS_Node *n = path_slot->first; n != 0; n = n->next)
@@ -356,191 +397,3 @@ fs_async_tick(void)
scratch_end(scratch); 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);
}
}
-23
View File
@@ -91,17 +91,6 @@ struct FS_Shared
FS_RequestNode *first_req; FS_RequestNode *first_req;
FS_RequestNode *last_req; FS_RequestNode *last_req;
U64 req_count; 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); 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 #endif // FILE_STREAM_H
+11 -11
View File
@@ -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_base = push_array_no_zero(arena, U8, geo_shared->u2x_ring_size);
geo_shared->u2x_ring_cv = cond_var_alloc(); geo_shared->u2x_ring_cv = cond_var_alloc();
geo_shared->u2x_ring_mutex = mutex_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; U64 stripe_idx = slot_idx%geo_shared->stripes_count;
GEO_Slot *slot = &geo_shared->slots[slot_idx]; GEO_Slot *slot = &geo_shared->slots[slot_idx];
GEO_Stripe *stripe = &geo_shared->stripes[stripe_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) 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_Slot *slot = &geo_shared->slots[slot_idx];
GEO_Stripe *stripe = &geo_shared->stripes[stripe_idx]; GEO_Stripe *stripe = &geo_shared->stripes[stripe_idx];
B32 found = 0; B32 found = 0;
OS_MutexScopeR(stripe->rw_mutex) MutexScopeR(stripe->rw_mutex)
{ {
for(GEO_Node *n = slot->first; n != 0; n = n->next) 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; B32 node_is_new = 0;
if(!found) if(!found)
{ {
OS_MutexScopeW(stripe->rw_mutex) MutexScopeW(stripe->rw_mutex)
{ {
GEO_Node *node = 0; GEO_Node *node = 0;
for(GEO_Node *n = slot->first; n != 0; n = n->next) 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) geo_u2x_enqueue_req(U128 hash, U64 endt_us)
{ {
B32 good = 0; 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 unconsumed_size = geo_shared->u2x_ring_write_pos-geo_shared->u2x_ring_read_pos;
U64 available_size = geo_shared->u2x_ring_size-unconsumed_size; 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 internal void
geo_u2x_dequeue_req(U128 *hash_out) 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; U64 unconsumed_size = geo_shared->u2x_ring_write_pos-geo_shared->u2x_ring_read_pos;
if(unconsumed_size >= sizeof(*hash_out)) if(unconsumed_size >= sizeof(*hash_out))
@@ -259,7 +259,7 @@ ASYNC_WORK_DEF(geo_xfer_work)
//- rjf: take task //- rjf: take task
B32 got_task = 0; B32 got_task = 0;
OS_MutexScopeR(stripe->rw_mutex) MutexScopeR(stripe->rw_mutex)
{ {
for(GEO_Node *n = slot->first; n != 0; n = n->next) 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 //- 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) for(GEO_Node *n = slot->first; n != 0; n = n->next)
{ {
@@ -311,7 +311,7 @@ ASYNC_WORK_DEF(geo_xfer_work)
internal void internal void
geo_evictor_thread__entry_point(void *p) geo_evictor_thread__entry_point(void *p)
{ {
ThreadNameF("[geo] evictor thread"); ThreadNameF("geo_evictor_thread");
for(;;) for(;;)
{ {
U64 check_time_us = os_now_microseconds(); 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_Slot *slot = &geo_shared->slots[slot_idx];
GEO_Stripe *stripe = &geo_shared->stripes[stripe_idx]; GEO_Stripe *stripe = &geo_shared->stripes[stripe_idx];
B32 slot_has_work = 0; 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) 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) for(GEO_Node *n = slot->first, *next = 0; n != 0; n = next)
{ {
+1 -1
View File
@@ -88,7 +88,7 @@ struct GEO_Shared
Mutex u2x_ring_mutex; Mutex u2x_ring_mutex;
// rjf: evictor thread // rjf: evictor thread
OS_Handle evictor_thread; Thread evictor_thread;
}; };
//////////////////////////////// ////////////////////////////////
+17 -17
View File
@@ -103,7 +103,7 @@ hs_init(void)
stripe->rw_mutex = rw_mutex_alloc(); stripe->rw_mutex = rw_mutex_alloc();
stripe->cv = cond_var_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; U64 stripe_idx = slot_idx%hs_shared->root_stripes_count;
HS_RootSlot *slot = &hs_shared->root_slots[slot_idx]; HS_RootSlot *slot = &hs_shared->root_slots[slot_idx];
HS_Stripe *stripe = &hs_shared->root_stripes[stripe_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]; HS_RootNode *node = hs_shared->root_stripes_free_nodes[stripe_idx];
if(node != 0) if(node != 0)
@@ -148,7 +148,7 @@ hs_root_release(HS_Root root)
//- rjf: release root node, grab its arena / ID list //- rjf: release root node, grab its arena / ID list
Arena *root_arena = 0; Arena *root_arena = 0;
HS_RootIDChunkList root_ids = {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) 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; U64 key_stripe_idx = key_slot_idx%hs_shared->key_stripes_count;
HS_KeySlot *key_slot = &hs_shared->key_slots[key_slot_idx]; HS_KeySlot *key_slot = &hs_shared->key_slots[key_slot_idx];
HS_Stripe *key_stripe = &hs_shared->key_stripes[key_stripe_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) 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; U64 hash_stripe_idx = hash_slot_idx%hs_shared->stripes_count;
HS_Slot *hash_slot = &hs_shared->slots[hash_slot_idx]; HS_Slot *hash_slot = &hs_shared->slots[hash_slot_idx];
HS_Stripe *hash_stripe = &hs_shared->stripes[hash_stripe_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) 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]; HS_Stripe *stripe = &hs_shared->stripes[stripe_idx];
//- rjf: commit data to cache - if already there, just bump key refcount //- 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; HS_Node *existing_node = 0;
for(HS_Node *n = slot->first; n != 0; n = n->next) 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 //- rjf: commit this hash to key cache
U128 key_expired_hash = {0}; 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 // rjf: find existing key
B32 key_is_new = 0; 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; U64 root_stripe_idx = root_slot_idx%hs_shared->root_stripes_count;
HS_RootSlot *root_slot = &hs_shared->root_slots[root_slot_idx]; HS_RootSlot *root_slot = &hs_shared->root_slots[root_slot_idx];
HS_Stripe *root_stripe = &hs_shared->root_stripes[root_stripe_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) 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; 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_Slot *old_hash_slot = &hs_shared->slots[old_hash_slot_idx];
HS_Stripe *old_hash_stripe = &hs_shared->stripes[old_hash_stripe_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) 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; U64 stripe_idx = slot_idx%hs_shared->stripes_count;
HS_Slot *slot = &hs_shared->slots[slot_idx]; HS_Slot *slot = &hs_shared->slots[slot_idx];
HS_Stripe *stripe = &hs_shared->stripes[stripe_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) 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; U64 stripe_idx = slot_idx%hs_shared->stripes_count;
HS_Slot *slot = &hs_shared->slots[slot_idx]; HS_Slot *slot = &hs_shared->slots[slot_idx];
HS_Stripe *stripe = &hs_shared->stripes[stripe_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) 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; U64 stripe_idx = slot_idx%hs_shared->stripes_count;
HS_Slot *slot = &hs_shared->slots[slot_idx]; HS_Slot *slot = &hs_shared->slots[slot_idx];
HS_Stripe *stripe = &hs_shared->stripes[stripe_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) 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; U64 key_stripe_idx = key_slot_idx%hs_shared->key_stripes_count;
HS_KeySlot *key_slot = &hs_shared->key_slots[key_slot_idx]; HS_KeySlot *key_slot = &hs_shared->key_slots[key_slot_idx];
HS_Stripe *key_stripe = &hs_shared->key_stripes[key_stripe_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) 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; U64 stripe_idx = slot_idx%hs_shared->stripes_count;
HS_Slot *slot = &hs_shared->slots[slot_idx]; HS_Slot *slot = &hs_shared->slots[slot_idx];
HS_Stripe *stripe = &hs_shared->stripes[stripe_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) 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 internal void
hs_evictor_thread__entry_point(void *p) hs_evictor_thread__entry_point(void *p)
{ {
ThreadNameF("[hs] evictor thread"); ThreadNameF("hs_evictor_thread");
for(;;) for(;;)
{ {
for(U64 slot_idx = 0; slot_idx < hs_shared->slots_count; slot_idx += 1) 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_Slot *slot = &hs_shared->slots[slot_idx];
HS_Stripe *stripe = &hs_shared->stripes[stripe_idx]; HS_Stripe *stripe = &hs_shared->stripes[stripe_idx];
B32 slot_has_work = 0; 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) 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) for(HS_Node *n = slot->first, *next = 0; n != 0; n = next)
{ {
+1 -1
View File
@@ -208,7 +208,7 @@ struct HS_Shared
U64 root_id_gen; U64 root_id_gen;
// rjf: evictor thread // rjf: evictor thread
OS_Handle evictor_thread; Thread evictor_thread;
}; };
//////////////////////////////// ////////////////////////////////
+4 -4
View File
@@ -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].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].cv = cond_var_alloc();
mtx_shared->mut_threads[idx].mutex = mutex_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) 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 // 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 unconsumed_size = thread->ring_write_pos - thread->ring_read_pos;
U64 available_size = thread->ring_size - unconsumed_size; 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 internal void
mtx_dequeue_op(Arena *arena, MTX_MutThread *thread, HS_Key *buffer_key_out, MTX_Op *op_out) 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; 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)) 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_mut_thread__entry_point(void *p)
{ {
MTX_MutThread *mut_thread = (MTX_MutThread *)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(;;) for(;;)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
+1 -1
View File
@@ -49,7 +49,7 @@ struct MTX_MutThread
U64 ring_write_pos; U64 ring_write_pos;
CondVar cv; CondVar cv;
Mutex mutex; Mutex mutex;
OS_Handle thread; Thread thread;
}; };
//////////////////////////////// ////////////////////////////////
+30 -61
View File
@@ -121,7 +121,7 @@ internal void *
os_lnx_thread_entry_point(void *ptr) os_lnx_thread_entry_point(void *ptr)
{ {
OS_LNX_Entity *entity = (OS_LNX_Entity *)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; void *thread_ptr = entity->thread.ptr;
supplement_thread_base_entry_point(func, thread_ptr); supplement_thread_base_entry_point(func, thread_ptr);
return 0; return 0;
@@ -801,7 +801,7 @@ os_process_kill(OS_Handle handle)
//~ rjf: @os_hooks Threads (Implemented Per-OS) //~ rjf: @os_hooks Threads (Implemented Per-OS)
internal OS_Handle 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); OS_LNX_Entity *entity = os_lnx_entity_alloc(OS_LNX_EntityKind_Thread);
entity->thread.func = func; entity->thread.func = func;
@@ -911,31 +911,22 @@ os_rw_mutex_release(OS_Handle rw_mutex)
} }
internal void 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; } if(os_handle_match(rw_mutex, os_handle_zero())) { return; }
OS_LNX_Entity *entity = (OS_LNX_Entity *)rw_mutex.u64[0]; 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 internal void
os_rw_mutex_drop_r(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];
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)
{ {
if(os_handle_match(rw_mutex, os_handle_zero())) { return; } if(os_handle_match(rw_mutex, os_handle_zero())) { return; }
OS_LNX_Entity *entity = (OS_LNX_Entity *)rw_mutex.u64[0]; 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 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 // 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 // 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); int wait_result = pthread_cond_timedwait(&cv_entity->cv.cond_handle, &cv_entity->cv.rwlock_mutex_handle, &endt_timespec);
if(wait_result != ETIMEDOUT) 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; result = 1;
break; break;
} }
if(wait_result == ETIMEDOUT) if(wait_result == ETIMEDOUT)
{ {
pthread_rwlock_rdlock(&rw_mutex_entity->rwmutex_handle); if(write_mode)
break; {
} pthread_rwlock_wrlock(&rw_mutex_entity->rwmutex_handle);
} }
pthread_mutex_unlock(&cv_entity->cv.rwlock_mutex_handle); else
return result; {
} pthread_rwlock_rdlock(&rw_mutex_entity->rwmutex_handle);
}
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);
break; break;
} }
} }
@@ -1229,7 +1198,7 @@ os_library_close(OS_Handle lib)
//~ rjf: @os_hooks Safe Calls (Implemented Per-OS) //~ rjf: @os_hooks Safe Calls (Implemented Per-OS)
internal void 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 // rjf: push handler to chain
OS_LNX_SafeCallChain chain = {0}; OS_LNX_SafeCallChain chain = {0};
+2 -2
View File
@@ -54,7 +54,7 @@ typedef struct OS_LNX_SafeCallChain OS_LNX_SafeCallChain;
struct OS_LNX_SafeCallChain struct OS_LNX_SafeCallChain
{ {
OS_LNX_SafeCallChain *next; OS_LNX_SafeCallChain *next;
OS_ThreadFunctionType *fail_handler; ThreadEntryPointFunctionType *fail_handler;
void *ptr; void *ptr;
}; };
@@ -81,7 +81,7 @@ struct OS_LNX_Entity
struct struct
{ {
pthread_t handle; pthread_t handle;
OS_ThreadFunctionType *func; ThreadEntryPointFunctionType *func;
void *ptr; void *ptr;
} thread; } thread;
pthread_mutex_t mutex_handle; pthread_mutex_t mutex_handle;
+3 -3
View File
@@ -783,7 +783,7 @@ lnx_free_entity(LNX_Entity *entity){
internal void* internal void*
lnx_thread_base(void *ptr){ lnx_thread_base(void *ptr){
LNX_Entity *entity = (LNX_Entity*)ptr; LNX_Entity *entity = (LNX_Entity*)ptr;
OS_ThreadFunctionType *func = entity->thread.func; ThreadEntryPointFunctionType *func = entity->thread.func;
void *thread_ptr = entity->thread.ptr; void *thread_ptr = entity->thread.ptr;
TCTX tctx_; TCTX tctx_;
@@ -1377,7 +1377,7 @@ os_launch_process(OS_LaunchOptions *options){
//~ rjf: @os_hooks Threads (Implemented Per-OS) //~ rjf: @os_hooks Threads (Implemented Per-OS)
internal OS_Handle internal OS_Handle
os_thread_launch(OS_ThreadFunctionType *func, void *ptr, void *params){ os_thread_launch(ThreadEntryPointFunctionType *func, void *ptr, void *params){
// entity // entity
LNX_Entity *entity = lnx_alloc_entity(LNX_EntityKind_Thread); LNX_Entity *entity = lnx_alloc_entity(LNX_EntityKind_Thread);
entity->reference_mask = 0x3; entity->reference_mask = 0x3;
@@ -1642,7 +1642,7 @@ os_library_close(OS_Handle lib)
//~ rjf: @os_hooks Dynamically-Loaded Libraries (Implemented Per-OS) //~ rjf: @os_hooks Dynamically-Loaded Libraries (Implemented Per-OS)
internal void 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}; LNX_SafeCallChain chain = {0};
SLLStackPush(lnx_safe_call_chain, &chain); SLLStackPush(lnx_safe_call_chain, &chain);
chain.fail_handler = fail_handler; chain.fail_handler = fail_handler;
+2 -2
View File
@@ -48,7 +48,7 @@ struct LNX_Entity{
volatile U32 reference_mask; volatile U32 reference_mask;
union{ union{
struct{ struct{
OS_ThreadFunctionType *func; ThreadEntryPointFunctionType *func;
void *ptr; void *ptr;
pthread_t handle; pthread_t handle;
} thread; } thread;
@@ -62,7 +62,7 @@ struct LNX_Entity{
struct LNX_SafeCallChain{ struct LNX_SafeCallChain{
LNX_SafeCallChain *next; LNX_SafeCallChain *next;
OS_ThreadFunctionType *fail_handler; ThreadEntryPointFunctionType *fail_handler;
void *ptr; void *ptr;
}; };
-15
View File
@@ -40,21 +40,6 @@ os_handle_array_from_list(Arena *arena, OS_HandleList *list)
return result; 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) //~ rjf: Filesystem Helpers (Helpers, Implemented Once)
+7 -26
View File
@@ -128,11 +128,6 @@ struct OS_ProcessLaunchParams
OS_Handle stdin_file; OS_Handle stdin_file;
}; };
////////////////////////////////
//~ rjf: Thread Types
typedef void OS_ThreadFunctionType(void *ptr);
//////////////////////////////// ////////////////////////////////
//~ rjf: Handle Type Functions (Helpers, Implemented Once) //~ 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 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); 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) //~ 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) //~ 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);
internal B32 os_thread_join(OS_Handle handle, U64 endt_us); internal B32 os_thread_join(Thread handle, U64 endt_us);
internal void os_thread_detach(OS_Handle handle); internal void os_thread_detach(Thread handle);
//////////////////////////////// ////////////////////////////////
//~ rjf: @os_hooks Synchronization Primitives (Implemented Per-OS) //~ rjf: @os_hooks Synchronization Primitives (Implemented Per-OS)
@@ -278,18 +268,15 @@ internal void os_mutex_drop(Mutex mutex);
//- rjf: reader/writer mutexes //- rjf: reader/writer mutexes
internal RWMutex os_rw_mutex_alloc(void); internal RWMutex os_rw_mutex_alloc(void);
internal void os_rw_mutex_release(RWMutex mutex); internal void os_rw_mutex_release(RWMutex mutex);
internal void os_rw_mutex_take_r(RWMutex mutex); internal void os_rw_mutex_take(RWMutex mutex, B32 write_mode);
internal void os_rw_mutex_drop_r(RWMutex mutex); internal void os_rw_mutex_drop(RWMutex mutex, B32 write_mode);
internal void os_rw_mutex_take_w(RWMutex mutex);
internal void os_rw_mutex_drop_w(RWMutex mutex);
//- rjf: condition variables //- rjf: condition variables
internal CondVar os_cond_var_alloc(void); internal CondVar os_cond_var_alloc(void);
internal void os_cond_var_release(CondVar cv); internal void os_cond_var_release(CondVar cv);
// returns false on timeout, true on signal, (max_wait_ms = max_U64) -> no timeout // 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(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(CondVar cv, RWMutex mutex_rw, B32 write_mode, U64 endt_us);
internal B32 os_cond_var_wait_rw_w(CondVar cv, RWMutex mutex_rw, U64 endt_us);
internal void os_cond_var_signal(CondVar cv); internal void os_cond_var_signal(CondVar cv);
internal void os_cond_var_broadcast(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_release(Barrier barrier);
internal void os_barrier_wait(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) //~ 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) //~ 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) //~ rjf: @os_hooks GUIDs (Implemented Per-OS)
+29 -43
View File
@@ -144,7 +144,7 @@ internal DWORD
os_w32_thread_entry_point(void *ptr) os_w32_thread_entry_point(void *ptr)
{ {
OS_W32_Entity *entity = (OS_W32_Entity *)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; void *thread_ptr = entity->thread.ptr;
supplement_thread_base_entry_point(func, thread_ptr); supplement_thread_base_entry_point(func, thread_ptr);
return 0; return 0;
@@ -1103,19 +1103,19 @@ os_process_detach(OS_Handle handle)
//////////////////////////////// ////////////////////////////////
//~ rjf: @os_hooks Threads (Implemented Per-OS) //~ rjf: @os_hooks Threads (Implemented Per-OS)
internal OS_Handle internal Thread
os_thread_launch(OS_ThreadFunctionType *func, void *ptr, void *params) os_thread_launch(ThreadEntryPointFunctionType *f, void *p)
{ {
OS_W32_Entity *entity = os_w32_entity_alloc(OS_W32_EntityKind_Thread); OS_W32_Entity *entity = os_w32_entity_alloc(OS_W32_EntityKind_Thread);
entity->thread.func = func; entity->thread.func = f;
entity->thread.ptr = ptr; entity->thread.ptr = p;
entity->thread.handle = CreateThread(0, 0, os_w32_thread_entry_point, entity, 0, &entity->thread.tid); 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; return result;
} }
internal B32 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); DWORD sleep_ms = os_w32_sleep_ms_from_endt_us(endt_us);
OS_W32_Entity *entity = (OS_W32_Entity *)PtrFromInt(handle.u64[0]); 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 internal void
os_thread_detach(OS_Handle thread) os_thread_detach(Thread thread)
{ {
OS_W32_Entity *entity = (OS_W32_Entity*)PtrFromInt(thread.u64[0]); OS_W32_Entity *entity = (OS_W32_Entity*)PtrFromInt(thread.u64[0]);
if(entity != 0) if(entity != 0)
@@ -1194,31 +1194,31 @@ os_rw_mutex_release(RWMutex rw_mutex)
} }
internal void 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]); 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 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]); OS_W32_Entity *entity = (OS_W32_Entity*)PtrFromInt(rw_mutex.u64[0]);
ReleaseSRWLockShared(&entity->rw_mutex); if(write_mode)
} {
ReleaseSRWLockExclusive(&entity->rw_mutex);
internal void }
os_rw_mutex_take_w(RWMutex rw_mutex) else
{ {
OS_W32_Entity *entity = (OS_W32_Entity*)PtrFromInt(rw_mutex.u64[0]); ReleaseSRWLockShared(&entity->rw_mutex);
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);
} }
//- rjf: condition variables //- rjf: condition variables
@@ -1254,7 +1254,7 @@ os_cond_var_wait(CondVar cv, Mutex mutex, U64 endt_us)
} }
internal B32 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); U32 sleep_ms = os_w32_sleep_ms_from_endt_us(endt_us);
BOOL result = 0; 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 *entity = (OS_W32_Entity*)PtrFromInt(cv.u64[0]);
OS_W32_Entity *mutex_entity = (OS_W32_Entity*)PtrFromInt(mutex_rw.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, result = SleepConditionVariableSRW(&entity->cv, &mutex_entity->rw_mutex, sleep_ms,
CONDITION_VARIABLE_LOCKMODE_SHARED); write_mode ? 0 : 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);
} }
return result; return result;
} }
@@ -1413,7 +1399,7 @@ os_library_close(OS_Handle lib)
//~ rjf: @os_hooks Safe Calls (Implemented Per-OS) //~ rjf: @os_hooks Safe Calls (Implemented Per-OS)
internal void 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 __try
{ {
+1 -1
View File
@@ -62,7 +62,7 @@ struct OS_W32_Entity
{ {
struct struct
{ {
OS_ThreadFunctionType *func; ThreadEntryPointFunctionType *func;
void *ptr; void *ptr;
HANDLE handle; HANDLE handle;
DWORD tid; DWORD tid;
+9 -9
View File
@@ -25,12 +25,12 @@ ptg_init(void)
ptg_shared->u2b_ring_cv = cond_var_alloc(); ptg_shared->u2b_ring_cv = cond_var_alloc();
ptg_shared->u2b_ring_mutex = mutex_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_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) 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) ptg_u2b_enqueue_req(PTG_Key *key, U64 endt_us)
{ {
B32 good = 0; 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 unconsumed_size = ptg_shared->u2b_ring_write_pos-ptg_shared->u2b_ring_read_pos;
U64 available_size = ptg_shared->u2b_ring_size-unconsumed_size; 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 internal void
ptg_u2b_dequeue_req(PTG_Key *key_out) 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; U64 unconsumed_size = ptg_shared->u2b_ring_write_pos-ptg_shared->u2b_ring_read_pos;
if(unconsumed_size >= sizeof(*key_out)) if(unconsumed_size >= sizeof(*key_out))
@@ -180,7 +180,7 @@ ptg_builder_thread__entry_point(void *p)
//- rjf: take task //- rjf: take task
B32 got_task = 0; B32 got_task = 0;
OS_MutexScopeR(stripe->rw_mutex) MutexScopeR(stripe->rw_mutex)
{ {
for(PTG_GraphNode *n = slot->first; n != 0; n = n->next) 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 //- 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) 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_GraphSlot *slot = &ptg_shared->slots[slot_idx];
PTG_GraphStripe *stripe = &ptg_shared->stripes[stripe_idx]; PTG_GraphStripe *stripe = &ptg_shared->stripes[stripe_idx];
B32 slot_has_work = 0; 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) 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) for(PTG_GraphNode *n = slot->first, *next = 0; n != 0; n = next)
{ {
+2 -2
View File
@@ -181,10 +181,10 @@ struct PTG_Shared
// rjf: builder threads // rjf: builder threads
U64 builder_thread_count; U64 builder_thread_count;
OS_Handle *builder_threads; Thread *builder_threads;
// rjf: evictor thread // rjf: evictor thread
OS_Handle evictor_thread; Thread evictor_thread;
}; };
//////////////////////////////// ////////////////////////////////
+3 -3
View File
@@ -23,7 +23,7 @@ rb_entry_point(CmdLine *cmdline)
threads_count = threads_count_from_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); RB_ThreadParams *threads_params = push_array(scratch.arena, RB_ThreadParams, threads_count);
Barrier barrier = barrier_alloc(threads_count); Barrier barrier = barrier_alloc(threads_count);
for EachIndex(idx, 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_idx = idx;
threads_params[idx].lane_ctx.lane_count = threads_count; threads_params[idx].lane_ctx.lane_count = threads_count;
threads_params[idx].lane_ctx.barrier = barrier; 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) for EachIndex(idx, threads_count)
{ {
os_thread_join(threads[idx], max_U64); thread_join(threads[idx], max_U64);
} }
scratch_end(scratch); scratch_end(scratch);
} }
+11 -5
View File
@@ -357,7 +357,7 @@ global CondVar ipc_s2m_ring_cv = {0};
internal void internal void
ipc_signaler_thread__entry_point(void *p) ipc_signaler_thread__entry_point(void *p)
{ {
ThreadNameF("[rd] ipc signaler thread"); ThreadNameF("rd_ipc_signaler_thread");
for(;;) for(;;)
{ {
if(os_semaphore_take(ipc_sender2main_signal_semaphore, max_U64)) 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; IPCInfo *ipc_info = (IPCInfo *)ipc_sender2main_shared_memory_base;
String8 msg = str8((U8 *)(ipc_info+1), ipc_info->msg_size); String8 msg = str8((U8 *)(ipc_info+1), ipc_info->msg_size);
msg.size = Min(msg.size, IPC_SHARED_MEMORY_BUFFER_SIZE - sizeof(IPCInfo)); 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 unconsumed_size = ipc_s2m_ring_write_pos - ipc_s2m_ring_read_pos;
U64 available_size = (sizeof(ipc_s2m_ring_buffer) - unconsumed_size); 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) if(ipc_sender2main_shared_memory_base != 0)
{ {
MemoryZeroStruct(ipc_info); MemoryZeroStruct(ipc_info);
os_thread_launch(ipc_signaler_thread__entry_point, 0, 0); thread_launch(ipc_signaler_thread__entry_point, 0);
} }
scratch_end(scratch); scratch_end(scratch);
@@ -551,7 +551,7 @@ entry_point(CmdLine *cmd_line)
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
B32 consumed = 0; B32 consumed = 0;
String8 msg = {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; U64 unconsumed_size = ipc_s2m_ring_write_pos - ipc_s2m_ring_read_pos;
if(unconsumed_size >= sizeof(U64)) if(unconsumed_size >= sizeof(U64))
@@ -711,7 +711,13 @@ entry_point(CmdLine *cmd_line)
IPCInfo *ipc_info = (IPCInfo *)ipc_sender2main_shared_memory_base; IPCInfo *ipc_info = (IPCInfo *)ipc_sender2main_shared_memory_base;
U8 *buffer = (U8 *)(ipc_info+1); U8 *buffer = (U8 *)(ipc_info+1);
U64 buffer_max = IPC_SHARED_MEMORY_BUFFER_SIZE - sizeof(IPCInfo); 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("")}; StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")};
String8 msg = str8_list_join(scratch.arena, &parts, &join); String8 msg = str8_list_join(scratch.arena, &parts, &join);
ipc_info->msg_size = Min(buffer_max, msg.size); ipc_info->msg_size = Min(buffer_max, msg.size);
+12 -12
View File
@@ -487,7 +487,7 @@ r_window_equip(OS_Handle handle)
{ {
ProfBeginFunction(); ProfBeginFunction();
R_Handle result = {0}; R_Handle result = {0};
OS_MutexScopeW(r_d3d11_state->device_rw_mutex) MutexScopeW(r_d3d11_state->device_rw_mutex)
{ {
//- rjf: allocate per-window-state //- rjf: allocate per-window-state
R_D3D11_Window *window = r_d3d11_state->first_free_window; 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) r_window_unequip(OS_Handle handle, R_Handle equip_handle)
{ {
ProfBeginFunction(); 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); R_D3D11_Window *window = r_d3d11_window_from_handle(equip_handle);
window->stage_color_srv->lpVtbl->Release(window->stage_color_srv); 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 //- rjf: allocate
R_D3D11_Tex2D *texture = 0; 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; texture = r_d3d11_state->first_free_tex2d;
if(texture == 0) if(texture == 0)
@@ -675,7 +675,7 @@ r_hook void
r_tex2d_release(R_Handle handle) r_tex2d_release(R_Handle handle)
{ {
ProfBeginFunction(); 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); R_D3D11_Tex2D *texture = r_d3d11_tex2d_from_handle(handle);
if(texture != &r_d3d11_tex2d_nil) if(texture != &r_d3d11_tex2d_nil)
@@ -711,7 +711,7 @@ r_hook void
r_fill_tex2d_region(R_Handle handle, Rng2S32 subrect, void *data) r_fill_tex2d_region(R_Handle handle, Rng2S32 subrect, void *data)
{ {
ProfBeginFunction(); 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); R_D3D11_Tex2D *texture = r_d3d11_tex2d_from_handle(handle);
if(texture != &r_d3d11_tex2d_nil) if(texture != &r_d3d11_tex2d_nil)
@@ -739,7 +739,7 @@ r_buffer_alloc(R_ResourceKind kind, U64 size, void *data)
//- rjf: allocate //- rjf: allocate
R_D3D11_Buffer *buffer = 0; 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; buffer = r_d3d11_state->first_free_buffer;
if(buffer == 0) if(buffer == 0)
@@ -798,7 +798,7 @@ r_hook void
r_buffer_release(R_Handle handle) r_buffer_release(R_Handle handle)
{ {
ProfBeginFunction(); 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); R_D3D11_Buffer *buffer = r_d3d11_buffer_from_handle(handle);
SLLStackPush(r_d3d11_state->first_to_free_buffer, buffer); SLLStackPush(r_d3d11_state->first_to_free_buffer, buffer);
@@ -811,7 +811,7 @@ r_buffer_release(R_Handle handle)
r_hook void r_hook void
r_begin_frame(void) r_begin_frame(void)
{ {
OS_MutexScopeW(r_d3d11_state->device_rw_mutex) MutexScopeW(r_d3d11_state->device_rw_mutex)
{ {
// NOTE(rjf): no-op // NOTE(rjf): no-op
} }
@@ -820,7 +820,7 @@ r_begin_frame(void)
r_hook void r_hook void
r_end_frame(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) 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) r_window_begin_frame(OS_Handle window, R_Handle window_equip)
{ {
ProfBeginFunction(); 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); R_D3D11_Window *wnd = r_d3d11_window_from_handle(window_equip);
ID3D11DeviceContext1 *d_ctx = r_d3d11_state->device_ctx; 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) r_window_end_frame(OS_Handle window, R_Handle window_equip)
{ {
ProfBeginFunction(); 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); R_D3D11_Window *wnd = r_d3d11_window_from_handle(window_equip);
ID3D11DeviceContext1 *d_ctx = r_d3d11_state->device_ctx; 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) r_window_submit(OS_Handle window, R_Handle window_equip, R_PassList *passes)
{ {
ProfBeginFunction(); ProfBeginFunction();
OS_MutexScopeW(r_d3d11_state->device_rw_mutex) MutexScopeW(r_d3d11_state->device_rw_mutex)
{ {
//////////////////////////// ////////////////////////////
//- rjf: unpack arguments //- rjf: unpack arguments
+12 -12
View File
@@ -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_base = push_array_no_zero(arena, U8, txt_shared->u2p_ring_size);
txt_shared->u2p_ring_cv = cond_var_alloc(); txt_shared->u2p_ring_cv = cond_var_alloc();
txt_shared->u2p_ring_mutex = mutex_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; U64 stripe_idx = slot_idx%txt_shared->stripes_count;
TXT_Slot *slot = &txt_shared->slots[slot_idx]; TXT_Slot *slot = &txt_shared->slots[slot_idx];
TXT_Stripe *stripe = &txt_shared->stripes[stripe_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) 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_Slot *slot = &txt_shared->slots[slot_idx];
TXT_Stripe *stripe = &txt_shared->stripes[stripe_idx]; TXT_Stripe *stripe = &txt_shared->stripes[stripe_idx];
B32 found = 0; B32 found = 0;
OS_MutexScopeR(stripe->rw_mutex) MutexScopeR(stripe->rw_mutex)
{ {
for(TXT_Node *n = slot->first; n != 0; n = n->next) 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; B32 node_is_new = 0;
if(!found) if(!found)
{ {
OS_MutexScopeW(stripe->rw_mutex) MutexScopeW(stripe->rw_mutex)
{ {
TXT_Node *node = 0; TXT_Node *node = 0;
for(TXT_Node *n = slot->first; n != 0; n = n->next) 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) txt_u2p_enqueue_req(U128 hash, TXT_LangKind lang, U64 endt_us)
{ {
B32 good = 0; 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 unconsumed_size = txt_shared->u2p_ring_write_pos - txt_shared->u2p_ring_read_pos;
U64 available_size = txt_shared->u2p_ring_size - unconsumed_size; 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 internal void
txt_u2p_dequeue_req(U128 *hash_out, TXT_LangKind *lang_out) 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; U64 unconsumed_size = txt_shared->u2p_ring_write_pos - txt_shared->u2p_ring_read_pos;
if(unconsumed_size >= sizeof(*hash_out) + sizeof(*lang_out)) if(unconsumed_size >= sizeof(*hash_out) + sizeof(*lang_out))
@@ -2216,7 +2216,7 @@ ASYNC_WORK_DEF(txt_parse_work)
//- rjf: take task //- rjf: take task
B32 got_task = 0; B32 got_task = 0;
OS_MutexScopeR(stripe->rw_mutex) MutexScopeR(stripe->rw_mutex)
{ {
for(TXT_Node *n = slot->first; n != 0; n = n->next) 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 //- rjf: grab pointers to working counters
U64 *bytes_processed_ptr = 0; U64 *bytes_processed_ptr = 0;
U64 *bytes_to_process_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) 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 //- 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) for(TXT_Node *n = slot->first; n != 0; n = n->next)
{ {
@@ -2511,7 +2511,7 @@ ASYNC_WORK_DEF(txt_parse_work)
internal void internal void
txt_evictor_thread__entry_point(void *p) txt_evictor_thread__entry_point(void *p)
{ {
ThreadNameF("[txt] evictor thread"); ThreadNameF("txt_evictor_thread");
for(;;) for(;;)
{ {
U64 check_time_us = os_now_microseconds(); 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_Slot *slot = &txt_shared->slots[slot_idx];
TXT_Stripe *stripe = &txt_shared->stripes[stripe_idx]; TXT_Stripe *stripe = &txt_shared->stripes[stripe_idx];
B32 slot_has_work = 0; 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) 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) for(TXT_Node *n = slot->first, *next = 0; n != 0; n = next)
{ {
+1 -1
View File
@@ -252,7 +252,7 @@ struct TXT_Shared
Mutex u2p_ring_mutex; Mutex u2p_ring_mutex;
// rjf: evictor thread // rjf: evictor thread
OS_Handle evictor_thread; Thread evictor_thread;
}; };
//////////////////////////////// ////////////////////////////////
+11 -11
View File
@@ -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_base = push_array_no_zero(arena, U8, tex_shared->u2x_ring_size);
tex_shared->u2x_ring_cv = cond_var_alloc(); tex_shared->u2x_ring_cv = cond_var_alloc();
tex_shared->u2x_ring_mutex = mutex_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; U64 stripe_idx = slot_idx%tex_shared->stripes_count;
TEX_Slot *slot = &tex_shared->slots[slot_idx]; TEX_Slot *slot = &tex_shared->slots[slot_idx];
TEX_Stripe *stripe = &tex_shared->stripes[stripe_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) 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]; TEX_Stripe *stripe = &tex_shared->stripes[stripe_idx];
B32 found = 0; B32 found = 0;
B32 stale = 0; B32 stale = 0;
OS_MutexScopeR(stripe->rw_mutex) MutexScopeR(stripe->rw_mutex)
{ {
for(TEX_Node *n = slot->first; n != 0; n = n->next) 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; B32 node_is_new = 0;
if(!found) if(!found)
{ {
OS_MutexScopeW(stripe->rw_mutex) MutexScopeW(stripe->rw_mutex)
{ {
TEX_Node *node = 0; TEX_Node *node = 0;
for(TEX_Node *n = slot->first; n != 0; n = n->next) 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) tex_u2x_enqueue_req(U128 hash, TEX_Topology top, U64 endt_us)
{ {
B32 good = 0; 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 unconsumed_size = tex_shared->u2x_ring_write_pos-tex_shared->u2x_ring_read_pos;
U64 available_size = tex_shared->u2x_ring_size-unconsumed_size; 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 internal void
tex_u2x_dequeue_req(U128 *hash_out, TEX_Topology *top_out) 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; U64 unconsumed_size = tex_shared->u2x_ring_write_pos-tex_shared->u2x_ring_read_pos;
if(unconsumed_size >= sizeof(*hash_out)+sizeof(*top_out)) if(unconsumed_size >= sizeof(*hash_out)+sizeof(*top_out))
@@ -281,7 +281,7 @@ ASYNC_WORK_DEF(tex_xfer_work)
//- rjf: take task //- rjf: take task
B32 got_task = 0; B32 got_task = 0;
OS_MutexScopeR(stripe->rw_mutex) MutexScopeR(stripe->rw_mutex)
{ {
for(TEX_Node *n = slot->first; n != 0; n = n->next) 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 //- 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) for(TEX_Node *n = slot->first; n != 0; n = n->next)
{ {
@@ -333,7 +333,7 @@ ASYNC_WORK_DEF(tex_xfer_work)
internal void internal void
tex_evictor_thread__entry_point(void *p) tex_evictor_thread__entry_point(void *p)
{ {
ThreadNameF("[tex] evictor thread"); ThreadNameF("tex_evictor_thread");
for(;;) for(;;)
{ {
U64 check_time_us = os_now_microseconds(); 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_Slot *slot = &tex_shared->slots[slot_idx];
TEX_Stripe *stripe = &tex_shared->stripes[stripe_idx]; TEX_Stripe *stripe = &tex_shared->stripes[stripe_idx];
B32 slot_has_work = 0; 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) 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) for(TEX_Node *n = slot->first, *next = 0; n != 0; n = next)
{ {
+1 -1
View File
@@ -100,7 +100,7 @@ struct TEX_Shared
Mutex u2x_ring_mutex; Mutex u2x_ring_mutex;
// rjf: evictor thread // rjf: evictor thread
OS_Handle evictor_thread; Thread evictor_thread;
}; };
//////////////////////////////// ////////////////////////////////