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