From 67eede75138644e5a92f08f06711f901ad05692e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 25 Apr 2024 09:37:16 -0700 Subject: [PATCH] hot-reloading for dasm_cache, in case of filesystem changes; file stream layer -> expose filesystem-wide generation number, for very coarse-grained generation number to gracefully depend on filesystem changes passively --- src/dasm_cache/dasm_cache.c | 40 +++++++++++++++++++++++++++++------ src/dasm_cache/dasm_cache.h | 13 ++++++++---- src/df/gfx/df_gfx.c | 2 +- src/file_stream/file_stream.c | 14 ++++++++++++ src/file_stream/file_stream.h | 6 ++++++ src/raddbg/raddbg.c | 1 + src/text_cache/text_cache.c | 2 +- 7 files changed, 66 insertions(+), 12 deletions(-) diff --git a/src/dasm_cache/dasm_cache.c b/src/dasm_cache/dasm_cache.c index 24361e69..6400dadc 100644 --- a/src/dasm_cache/dasm_cache.c +++ b/src/dasm_cache/dasm_cache.c @@ -118,7 +118,7 @@ dasm_init(void) { dasm_shared->parse_threads[idx] = os_launch_thread(dasm_parse_thread__entry_point, (void *)idx, 0); } - dasm_shared->evictor_thread = os_launch_thread(dasm_evictor_thread__entry_point, 0, 0); + dasm_shared->evictor_detector_thread = os_launch_thread(dasm_evictor_detector_thread__entry_point, 0, 0); } //////////////////////////////// @@ -360,6 +360,7 @@ dasm_parse_thread__entry_point(void *p) U128 hash = {0}; DASM_Params params = {0}; dasm_u2p_dequeue_req(scratch.arena, &hash, ¶ms); + U64 change_gen = fs_change_gen(); HS_Scope *hs_scope = hs_scope_open(); DBGI_Scope *dbgi_scope = dbgi_scope_open(); TXT_Scope *txt_scope = txt_scope_open(); @@ -613,6 +614,14 @@ dasm_parse_thread__entry_point(void *p) { n->info_arena = info_arena; MemoryCopyStruct(&n->info, &info); + if(dbgi != &dbgi_parse_nil && params.style_flags & (DASM_StyleFlag_SourceLines|DASM_StyleFlag_SourceFilesNames)) + { + n->change_gen = change_gen; + } + else + { + n->change_gen = 0; + } ins_atomic_u32_eval_assign(&n->is_working, 0); ins_atomic_u64_inc_eval(&n->load_count); break; @@ -628,18 +637,21 @@ dasm_parse_thread__entry_point(void *p) } //////////////////////////////// -//~ rjf: Evictor Threads +//~ rjf: Evictor/Detector Thread internal void -dasm_evictor_thread__entry_point(void *p) +dasm_evictor_detector_thread__entry_point(void *p) { - ThreadNameF("[dasm] evictor thread"); + ThreadNameF("[dasm] evictor/detector thread"); for(;;) { + U64 change_gen = fs_change_gen(); U64 check_time_us = os_now_microseconds(); U64 check_time_user_clocks = dasm_user_clock_idx(); U64 evict_threshold_us = 10*1000000; + U64 retry_threshold_us = 1*1000000; U64 evict_threshold_user_clocks = 10; + U64 retry_threshold_user_clocks = 10; for(U64 slot_idx = 0; slot_idx < dasm_shared->slots_count; slot_idx += 1) { U64 stripe_idx = slot_idx%dasm_shared->stripes_count; @@ -659,6 +671,13 @@ dasm_evictor_thread__entry_point(void *p) slot_has_work = 1; break; } + if(n->change_gen != 0 && n->change_gen != change_gen && + n->last_time_requested_us+retry_threshold_us <= check_time_us && + n->last_user_clock_idx_requested+retry_threshold_user_clocks <= check_time_user_clocks) + { + slot_has_work = 1; + break; + } } } if(slot_has_work) OS_MutexScopeW(stripe->rw_mutex) @@ -679,10 +698,19 @@ dasm_evictor_thread__entry_point(void *p) } SLLStackPush(stripe->free_node, n); } + if(n->change_gen != 0 && n->change_gen != change_gen && + n->last_time_requested_us+retry_threshold_us <= check_time_us && + n->last_user_clock_idx_requested+retry_threshold_user_clocks <= check_time_user_clocks) + { + if(dasm_u2p_enqueue_req(n->hash, &n->params, max_U64)) + { + n->last_time_requested_us = os_now_microseconds(); + n->last_user_clock_idx_requested = check_time_user_clocks; + } + } } } - os_sleep_milliseconds(5); } - os_sleep_milliseconds(1000); + os_sleep_milliseconds(100); } } diff --git a/src/dasm_cache/dasm_cache.h b/src/dasm_cache/dasm_cache.h index 9b4765d9..3e5d4e9f 100644 --- a/src/dasm_cache/dasm_cache.h +++ b/src/dasm_cache/dasm_cache.h @@ -99,6 +99,9 @@ struct DASM_Node U128 hash; DASM_Params params; + // rjf: generations + U64 change_gen; + // rjf: value Arena *info_arena; DASM_Info info; @@ -109,6 +112,8 @@ struct DASM_Node U64 last_time_touched_us; U64 last_user_clock_idx_touched; U64 load_count; + U64 last_time_requested_us; + U64 last_user_clock_idx_requested; }; typedef struct DASM_Slot DASM_Slot; @@ -184,8 +189,8 @@ struct DASM_Shared U64 parse_thread_count; OS_Handle *parse_threads; - // rjf: evictor thread - OS_Handle evictor_thread; + // rjf: evictor/detector thread + OS_Handle evictor_detector_thread; }; //////////////////////////////// @@ -239,8 +244,8 @@ internal void dasm_u2p_dequeue_req(Arena *arena, U128 *hash_out, DASM_Params *pa internal void dasm_parse_thread__entry_point(void *p); //////////////////////////////// -//~ rjf: Evictor Threads +//~ rjf: Evictor/Detector Thread -internal void dasm_evictor_thread__entry_point(void *p); +internal void dasm_evictor_detector_thread__entry_point(void *p); #endif // DASM_CACHE_H diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 7d2b363f..cf6f393d 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -11697,7 +11697,7 @@ df_gfx_begin_frame(Arena *arena, DF_CmdList *cmds) } //- rjf: capture is active? -> keep rendering - if(ProfIsCapturing()) + if(ProfIsCapturing() || DEV_telemetry_capture) { df_gfx_request_frame(); } diff --git a/src/file_stream/file_stream.c b/src/file_stream/file_stream.c index e1b411e5..6f1e63be 100644 --- a/src/file_stream/file_stream.c +++ b/src/file_stream/file_stream.c @@ -10,6 +10,7 @@ fs_init(void) Arena *arena = arena_alloc(); fs_shared = push_array(arena, FS_Shared, 1); fs_shared->arena = arena; + fs_shared->change_gen = 1; fs_shared->slots_count = 1024; fs_shared->stripes_count = os_logical_core_count(); fs_shared->slots = push_array(arena, FS_Slot, fs_shared->slots_count); @@ -33,6 +34,15 @@ fs_init(void) fs_shared->detector_thread = os_launch_thread(fs_detector_thread__entry_point, 0, 0); } +//////////////////////////////// +//~ rjf: Change Generation + +internal U64 +fs_change_gen(void) +{ + return ins_atomic_u64_eval(&fs_shared->change_gen); +} + //////////////////////////////// //~ rjf: Cache Interaction @@ -220,6 +230,10 @@ fs_streamer_thread__entry_point(void *p) } if(node != 0) { + if(node->timestamp != 0) + { + ins_atomic_u64_inc_eval(&fs_shared->change_gen); + } if(post_props.modified == pre_props.modified) { node->timestamp = post_props.modified; diff --git a/src/file_stream/file_stream.h b/src/file_stream/file_stream.h index 078b3547..66f88f1f 100644 --- a/src/file_stream/file_stream.h +++ b/src/file_stream/file_stream.h @@ -38,6 +38,7 @@ typedef struct FS_Shared FS_Shared; struct FS_Shared { Arena *arena; + U64 change_gen; // rjf: path info cache U64 slots_count; @@ -71,6 +72,11 @@ global FS_Shared *fs_shared = 0; internal void fs_init(void); +//////////////////////////////// +//~ rjf: Change Generation + +internal U64 fs_change_gen(void); + //////////////////////////////// //~ rjf: Cache Interaction diff --git a/src/raddbg/raddbg.c b/src/raddbg/raddbg.c index 9d58a847..218b7fa8 100644 --- a/src/raddbg/raddbg.c +++ b/src/raddbg/raddbg.c @@ -26,6 +26,7 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data) //- rjf: tick cache layers txt_user_clock_tick(); + dasm_user_clock_tick(); geo_user_clock_tick(); tex_user_clock_tick(); diff --git a/src/text_cache/text_cache.c b/src/text_cache/text_cache.c index 32e953bb..18e21dc5 100644 --- a/src/text_cache/text_cache.c +++ b/src/text_cache/text_cache.c @@ -1169,7 +1169,7 @@ txt_token_array_from_string__disasm_x64_intel(Arena *arena, U64 *bytes_processed active_token_kind = TXT_TokenKind_Whitespace; advance = 1; } - else if(byte == '>') + else if(byte == '>' && brace_nest == 0 && paren_nest == 0) { active_token_start_off = off; active_token_kind = TXT_TokenKind_Comment;