From f12b66c1ee6ad1c4e70bc8186c03b9bb573d8357 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 14 May 2025 13:27:10 -0700 Subject: [PATCH] sketch out asynchronous unwinding stuff --- project.4coder | 4 +-- src/ctrl/ctrl_core.c | 83 +++++++++++++++++++++++++++++++++++++++----- src/ctrl/ctrl_core.h | 53 ++++++++++++++++++---------- 3 files changed, 112 insertions(+), 28 deletions(-) diff --git a/project.4coder b/project.4coder index 5be24aab..32a1e737 100644 --- a/project.4coder +++ b/project.4coder @@ -55,8 +55,8 @@ commands = // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta tester", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: running target - .f3 = { .win = "pushd build && raddbg --user:dev.raddbg_user && popd", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - // .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + // .f3 = { .win = "pushd build && raddbg --user:dev.raddbg_user && popd", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f3 = { .win = "C:/devel/raddebugger/build/raddbg.exe --capture --user:C:/devel/raddebugger/build/local_dev.raddbg_user --project:C:/devel/raddebugger/build/local_dev.raddbg_project", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f3 = { .win = "wsl_launch /mnt/c/devel/raddebugger/build/raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 6b14633f..795e8dfc 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1432,14 +1432,14 @@ ctrl_init(void) ctrl_state->thread_reg_cache.stripes[idx].arena = arena_alloc(); ctrl_state->thread_reg_cache.stripes[idx].rw_mutex = os_rw_mutex_alloc(); } - ctrl_state->thread_unwind_cache.slots_count = 1024; - ctrl_state->thread_unwind_cache.slots = push_array(arena, CTRL_ThreadUnwindCacheSlot, ctrl_state->thread_unwind_cache.slots_count); - ctrl_state->thread_unwind_cache.stripes_count = os_get_system_info()->logical_processor_count; - ctrl_state->thread_unwind_cache.stripes = push_array(arena, CTRL_ThreadUnwindCacheStripe, ctrl_state->thread_unwind_cache.stripes_count); - for(U64 idx = 0; idx < ctrl_state->thread_unwind_cache.stripes_count; idx += 1) + ctrl_state->unwind_cache.slots_count = 1024; + ctrl_state->unwind_cache.slots = push_array(arena, CTRL_UnwindCacheSlot, ctrl_state->unwind_cache.slots_count); + ctrl_state->unwind_cache.stripes_count = os_get_system_info()->logical_processor_count; + ctrl_state->unwind_cache.stripes = push_array(arena, CTRL_UnwindCacheStripe, ctrl_state->unwind_cache.stripes_count); + for(U64 idx = 0; idx < ctrl_state->unwind_cache.stripes_count; idx += 1) { - ctrl_state->thread_unwind_cache.stripes[idx].arena = arena_alloc(); - ctrl_state->thread_unwind_cache.stripes[idx].rw_mutex = os_rw_mutex_alloc(); + ctrl_state->unwind_cache.stripes[idx].arena = arena_alloc(); + ctrl_state->unwind_cache.stripes[idx].rw_mutex = os_rw_mutex_alloc(); } ctrl_state->module_image_info_cache.slots_count = 1024; ctrl_state->module_image_info_cache.slots = push_array(arena, CTRL_ModuleImageInfoCacheSlot, ctrl_state->module_image_info_cache.slots_count); @@ -1484,6 +1484,10 @@ ctrl_init(void) ctrl_state->u2ms_ring_base = push_array(arena, U8, ctrl_state->u2ms_ring_size); ctrl_state->u2ms_ring_mutex = os_mutex_alloc(); ctrl_state->u2ms_ring_cv = os_condition_variable_alloc(); + ctrl_state->u2uw_ring_size = KB(64); + ctrl_state->u2uw_ring_base = push_array(arena, U8, ctrl_state->u2uw_ring_size); + ctrl_state->u2uw_ring_mutex = os_mutex_alloc(); + ctrl_state->u2uw_ring_cv = os_condition_variable_alloc(); ctrl_state->ctrl_thread_log = log_alloc(); ctrl_state->ctrl_thread = os_thread_launch(ctrl_thread__entry_point, 0, 0); } @@ -6334,7 +6338,7 @@ ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) } //////////////////////////////// -//~ rjf: Memory-Stream-Thread-Only Functions +//~ rjf: Asynchronous Memory Streaming Functions //- rjf: user -> memory stream communication @@ -6545,5 +6549,68 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work) os_condition_variable_broadcast(process_stripe->cv); ProfEnd(); ProfEnd(); + return 0; +} + +//////////////////////////////// +//~ rjf: Asynchronous Unwinding Functions + +//- rjf: user -> memory stream communication + +internal B32 +ctrl_u2uw_enqueue_req(CTRL_Handle thread, U64 endt_us) +{ + B32 good = 0; + OS_MutexScope(ctrl_state->u2uw_ring_mutex) for(;;) + { + U64 unconsumed_size = ctrl_state->u2uw_ring_write_pos - ctrl_state->u2uw_ring_read_pos; + U64 available_size = ctrl_state->u2uw_ring_size - unconsumed_size; + if(available_size >= sizeof(thread)) + { + good = 1; + ctrl_state->u2uw_ring_write_pos += ring_write_struct(ctrl_state->u2uw_ring_base, ctrl_state->u2uw_ring_size, ctrl_state->u2uw_ring_write_pos, &thread); + break; + } + if(os_now_microseconds() >= endt_us) + { + break; + } + os_condition_variable_wait(ctrl_state->u2uw_ring_cv, ctrl_state->u2uw_ring_mutex, endt_us); + } + if(good) + { + os_condition_variable_broadcast(ctrl_state->u2uw_ring_cv); + } + return good; +} + +internal void +ctrl_u2uw_dequeue_req(CTRL_Handle *out_thread) +{ + OS_MutexScope(ctrl_state->u2uw_ring_mutex) for(;;) + { + U64 unconsumed_size = ctrl_state->u2uw_ring_write_pos - ctrl_state->u2uw_ring_read_pos; + if(unconsumed_size >= sizeof(*out_thread)) + { + ctrl_state->u2uw_ring_read_pos += ring_read_struct(ctrl_state->u2uw_ring_base, ctrl_state->u2uw_ring_size, ctrl_state->u2uw_ring_read_pos, out_thread); + break; + } + os_condition_variable_wait(ctrl_state->u2uw_ring_cv, ctrl_state->u2uw_ring_mutex, max_U64); + } + os_condition_variable_broadcast(ctrl_state->u2uw_ring_cv); +} + +//- rjf: entry point + +ASYNC_WORK_DEF(ctrl_unwind_work) +{ + CTRL_UnwindCache *cache = &ctrl_state->unwind_cache; + + //- rjf: get next request + CTRL_Handle thread_handle = {0}; + ctrl_u2uw_dequeue_req(&thread_handle); + + + return 0; } diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 5304759e..cbec99ca 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -594,13 +594,13 @@ struct CTRL_ThreadRegCache }; //////////////////////////////// -//~ rjf: Thread Unwind Cache Types +//~ rjf: Unwind Cache Types -typedef struct CTRL_ThreadUnwindCacheNode CTRL_ThreadUnwindCacheNode; -struct CTRL_ThreadUnwindCacheNode +typedef struct CTRL_UnwindCacheNode CTRL_UnwindCacheNode; +struct CTRL_UnwindCacheNode { - CTRL_ThreadUnwindCacheNode *next; - CTRL_ThreadUnwindCacheNode *prev; + CTRL_UnwindCacheNode *next; + CTRL_UnwindCacheNode *prev; Arena *arena; CTRL_Handle thread; U64 reg_gen; @@ -608,27 +608,27 @@ struct CTRL_ThreadUnwindCacheNode CTRL_Unwind unwind; }; -typedef struct CTRL_ThreadUnwindCacheSlot CTRL_ThreadUnwindCacheSlot; -struct CTRL_ThreadUnwindCacheSlot +typedef struct CTRL_UnwindCacheSlot CTRL_UnwindCacheSlot; +struct CTRL_UnwindCacheSlot { - CTRL_ThreadUnwindCacheNode *first; - CTRL_ThreadUnwindCacheNode *last; + CTRL_UnwindCacheNode *first; + CTRL_UnwindCacheNode *last; }; -typedef struct CTRL_ThreadUnwindCacheStripe CTRL_ThreadUnwindCacheStripe; -struct CTRL_ThreadUnwindCacheStripe +typedef struct CTRL_UnwindCacheStripe CTRL_UnwindCacheStripe; +struct CTRL_UnwindCacheStripe { Arena *arena; OS_Handle rw_mutex; }; -typedef struct CTRL_ThreadUnwindCache CTRL_ThreadUnwindCache; -struct CTRL_ThreadUnwindCache +typedef struct CTRL_UnwindCache CTRL_UnwindCache; +struct CTRL_UnwindCache { U64 slots_count; - CTRL_ThreadUnwindCacheSlot *slots; + CTRL_UnwindCacheSlot *slots; U64 stripes_count; - CTRL_ThreadUnwindCacheStripe *stripes; + CTRL_UnwindCacheStripe *stripes; }; //////////////////////////////// @@ -724,7 +724,7 @@ struct CTRL_State // rjf: caches CTRL_ProcessMemoryCache process_memory_cache; CTRL_ThreadRegCache thread_reg_cache; - CTRL_ThreadUnwindCache thread_unwind_cache; + CTRL_UnwindCache unwind_cache; CTRL_ModuleImageInfoCache module_image_info_cache; // rjf: user -> ctrl msg ring buffer @@ -768,6 +768,14 @@ struct CTRL_State U64 u2ms_ring_read_pos; OS_Handle u2ms_ring_mutex; OS_Handle u2ms_ring_cv; + + // rjf: user -> unwind ring buffer + U64 u2uw_ring_size; + U8 *u2uw_ring_base; + U64 u2uw_ring_write_pos; + U64 u2uw_ring_read_pos; + OS_Handle u2uw_ring_mutex; + OS_Handle u2uw_ring_cv; }; //////////////////////////////// @@ -1039,7 +1047,7 @@ internal void ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg); internal void ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg); //////////////////////////////// -//~ rjf: Memory-Stream Thread Functions +//~ rjf: Asynchronous Memory Streaming Functions //- rjf: user -> memory stream communication internal B32 ctrl_u2ms_enqueue_req(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us); @@ -1047,6 +1055,15 @@ internal void ctrl_u2ms_dequeue_req(CTRL_Handle *out_process, Rng1U64 *out_vaddr //- rjf: entry point ASYNC_WORK_DEF(ctrl_mem_stream_work); -internal void ctrl_mem_stream_thread__entry_point(void *p); + +//////////////////////////////// +//~ rjf: Asynchronous Unwinding Functions + +//- rjf: user -> memory stream communication +internal B32 ctrl_u2uw_enqueue_req(CTRL_Handle thread, U64 endt_us); +internal void ctrl_u2uw_dequeue_req(CTRL_Handle *out_thread); + +//- rjf: entry point +ASYNC_WORK_DEF(ctrl_unwind_work); #endif // CTRL_CORE_H