diff --git a/src/base/base_entry_point.c b/src/base/base_entry_point.c index bef24678..d2d1e966 100644 --- a/src/base/base_entry_point.c +++ b/src/base/base_entry_point.c @@ -195,6 +195,9 @@ async_thread_entry_point(void *params) #endif #if defined(FILE_STREAM_H) fs_tick(); +#endif +#if defined(DASM_CACHE_H) + dasm_tick(); #endif cond_var_broadcast(async_tick_stop_cond_var); } diff --git a/src/dasm_cache/dasm_cache.c b/src/dasm_cache/dasm_cache.c index 319e5127..c6b10a54 100644 --- a/src/dasm_cache/dasm_cache.c +++ b/src/dasm_cache/dasm_cache.c @@ -273,11 +273,8 @@ dasm_init(void) dasm_shared->stripes[idx].rw_mutex = rw_mutex_alloc(); dasm_shared->stripes[idx].cv = cond_var_alloc(); } - dasm_shared->u2p_ring_size = KB(64); - 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 = thread_launch(dasm_evictor_detector_thread__entry_point, 0); + dasm_shared->req_mutex = mutex_alloc(); + dasm_shared->req_arena = arena_alloc(); } //////////////////////////////// @@ -351,42 +348,27 @@ dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params) DASM_Slot *slot = &dasm_shared->slots[slot_idx]; DASM_Stripe *stripe = &dasm_shared->stripes[stripe_idx]; - //- rjf: try to get existing results - B32 found = 0; - MutexScopeR(stripe->rw_mutex) + //- rjf: try to get existing results; create node if needed + for(B32 write_mode = 0; write_mode <= 1; write_mode += 1) { - for(DASM_Node *n = slot->first; n != 0; n = n->next) - { - if(u128_match(hash, n->hash) && dasm_params_match(params, &n->params)) - { - MemoryCopyStruct(&info, &n->info); - found = 1; - dasm_scope_touch_node__stripe_r_guarded(scope, n); - break; - } - } - } - - //- rjf: miss -> kick off work to fill cache - if(!found) - { - B32 node_is_new = 0; - U64 *node_working_count = 0; - HS_Root root = {0}; - MutexScopeW(stripe->rw_mutex) + B32 found = 0; + RWMutexScope(stripe->rw_mutex, write_mode) { + // rjf: find existing node DASM_Node *node = 0; for(DASM_Node *n = slot->first; n != 0; n = n->next) { if(u128_match(hash, n->hash) && dasm_params_match(params, &n->params)) { node = n; + found = 1; break; } } - if(node == 0) + + // rjf: [write mode] allocate node if needed, and kick off request + if(write_mode && node == 0) { - // rjf: allocate node node = stripe->free_node; if(node) { @@ -397,26 +379,36 @@ dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params) node = push_array_no_zero(stripe->arena, DASM_Node, 1); } MemoryZeroStruct(node); - - // rjf: fill node DLLPushBack(slot->first, slot->last, node); node->hash = hash; MemoryCopyStruct(&node->params, params); node->root = hs_root_alloc(); // TODO(rjf): need to make this releasable - currently all exe_paths just leak node->params.dbgi_key = di_key_copy(stripe->arena, &node->params.dbgi_key); - - // rjf: gather work kickoff params - node_is_new = 1; ins_atomic_u64_inc_eval(&node->working_count); - node_working_count = &node->working_count; - root = node->root; + MutexScope(dasm_shared->req_mutex) + { + DASM_RequestNode *req_n = push_array(dasm_shared->req_arena, DASM_RequestNode, 1); + SLLQueuePush(dasm_shared->first_req, dasm_shared->last_req, req_n); + dasm_shared->req_count += 1; + req_n->v.root = node->root; + req_n->v.hash = hash; + MemoryCopyStruct(&req_n->v.params, params); + req_n->v.params.dbgi_key = di_key_copy(dasm_shared->req_arena, &req_n->v.params.dbgi_key); + } + cond_var_broadcast(async_tick_start_cond_var); + } + + // rjf: nonzero node, request if needed - touch & return results + if(node != 0) + { + dasm_scope_touch_node__stripe_r_guarded(scope, node); + MemoryCopyStruct(&info, &node->info); } } - if(node_is_new) + if(found) { - dasm_u2p_enqueue_req(root, hash, params, max_U64); - async_push_work(dasm_parse_work, .working_counter = node_working_count); + break; } } } @@ -446,14 +438,88 @@ dasm_info_from_key_params(DASM_Scope *scope, HS_Key key, DASM_Params *params, U1 //////////////////////////////// //~ rjf: Ticks -#if 0 internal void dasm_tick(void) { + ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); - HS_Scope *hs_scope = hs_scope_open(); - DI_Scope *di_scope = di_scope_open(); - TXT_Scope *txt_scope = txt_scope_open(); + + //- rjf: do detection pass + { + U64 change_gen = fs_change_gen(); + U64 check_time_us = os_now_microseconds(); + U64 check_time_user_clocks = update_tick_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; + Rng1U64 range = lane_range(dasm_shared->slots_count); + for EachInRange(slot_idx, range) + { + 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]; + B32 slot_has_work = 0; + MutexScopeR(stripe->rw_mutex) + { + for(DASM_Node *n = slot->first; n != 0; n = n->next) + { + if(n->scope_ref_count == 0 && + n->last_time_touched_us+evict_threshold_us <= check_time_us && + n->last_user_clock_idx_touched+evict_threshold_user_clocks <= check_time_user_clocks && + ins_atomic_u64_eval(&n->working_count) == 0) + { + 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) MutexScopeW(stripe->rw_mutex) + { + for(DASM_Node *n = slot->first, *next = 0; n != 0; n = next) + { + next = n->next; + if(n->scope_ref_count == 0 && + n->last_time_touched_us+evict_threshold_us <= check_time_us && + n->last_user_clock_idx_touched+evict_threshold_user_clocks <= check_time_user_clocks && + ins_atomic_u64_eval(&n->working_count) == 0) + { + DLLRemove(slot->first, slot->last, n); + if(n->info_arena != 0) + { + arena_release(n->info_arena); + } + 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) + { + MutexScope(dasm_shared->req_mutex) + { + DASM_RequestNode *req_n = push_array(dasm_shared->req_arena, DASM_RequestNode, 1); + SLLQueuePush(dasm_shared->first_req, dasm_shared->last_req, req_n); + dasm_shared->req_count += 1; + req_n->v.root = n->root; + req_n->v.hash = n->hash; + req_n->v.params = n->params; + req_n->v.params.dbgi_key = di_key_copy(dasm_shared->req_arena, &req_n->v.params.dbgi_key); + } + n->last_time_requested_us = os_now_microseconds(); + n->last_user_clock_idx_requested = check_time_user_clocks; + ins_atomic_u64_inc_eval(&n->working_count); + } + } + } + } + } //- rjf: gather all requests local_persist DASM_Request *reqs = 0; @@ -479,7 +545,12 @@ dasm_tick(void) Rng1U64 range = lane_range(reqs_count); for EachInRange(req_idx, range) { + HS_Scope *hs_scope = hs_scope_open(); + DI_Scope *di_scope = di_scope_open(); + TXT_Scope *txt_scope = txt_scope_open(); + //- rjf: unpack + B32 stale = 0; DASM_Request *r = &reqs[req_idx]; HS_Root root = r->root; U128 hash = r->hash; @@ -497,6 +568,7 @@ dasm_tick(void) { rdi = di_rdi_from_key(di_scope, ¶ms.dbgi_key, 1, 0); } + stale = (stale || (rdi == &rdi_parsed_nil)); //- rjf: data * arch * addr * dbg -> decode artifacts DASM_LineChunkList line_list = {0}; @@ -572,15 +644,8 @@ dasm_tick(void) TXT_LangKind lang_kind = txt_lang_kind_from_extension(file_normalized_full_path); U64 endt_us = max_U64; U128 hash = {0}; - TXT_TextInfo text_info = {0}; - for(;os_now_microseconds() <= endt_us;) - { - text_info = txt_text_info_from_key_lang(txt_scope, key, lang_kind, &hash); - if(!u128_match(hash, u128_zero())) - { - break; - } - } + TXT_TextInfo text_info = txt_text_info_from_key_lang(txt_scope, key, lang_kind, &hash); + stale = (stale || u128_match(hash, u128_zero())); if(0 < line->line_num && line->line_num < text_info.lines_count) { String8 data = hs_data_from_hash(hs_scope, hash); @@ -657,6 +722,7 @@ dasm_tick(void) //- rjf: artifacts -> value bundle Arena *info_arena = 0; DASM_Info info = {0}; + if(!stale) { //- rjf: produce joined text Arena *text_arena = arena_alloc(); @@ -677,7 +743,7 @@ dasm_tick(void) } //- rjf: commit results to cache - RWMutexScope(stripe->rw_mutex, 1) + if(!stale) RWMutexScope(stripe->rw_mutex, 1) { for(DASM_Node *n = slot->first; n != 0; n = n->next) { @@ -693,401 +759,29 @@ dasm_tick(void) { n->change_gen = 0; } + ins_atomic_u64_dec_eval(&n->working_count); break; } } } - } - - txt_scope_close(txt_scope); - di_scope_close(di_scope); - hs_scope_close(hs_scope); - scratch_end(scratch); -} -#endif - -//////////////////////////////// -//~ rjf: Parse Threads - -internal B32 -dasm_u2p_enqueue_req(HS_Root root, U128 hash, DASM_Params *params, U64 endt_us) -{ - B32 good = 0; - 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; - if(available_size >= sizeof(root)+sizeof(hash)+sizeof(U64)+sizeof(Arch)+sizeof(DASM_StyleFlags)+sizeof(DASM_Syntax)+sizeof(U64)+sizeof(U64)+params->dbgi_key.path.size+sizeof(U64)) - { - good = 1; - dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, &root); - dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, &hash); - dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, ¶ms->vaddr); - dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, ¶ms->arch); - dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, ¶ms->style_flags); - dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, ¶ms->syntax); - dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, ¶ms->base_vaddr); - dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, ¶ms->dbgi_key.path.size); - dasm_shared->u2p_ring_write_pos += ring_write(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, params->dbgi_key.path.str, params->dbgi_key.path.size); - dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, ¶ms->dbgi_key.min_timestamp); - break; - } - if(os_now_microseconds() >= endt_us) - { - break; - } - cond_var_wait(dasm_shared->u2p_ring_cv, dasm_shared->u2p_ring_mutex, endt_us); - } - if(good) - { - cond_var_broadcast(dasm_shared->u2p_ring_cv); - } - return good; -} - -internal void -dasm_u2p_dequeue_req(Arena *arena, HS_Root *root_out, U128 *hash_out, DASM_Params *params_out) -{ - 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)) - { - dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, root_out); - dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, hash_out); - dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, ¶ms_out->vaddr); - dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, ¶ms_out->arch); - dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, ¶ms_out->style_flags); - dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, ¶ms_out->syntax); - dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, ¶ms_out->base_vaddr); - dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, ¶ms_out->dbgi_key.path.size); - params_out->dbgi_key.path.str = push_array(arena, U8, params_out->dbgi_key.path.size); - dasm_shared->u2p_ring_read_pos += ring_read(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, params_out->dbgi_key.path.str, params_out->dbgi_key.path.size); - dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, ¶ms_out->dbgi_key.min_timestamp); - break; - } - cond_var_wait(dasm_shared->u2p_ring_cv, dasm_shared->u2p_ring_mutex, max_U64); - } - cond_var_broadcast(dasm_shared->u2p_ring_cv); -} - -ASYNC_WORK_DEF(dasm_parse_work) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(0, 0); - HS_Scope *hs_scope = hs_scope_open(); - DI_Scope *di_scope = di_scope_open(); - TXT_Scope *txt_scope = txt_scope_open(); - - //- rjf: get next request - HS_Root root = {0}; - U128 hash = {0}; - DASM_Params params = {0}; - dasm_u2p_dequeue_req(scratch.arena, &root, &hash, ¶ms); - U64 change_gen = fs_change_gen(); - - //- rjf: unpack hash - U64 slot_idx = hash.u64[1]%dasm_shared->slots_count; - 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]; - - //- rjf: get dbg info - RDI_Parsed *rdi = &rdi_parsed_nil; - if(params.dbgi_key.path.size != 0) - { - rdi = di_rdi_from_key(di_scope, ¶ms.dbgi_key, 1, max_U64); - } - - //- rjf: hash -> data - String8 data = hs_data_from_hash(hs_scope, hash); - - //- rjf: data * arch * addr * dbg -> decode artifacts - DASM_LineChunkList line_list = {0}; - String8List inst_strings = {0}; - { - switch(params.arch) - { - default:{}break; - - //- rjf: x86/x64 decoding - case Arch_x64: - case Arch_x86: - { - // rjf: disassemble - RDI_SourceFile *last_file = &rdi_nil_element_union.source_file; - RDI_Line *last_line = 0; - for(U64 off = 0; off < data.size;) - { - // rjf: disassemble one instruction - DASM_Inst inst = dasm_inst_from_code(scratch.arena, params.arch, params.vaddr+off, str8_skip(data, off), params.syntax); - if(inst.size == 0) - { - break; - } - - // rjf: push strings derived from voff -> line info - if(params.style_flags & (DASM_StyleFlag_SourceFilesNames|DASM_StyleFlag_SourceLines)) - { - if(rdi != &rdi_parsed_nil) - { - U64 voff = (params.vaddr+off) - params.base_vaddr; - U32 unit_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_UnitVMap, voff); - RDI_Unit *unit = rdi_element_from_name_idx(rdi, Units, unit_idx); - RDI_LineTable *line_table = rdi_element_from_name_idx(rdi, LineTables, unit->line_table_idx); - RDI_ParsedLineTable unit_line_info = {0}; - rdi_parsed_from_line_table(rdi, line_table, &unit_line_info); - U64 line_info_idx = rdi_line_info_idx_from_voff(&unit_line_info, voff); - if(line_info_idx < unit_line_info.count) - { - RDI_Line *line = &unit_line_info.lines[line_info_idx]; - RDI_SourceFile *file = rdi_element_from_name_idx(rdi, SourceFiles, line->file_idx); - String8 file_normalized_full_path = {0}; - file_normalized_full_path.str = rdi_string_from_idx(rdi, file->normal_full_path_string_idx, &file_normalized_full_path.size); - if(file != last_file) - { - if(params.style_flags & DASM_StyleFlag_SourceFilesNames && - file->normal_full_path_string_idx != 0 && file_normalized_full_path.size != 0) - { - String8 inst_string = push_str8f(scratch.arena, "> %S", file_normalized_full_path); - DASM_Line inst = {u32_from_u64_saturate(off), DASM_LineFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count, - inst_strings.total_size + inst_strings.node_count + inst_string.size)}; - dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &inst); - str8_list_push(scratch.arena, &inst_strings, inst_string); - } - if(params.style_flags & DASM_StyleFlag_SourceFilesNames && file->normal_full_path_string_idx == 0) - { - String8 inst_string = str8_lit(">"); - DASM_Line inst = {u32_from_u64_saturate(off), DASM_LineFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count, - inst_strings.total_size + inst_strings.node_count + inst_string.size)}; - dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &inst); - str8_list_push(scratch.arena, &inst_strings, inst_string); - } - last_file = file; - } - if(line && line != last_line && file->normal_full_path_string_idx != 0 && - params.style_flags & DASM_StyleFlag_SourceLines && - file_normalized_full_path.size != 0) - { - FileProperties props = os_properties_from_file_path(file_normalized_full_path); - if(props.modified != 0) - { - // TODO(rjf): need redirection path - this may map to a different path on the local machine, - // need frontend to communicate path remapping info to this layer - HS_Key key = fs_key_from_path_range(file_normalized_full_path, r1u64(0, max_U64), 0); - TXT_LangKind lang_kind = txt_lang_kind_from_extension(file_normalized_full_path); - U64 endt_us = max_U64; - U128 hash = {0}; - TXT_TextInfo text_info = {0}; - for(;os_now_microseconds() <= endt_us;) - { - text_info = txt_text_info_from_key_lang(txt_scope, key, lang_kind, &hash); - if(!u128_match(hash, u128_zero())) - { - break; - } - } - if(0 < line->line_num && line->line_num < text_info.lines_count) - { - String8 data = hs_data_from_hash(hs_scope, hash); - String8 line_text = str8_skip_chop_whitespace(str8_substr(data, text_info.lines_ranges[line->line_num-1])); - if(line_text.size != 0) - { - String8 inst_string = push_str8f(scratch.arena, "> %S", line_text); - DASM_Line inst = {u32_from_u64_saturate(off), DASM_LineFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count, - inst_strings.total_size + inst_strings.node_count + inst_string.size)}; - dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &inst); - str8_list_push(scratch.arena, &inst_strings, inst_string); - } - } - } - last_line = line; - } - } - } - } - - // rjf: push line - String8 addr_part = {0}; - if(params.style_flags & DASM_StyleFlag_Addresses) - { - addr_part = push_str8f(scratch.arena, "%s0x%016I64x ", rdi != &rdi_parsed_nil ? " " : "", params.vaddr+off); - } - String8 code_bytes_part = {0}; - if(params.style_flags & DASM_StyleFlag_CodeBytes) - { - String8List code_bytes_strings = {0}; - str8_list_push(scratch.arena, &code_bytes_strings, str8_lit("{")); - for(U64 byte_idx = 0; byte_idx < inst.size || byte_idx < 16; byte_idx += 1) - { - if(byte_idx < inst.size) - { - str8_list_pushf(scratch.arena, &code_bytes_strings, "%02x%s ", (U32)data.str[off+byte_idx], byte_idx == inst.size-1 ? "}" : ""); - } - else if(byte_idx < 8) - { - str8_list_push(scratch.arena, &code_bytes_strings, str8_lit(" ")); - } - } - str8_list_push(scratch.arena, &code_bytes_strings, str8_lit(" ")); - code_bytes_part = str8_list_join(scratch.arena, &code_bytes_strings, 0); - } - String8 symbol_part = {0}; - if(inst.jump_dest_vaddr != 0 && rdi != &rdi_parsed_nil && params.style_flags & DASM_StyleFlag_SymbolNames) - { - RDI_U32 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, inst.jump_dest_vaddr-params.base_vaddr); - if(scope_idx != 0) - { - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); - RDI_U32 procedure_idx = scope->proc_idx; - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, procedure_idx); - String8 procedure_name = {0}; - procedure_name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &procedure_name.size); - if(procedure_name.size != 0) - { - symbol_part = push_str8f(scratch.arena, " (%S)", procedure_name); - } - } - } - String8 inst_string = push_str8f(scratch.arena, "%S%S%S%S", addr_part, code_bytes_part, inst.string, symbol_part); - DASM_Line line = {u32_from_u64_saturate(off), 0, inst.jump_dest_vaddr, r1u64(inst_strings.total_size + inst_strings.node_count, - inst_strings.total_size + inst_strings.node_count + inst_string.size)}; - dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &line); - str8_list_push(scratch.arena, &inst_strings, inst_string); - - // rjf: increment - off += inst.size; - } - }break; - } - } - - //- rjf: artifacts -> value bundle - Arena *info_arena = 0; - DASM_Info info = {0}; - { - //- rjf: produce joined text - Arena *text_arena = arena_alloc(); - StringJoin text_join = {0}; - text_join.sep = str8_lit("\n"); - String8 text = str8_list_join(text_arena, &inst_strings, &text_join); - //- rjf: produce unique key for this disassembly's text - HS_Key text_key = hs_key_make(root, hs_id_make(0, 0)); - - //- rjf: submit text data to hash store - U128 text_hash = hs_submit_data(text_key, &text_arena, text); - - //- rjf: produce value bundle - info_arena = arena_alloc(); - info.text_key = text_key; - info.lines = dasm_line_array_from_chunk_list(info_arena, &line_list); - } - - //- rjf: commit results to cache - MutexScopeW(stripe->rw_mutex) - { - for(DASM_Node *n = slot->first; n != 0; n = n->next) + //- rjf: re-request if stale + MutexScope(dasm_shared->req_mutex) { - if(u128_match(n->hash, hash) && dasm_params_match(&n->params, ¶ms)) - { - n->info_arena = info_arena; - MemoryCopyStruct(&n->info, &info); - if(rdi != &rdi_parsed_nil && params.style_flags & (DASM_StyleFlag_SourceLines|DASM_StyleFlag_SourceFilesNames)) - { - n->change_gen = change_gen; - } - else - { - n->change_gen = 0; - } - break; - } + DASM_RequestNode *req_n = push_array(dasm_shared->req_arena, DASM_RequestNode, 1); + SLLQueuePush(dasm_shared->first_req, dasm_shared->last_req, req_n); + dasm_shared->req_count += 1; + req_n->v.root = root; + req_n->v.hash = hash; + req_n->v.params = params; + req_n->v.params.dbgi_key = di_key_copy(dasm_shared->req_arena, &req_n->v.params.dbgi_key); } + + txt_scope_close(txt_scope); + di_scope_close(di_scope); + hs_scope_close(hs_scope); } - txt_scope_close(txt_scope); - di_scope_close(di_scope); - hs_scope_close(hs_scope); scratch_end(scratch); ProfEnd(); - return 0; -} - -//////////////////////////////// -//~ rjf: Evictor/Detector Thread - -internal void -dasm_evictor_detector_thread__entry_point(void *p) -{ - ThreadNameF("dasm_evictor_detector_thread"); - for(;;) - { - U64 change_gen = fs_change_gen(); - U64 check_time_us = os_now_microseconds(); - U64 check_time_user_clocks = update_tick_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; - DASM_Slot *slot = &dasm_shared->slots[slot_idx]; - DASM_Stripe *stripe = &dasm_shared->stripes[stripe_idx]; - B32 slot_has_work = 0; - MutexScopeR(stripe->rw_mutex) - { - for(DASM_Node *n = slot->first; n != 0; n = n->next) - { - if(n->scope_ref_count == 0 && - n->last_time_touched_us+evict_threshold_us <= check_time_us && - n->last_user_clock_idx_touched+evict_threshold_user_clocks <= check_time_user_clocks && - ins_atomic_u64_eval(&n->working_count) == 0) - { - 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) MutexScopeW(stripe->rw_mutex) - { - for(DASM_Node *n = slot->first, *next = 0; n != 0; n = next) - { - next = n->next; - if(n->scope_ref_count == 0 && - n->last_time_touched_us+evict_threshold_us <= check_time_us && - n->last_user_clock_idx_touched+evict_threshold_user_clocks <= check_time_user_clocks && - ins_atomic_u64_eval(&n->working_count) == 0) - { - DLLRemove(slot->first, slot->last, n); - if(n->info_arena != 0) - { - arena_release(n->info_arena); - } - 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->root, n->hash, &n->params, max_U64)) - { - async_push_work(dasm_parse_work); - n->last_time_requested_us = os_now_microseconds(); - n->last_user_clock_idx_requested = check_time_user_clocks; - } - } - } - } - } - os_sleep_milliseconds(100); - } } diff --git a/src/dasm_cache/dasm_cache.h b/src/dasm_cache/dasm_cache.h index 4cde946b..855cf348 100644 --- a/src/dasm_cache/dasm_cache.h +++ b/src/dasm_cache/dasm_cache.h @@ -268,17 +268,6 @@ struct DASM_Shared DASM_RequestNode *first_req; DASM_RequestNode *last_req; U64 req_count; - - // rjf: user -> parse thread - U64 u2p_ring_size; - U8 *u2p_ring_base; - U64 u2p_ring_write_pos; - U64 u2p_ring_read_pos; - CondVar u2p_ring_cv; - Mutex u2p_ring_mutex; - - // rjf: evictor/detector thread - Thread evictor_detector_thread; }; //////////////////////////////// @@ -333,16 +322,4 @@ internal DASM_Info dasm_info_from_key_params(DASM_Scope *scope, HS_Key key, DASM internal void dasm_tick(void); -//////////////////////////////// -//~ rjf: Parse Threads - -internal B32 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); -ASYNC_WORK_DEF(dasm_parse_work); - -//////////////////////////////// -//~ rjf: Evictor/Detector Thread - -internal void dasm_evictor_detector_thread__entry_point(void *p); - #endif // DASM_CACHE_H diff --git a/src/file_stream/file_stream.c b/src/file_stream/file_stream.c index a90656cf..d7a0dd02 100644 --- a/src/file_stream/file_stream.c +++ b/src/file_stream/file_stream.c @@ -246,6 +246,7 @@ fs_properties_from_path(String8 path) internal void fs_tick(void) { + ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); //- rjf: do detection pass @@ -283,7 +284,6 @@ fs_tick(void) 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); } } } @@ -396,4 +396,5 @@ fs_tick(void) } scratch_end(scratch); + ProfEnd(); } diff --git a/src/hash_store/hash_store.c b/src/hash_store/hash_store.c index 8adccdfd..48555c7c 100644 --- a/src/hash_store/hash_store.c +++ b/src/hash_store/hash_store.c @@ -547,6 +547,7 @@ hs_data_from_hash(HS_Scope *scope, U128 hash) internal void hs_tick(void) { + ProfBeginFunction(); Rng1U64 range = lane_range(hs_shared->slots_count); for EachInRange(slot_idx, range) { @@ -588,4 +589,5 @@ hs_tick(void) } } } + ProfEnd(); }