From 768755b0a4b17e26b12b50b4a4be9b156effc53a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 29 Sep 2025 16:38:57 -0700 Subject: [PATCH] equip conversion subprocesses with info to signal parent on completion, + plug into a wakeup thread, which can re-trigger the async wavefront. also fix duplicate line counts in text parsing --- src/base/base_entry_point.c | 2 +- src/dbg_info/dbg_info2.c | 43 ++++++++++++++++++++++++++++++- src/dbg_info/dbg_info2.h | 13 +++++++++- src/os/core/win32/os_core_win32.c | 2 +- src/raddbg/raddbg_main.c | 9 ++++--- src/text/text.c | 6 +---- 6 files changed, 62 insertions(+), 13 deletions(-) diff --git a/src/base/base_entry_point.c b/src/base/base_entry_point.c index 5037dbde..7411e32c 100644 --- a/src/base/base_entry_point.c +++ b/src/base/base_entry_point.c @@ -72,7 +72,7 @@ main_thread_base_entry_point(int arguments_count, char **arguments) di_init(); #endif #if defined(DBG_INFO2_H) && !defined(DI_INIT_MANUAL) - di2_init(); + di2_init(&cmdline); #endif #if defined(DEMON_CORE_H) && !defined(DMN_INIT_MANUAL) dmn_init(); diff --git a/src/dbg_info/dbg_info2.c b/src/dbg_info/dbg_info2.c index 70dafa8e..5a66d242 100644 --- a/src/dbg_info/dbg_info2.c +++ b/src/dbg_info/dbg_info2.c @@ -22,7 +22,7 @@ di2_key_match(DI2_Key a, DI2_Key b) //~ rjf: Main Layer Initialization internal void -di2_init(void) +di2_init(CmdLine *cmdline) { Arena *arena = arena_alloc(); di2_shared = push_array(arena, DI2_Shared, 1); @@ -41,6 +41,24 @@ di2_init(void) di2_shared->req_batches[idx].mutex = mutex_alloc(); di2_shared->req_batches[idx].arena = arena_alloc(); } + U64 signal_pid = 0; + String8 signal_pid_string = cmd_line_string(cmdline, str8_lit("signal_pid")); + B32 has_parent = 1; + if(!try_u64_from_str8_c_rules(signal_pid_string, &signal_pid)) + { + has_parent = 0; + signal_pid = os_get_process_info()->pid; + } + di2_shared->conversion_completion_signal_semaphore_name = str8f(arena, "conversion_completion_signal_pid_%I64u", signal_pid); + if(has_parent) + { + di2_shared->conversion_completion_signal_semaphore = semaphore_open(di2_shared->conversion_completion_signal_semaphore_name); + } + else + { + di2_shared->conversion_completion_signal_semaphore = semaphore_alloc(0, 65536, di2_shared->conversion_completion_signal_semaphore_name); + di2_shared->conversion_completion_signal_receiver_thread = thread_launch(di2_conversion_completion_signal_receiver_thread_entry_point, 0); + } } //////////////////////////////// @@ -607,6 +625,7 @@ di2_async_tick(void) str8_list_pushf(scratch.arena, ¶ms.cmd_line, "--rdi"); str8_list_pushf(scratch.arena, ¶ms.cmd_line, "--out:%S", rdi_path); str8_list_pushf(scratch.arena, ¶ms.cmd_line, "--thread_count:%I64u", t->thread_count); + str8_list_pushf(scratch.arena, ¶ms.cmd_line, "--signal_pid:%I64u", (U64)os_get_process_info()->pid); str8_list_pushf(scratch.arena, ¶ms.cmd_line, "%S", og_path); t->process = os_process_launch(¶ms); t->status = DI2_LoadTaskStatus_Active; @@ -770,3 +789,25 @@ di2_async_tick(void) scratch_end(scratch); } + +//////////////////////////////// +//~ rjf: Conversion Completion Signal Receiver Thread + +internal void +di2_signal_completion(void) +{ + semaphore_drop(di2_shared->conversion_completion_signal_semaphore); +} + +internal void +di2_conversion_completion_signal_receiver_thread_entry_point(void *p) +{ + ThreadNameF("di2_conversion_completion_signal_receiver_thread"); + for(;;) + { + if(semaphore_take(di2_shared->conversion_completion_signal_semaphore, max_U64)) + { + cond_var_broadcast(async_tick_start_cond_var); + } + } +} diff --git a/src/dbg_info/dbg_info2.h b/src/dbg_info/dbg_info2.h index 2e93cd70..6062a262 100644 --- a/src/dbg_info/dbg_info2.h +++ b/src/dbg_info/dbg_info2.h @@ -158,6 +158,11 @@ struct DI2_Shared DI2_LoadTask *free_load_task; U64 conversion_process_count; U64 conversion_thread_count; + + // rjf: conversion completion receiving thread + String8 conversion_completion_signal_semaphore_name; + Semaphore conversion_completion_signal_semaphore; + Thread conversion_completion_signal_receiver_thread; }; //////////////////////////////// @@ -174,7 +179,7 @@ internal B32 di2_key_match(DI2_Key a, DI2_Key b); //////////////////////////////// //~ rjf: Main Layer Initialization -internal void di2_init(void); +internal void di2_init(CmdLine *cmdline); //////////////////////////////// //~ rjf: Path * Timestamp Cache Submission & Lookup @@ -197,4 +202,10 @@ internal RDI_Parsed *di2_rdi_from_key(Access *access, DI2_Key key, B32 high_prio internal void di2_async_tick(void); +//////////////////////////////// +//~ rjf: Conversion Completion Signal Receiver Thread + +internal void di2_signal_completion(void); +internal void di2_conversion_completion_signal_receiver_thread_entry_point(void *p); + #endif // DBG_INFO2_H diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index d91b8088..a2e8cd9f 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -1300,7 +1300,7 @@ os_semaphore_open(String8 name) { Temp scratch = scratch_begin(0, 0); String16 name16 = str16_from_8(scratch.arena, name); - HANDLE handle = OpenSemaphoreW(SEMAPHORE_ALL_ACCESS , 0, (WCHAR *)name16.str); + HANDLE handle = OpenSemaphoreW(SEMAPHORE_ALL_ACCESS, 0, (WCHAR *)name16.str); Semaphore result = {(U64)handle}; scratch_end(scratch); return result; diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 14af7b95..4d7a2865 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -510,8 +510,8 @@ entry_point(CmdLine *cmd_line) String8 ipc_sender2main_lock_semaphore_name = push_str8f(scratch.arena, "_raddbg_ipc_sender2main_lock_semaphore_%i_", instance_pid); OS_Handle ipc_sender2main_shared_memory = os_shared_memory_alloc(IPC_SHARED_MEMORY_BUFFER_SIZE, ipc_sender2main_shared_memory_name); ipc_sender2main_shared_memory_base = (U8 *)os_shared_memory_view_open(ipc_sender2main_shared_memory, r1u64(0, IPC_SHARED_MEMORY_BUFFER_SIZE)); - ipc_sender2main_signal_semaphore = os_semaphore_alloc(0, 1, ipc_sender2main_signal_semaphore_name); - ipc_sender2main_lock_semaphore = os_semaphore_alloc(1, 1, ipc_sender2main_lock_semaphore_name); + ipc_sender2main_signal_semaphore = semaphore_alloc(0, 1, ipc_sender2main_signal_semaphore_name); + ipc_sender2main_lock_semaphore = semaphore_alloc(1, 1, ipc_sender2main_lock_semaphore_name); // rjf: set up cross-process main -> sender ring buffer String8 ipc_main2sender_shared_memory_name = push_str8f(scratch.arena, "_raddbg_ipc_main2sender_shared_memory_%i_", instance_pid); @@ -519,8 +519,8 @@ entry_point(CmdLine *cmd_line) String8 ipc_main2sender_lock_semaphore_name = push_str8f(scratch.arena, "_raddbg_ipc_main2sender_lock_semaphore_%i_", instance_pid); OS_Handle ipc_main2sender_shared_memory = os_shared_memory_alloc(IPC_SHARED_MEMORY_BUFFER_SIZE, ipc_main2sender_shared_memory_name); ipc_main2sender_shared_memory_base = (U8 *)os_shared_memory_view_open(ipc_main2sender_shared_memory, r1u64(0, IPC_SHARED_MEMORY_BUFFER_SIZE)); - ipc_main2sender_signal_semaphore = os_semaphore_alloc(0, 1, ipc_main2sender_signal_semaphore_name); - ipc_main2sender_lock_semaphore = os_semaphore_alloc(1, 1, ipc_main2sender_lock_semaphore_name); + ipc_main2sender_signal_semaphore = semaphore_alloc(0, 1, ipc_main2sender_signal_semaphore_name); + ipc_main2sender_lock_semaphore = semaphore_alloc(1, 1, ipc_main2sender_lock_semaphore_name); // rjf: set up ipc-receiver -> main thread ring buffer; launch signaler thread ipc_s2m_ring_mutex = mutex_alloc(); @@ -751,6 +751,7 @@ entry_point(CmdLine *cmd_line) case ExecMode_BinaryUtility: { rb_entry_point(cmd_line); + di2_signal_completion(); }break; //- rjf: help message box diff --git a/src/text/text.c b/src/text/text.c index dd59b33a..3ee0c191 100644 --- a/src/text/text.c +++ b/src/text/text.c @@ -2044,13 +2044,9 @@ txt_artifact_create(String8 key, U64 gen, U64 *requested_gen, B32 *retry_out) Rng1U64 range = lane_range(data.size); for EachInRange(idx, range) { - if(data.str[idx] == '\n' || data.str[idx] == '\r') + if(data.str[idx] == '\n') { lane_line_count += 1; - if(data.str[idx] == '\r') - { - idx += 1; - } } if(idx && idx%1000 == 0) {