From 0948e357c6a130e412a4d055ee7d50db6e5ff8f9 Mon Sep 17 00:00:00 2001 From: jacob Date: Mon, 14 Jul 2025 17:27:46 -0500 Subject: [PATCH] use jobs for resource watch --- src/incbin.c | 2 +- src/resource.c | 24 ++++++++++-------------- src/sys.h | 11 ++--------- src/sys_win32.c | 14 ++++++++------ 4 files changed, 21 insertions(+), 30 deletions(-) diff --git a/src/incbin.c b/src/incbin.c index 0ef9930b..98d3f9ad 100644 --- a/src/incbin.c +++ b/src/incbin.c @@ -28,7 +28,7 @@ INTERNAL BOOL CALLBACK enum_func(HMODULE module, LPCWSTR type, LPCWSTR wstr_entr struct arena_temp scratch = scratch_begin_no_conflict(); struct rc_search_params *params = (struct rc_search_params *)udata; struct string entry_name_lower = string_lower(scratch.arena, string_from_wstr_no_limit(scratch.arena, (LPWSTR)wstr_entry_name)); - params->found = false; + params->found = 0; params->data = STRING(0, 0); if (string_eq(entry_name_lower, params->name_lower)) { HRSRC hres = FindResourceW(module, wstr_entry_name, type); diff --git a/src/resource.c b/src/resource.c index 9216904f..9ff74486 100644 --- a/src/resource.c +++ b/src/resource.c @@ -23,11 +23,9 @@ GLOBAL struct { #endif #if RESOURCE_RELOADING - struct sys_thread *resource_watch_monitor_thread; - struct sys_thread *resource_watch_dispatch_thread; - struct sys_watch *watch; struct atomic32 watch_shutdown; + struct snc_counter watch_jobs_counter; struct snc_mutex watch_dispatcher_mutex; struct arena *watch_dispatcher_info_arena; @@ -45,8 +43,8 @@ GLOBAL struct { * ========================== */ #if RESOURCE_RELOADING -INTERNAL SYS_THREAD_DEF(resource_watch_monitor_thread_entry_point, _); -INTERNAL SYS_THREAD_DEF(resource_watch_dispatcher_thread_entry_point, _); +INTERNAL SYS_JOB_DEF(resource_watch_monitor_job, _); +INTERNAL SYS_JOB_DEF(resource_watch_dispatcher_job, _); INTERNAL SYS_EXIT_FUNC(resource_shutdown); #endif @@ -73,9 +71,9 @@ struct resource_startup_receipt resource_startup(void) G.watch_dispatcher_info_arena = arena_alloc(GIBI(64)); + sys_run(1, resource_watch_monitor_job, 0, SYS_POOL_FLOATING, SYS_PRIORITY_LOW, &G.watch_jobs_counter); + sys_run(1, resource_watch_dispatcher_job, 0, SYS_POOL_BACKGROUND, SYS_PRIORITY_LOW, &G.watch_jobs_counter); sys_on_exit(&resource_shutdown); - G.resource_watch_monitor_thread = sys_thread_alloc(resource_watch_monitor_thread_entry_point, 0, LIT("Resource watch monitor"), PROF_THREAD_GROUP_IO); - G.resource_watch_dispatch_thread = sys_thread_alloc(resource_watch_dispatcher_thread_entry_point, 0, LIT("Resource watch dispatcher"), PROF_THREAD_GROUP_IO); #endif @@ -166,9 +164,7 @@ INTERNAL SYS_EXIT_FUNC(resource_shutdown) sys_watch_wake(G.watch); snc_unlock(&lock); } - - sys_thread_wait_release(G.resource_watch_dispatch_thread); - sys_thread_wait_release(G.resource_watch_monitor_thread); + snc_counter_wait(&G.watch_jobs_counter); } void resource_register_watch_callback(resource_watch_callback *callback) @@ -184,14 +180,14 @@ void resource_register_watch_callback(resource_watch_callback *callback) snc_unlock(&lock); } -INTERNAL SYS_THREAD_DEF(resource_watch_monitor_thread_entry_point, _) +INTERNAL SYS_JOB_DEF(resource_watch_monitor_job, _) { (UNUSED)_; struct arena_temp scratch = scratch_begin_no_conflict(); while (!atomic32_fetch(&G.watch_shutdown)) { struct arena_temp temp = arena_temp_begin(scratch.arena); - struct sys_watch_info_list res = sys_watch_wait(temp.arena, G.watch); + struct sys_watch_info_list res = sys_watch_read_wait(temp.arena, G.watch); if (res.first && !atomic32_fetch(&G.watch_shutdown)) { struct snc_lock lock = snc_lock_e(&G.watch_dispatcher_mutex); { @@ -214,7 +210,7 @@ INTERNAL SYS_THREAD_DEF(resource_watch_monitor_thread_entry_point, _) } /* NOTE: We separate the responsibilities of monitoring directory changes - * & dispatching watch callbacks into two separate threads so that we can delay + * & dispatching watch callbacks into two separate jobs so that we can delay * the dispatch, allowing for deduplication of file modification notifications. */ #define WATCH_DISPATCHER_DELAY_SECONDS 0.050 @@ -234,7 +230,7 @@ INTERNAL SYS_JOB_DEF(resource_watch_callback_job, job) callback(name); } -INTERNAL SYS_THREAD_DEF(resource_watch_dispatcher_thread_entry_point, _) +INTERNAL SYS_JOB_DEF(resource_watch_dispatcher_job, _) { (UNUSED)_; struct arena_temp scratch = scratch_begin_no_conflict(); diff --git a/src/sys.h b/src/sys.h index c5c1c098..43bf8a51 100644 --- a/src/sys.h +++ b/src/sys.h @@ -1,13 +1,7 @@ #ifndef SYS_H #define SYS_H - - - - - - - +struct snc_counter; /* ========================== * * Exit @@ -87,7 +81,6 @@ struct sys_job_data { #define SYS_JOB_DEF(job_name, arg_name) void job_name(struct sys_job_data arg_name) typedef SYS_JOB_DEF(sys_job_func, job_data); -struct snc_counter; void sys_run(i32 count, sys_job_func *func, void *sig, enum sys_pool pool_kind, enum sys_priority priority, struct snc_counter *counter); /* ========================== * @@ -428,7 +421,7 @@ struct sys_watch *sys_watch_alloc(struct string path); void sys_watch_release(struct sys_watch *dw); -struct sys_watch_info_list sys_watch_wait(struct arena *arena, struct sys_watch *dw); +struct sys_watch_info_list sys_watch_read_wait(struct arena *arena, struct sys_watch *dw); void sys_watch_wake(struct sys_watch *dw); diff --git a/src/sys_win32.c b/src/sys_win32.c index 590a6a52..10fcb82a 100644 --- a/src/sys_win32.c +++ b/src/sys_win32.c @@ -181,9 +181,10 @@ struct alignas(64) fiber { /* ==================================================== */ char *name_cstr; /* 08 bytes */ /* ==================================================== */ - struct atomic32 wake_lock; /* 04 bytes (4 byte alignment) */ + struct atomic16 wake_lock; /* 02 bytes (4 byte alignment) */ i16 id; /* 02 bytes */ i16 parent_id; /* 02 bytes */ + i16 unyielding; /* 02 bytes */ /* ==================================================== */ u64 wait_addr; /* 08 bytes */ /* ==================================================== */ @@ -469,7 +470,7 @@ void sys_wait(void *addr, void *cmp, u32 size, i64 timeout_ns) { struct fiber *fiber = fiber_from_id(sys_current_fiber_id()); i16 parent_id = fiber->parent_id; - if (parent_id != 0) { + if (parent_id != 0 && !fiber->unyielding) { *fiber->yield_param = (struct yield_param) { .kind = YIELD_KIND_WAIT, .wait = { @@ -603,7 +604,7 @@ INTERNAL void wake_fibers_locked(i32 num_fibers, struct fiber **fibers) fiber->next_time_waiter = 0; } /* Unlock fiber */ - atomic32_fetch_set(&fiber->wake_lock, 0); + atomic16_fetch_set(&fiber->wake_lock, 0); } /* Unlock wait bins */ if (wait_time_bin != 0) tm_unlock(&wait_time_bin->lock); @@ -687,7 +688,7 @@ INTERNAL void wake_address(void *addr, i32 count) if (wait_addr_list) { fibers = arena_push_array_no_zero(scratch.arena, struct fiber *, wait_addr_list->num_waiters); for (struct fiber *fiber = fiber_from_id(wait_addr_list->first_waiter); fiber && num_fibers < count; fiber = fiber_from_id(fiber->next_addr_waiter)) { - if (atomic32_fetch_test_set(&fiber->wake_lock, 0, 1) == 0) { + if (atomic16_fetch_test_set(&fiber->wake_lock, 0, 1) == 0) { fibers[num_fibers] = fiber; ++num_fibers; } @@ -738,7 +739,7 @@ INTERNAL void wake_time(u64 time) /* Set waiter wake status & build fibers list */ fibers = arena_push_array_no_zero(scratch.arena, struct fiber *, wait_time_list->num_waiters); for (struct fiber *fiber = fiber_from_id(wait_time_list->first_waiter); fiber; fiber = fiber_from_id(fiber->next_time_waiter)) { - if (atomic32_fetch_test_set(&fiber->wake_lock, 0, 1) == 0) { + if (atomic16_fetch_test_set(&fiber->wake_lock, 0, 1) == 0) { fibers[num_fibers] = fiber; ++num_fibers; } @@ -1118,6 +1119,7 @@ INTERNAL SYS_THREAD_DEF(job_worker_entry, worker_ctx_arg) job_fiber->job_priority = job_priority; job_fiber->job_counter = job_counter; job_fiber->yield_param = &yield; + job_fiber->unyielding = 0; b32 done = 0; while (!done) { job_fiber_resume(job_fiber); @@ -2089,7 +2091,7 @@ void sys_watch_release(struct sys_watch *dw) snc_unlock(&lock); } -struct sys_watch_info_list sys_watch_wait(struct arena *arena, struct sys_watch *dw) +struct sys_watch_info_list sys_watch_read_wait(struct arena *arena, struct sys_watch *dw) { __prof; struct win32_watch *w32_watch = (struct win32_watch *)dw;