diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 74a31f02..b0e7de5d 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1432,70 +1432,6 @@ ctrl_entity_store_apply_events(CTRL_EntityCtxRWStore *store, CTRL_EventList *lis } } -//////////////////////////////// -//~ rjf: Cache Accessing Scopes - -internal CTRL_Scope * -ctrl_scope_open(void) -{ - if(ctrl_tctx == 0) - { - Arena *arena = arena_alloc(); - ctrl_tctx = push_array(arena, CTRL_TCTX, 1); - ctrl_tctx->arena = arena; - } - CTRL_Scope *scope = ctrl_tctx->free_scope; - if(scope != 0) - { - SLLStackPop(ctrl_tctx->free_scope); - } - else - { - scope = push_array_no_zero(ctrl_tctx->arena, CTRL_Scope, 1); - } - MemoryZeroStruct(scope); - return scope; -} - -internal void -ctrl_scope_close(CTRL_Scope *scope) -{ - for(CTRL_ScopeCallStackTouch *t = scope->first_call_stack_touch, *next = 0; t != 0; t = next) - { - next = t->next; - ins_atomic_u64_dec_eval(&t->node->scope_touch_count); - cond_var_broadcast(t->stripe->cv); - SLLStackPush(ctrl_tctx->free_call_stack_touch, t); - } - for(U64 idx = 0; idx < scope->call_stack_tree_touch_count; idx += 1) - { - ins_atomic_u64_dec_eval(&ctrl_state->call_stack_tree_cache.scope_touch_count); - } - if(scope->call_stack_tree_touch_count != 0) - { - cond_var_broadcast(ctrl_state->call_stack_tree_cache.cv); - } - SLLStackPush(ctrl_tctx->free_scope, scope); -} - -internal void -ctrl_scope_touch_call_stack_node__stripe_r_guarded(CTRL_Scope *scope, CTRL_CallStackCacheStripe *stripe, CTRL_CallStackCacheNode *node) -{ - ins_atomic_u64_inc_eval(&node->scope_touch_count); - CTRL_ScopeCallStackTouch *touch = ctrl_tctx->free_call_stack_touch; - if(touch != 0) - { - SLLStackPop(ctrl_tctx->free_call_stack_touch); - } - else - { - touch = push_array(ctrl_tctx->arena, CTRL_ScopeCallStackTouch, 1); - } - SLLQueuePush(scope->first_call_stack_touch, scope->last_call_stack_touch, touch); - touch->stripe = stripe; - touch->node = node; -} - //////////////////////////////// //~ rjf: Main Layer Initialization @@ -1540,16 +1476,6 @@ ctrl_init(void) ctrl_state->thread_reg_cache.stripes[idx].arena = arena_alloc(); ctrl_state->thread_reg_cache.stripes[idx].rw_mutex = rw_mutex_alloc(); } - ctrl_state->call_stack_cache.slots_count = 1024; - ctrl_state->call_stack_cache.slots = push_array(arena, CTRL_CallStackCacheSlot, ctrl_state->call_stack_cache.slots_count); - ctrl_state->call_stack_cache.stripes_count = os_get_system_info()->logical_processor_count; - ctrl_state->call_stack_cache.stripes = push_array(arena, CTRL_CallStackCacheStripe, ctrl_state->call_stack_cache.stripes_count); - for(U64 idx = 0; idx < ctrl_state->call_stack_cache.stripes_count; idx += 1) - { - ctrl_state->call_stack_cache.stripes[idx].arena = arena_alloc(); - ctrl_state->call_stack_cache.stripes[idx].rw_mutex = rw_mutex_alloc(); - ctrl_state->call_stack_cache.stripes[idx].cv = cond_var_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); ctrl_state->module_image_info_cache.stripes_count = os_get_system_info()->logical_processor_count; @@ -1600,10 +1526,6 @@ ctrl_init(void) ctrl_state->u2ms_ring_base = push_array(arena, U8, ctrl_state->u2ms_ring_size); ctrl_state->u2ms_ring_mutex = mutex_alloc(); ctrl_state->u2ms_ring_cv = cond_var_alloc(); - ctrl_state->u2csb_ring_size = KB(64); - ctrl_state->u2csb_ring_base = push_array(arena, U8, ctrl_state->u2csb_ring_size); - ctrl_state->u2csb_ring_mutex = mutex_alloc(); - ctrl_state->u2csb_ring_cv = cond_var_alloc(); ctrl_state->ctrl_thread_log = log_alloc(); ctrl_state->ctrl_thread = thread_launch(ctrl_thread__entry_point, 0); } @@ -3428,157 +3350,6 @@ ctrl_call_stack_frame_from_unwind_and_inline_depth(CTRL_CallStack *call_stack, U return f; } -//////////////////////////////// -//~ rjf: Call Stack Cache Functions - -internal CTRL_CallStack -ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Handle thread_handle, B32 high_priority, U64 endt_us) -{ - CTRL_CallStack call_stack = {0}; - CTRL_CallStackCache *cache = &ctrl_state->call_stack_cache; - - ////////////////////////////// - //- rjf: unpack thread - // - U64 hash = ctrl_hash_from_handle(thread_handle); - U64 slot_idx = hash%cache->slots_count; - U64 stripe_idx = slot_idx%cache->stripes_count; - CTRL_CallStackCacheSlot *slot = &cache->slots[slot_idx]; - CTRL_CallStackCacheStripe *stripe = &cache->stripes[stripe_idx]; - U64 reg_gen = ctrl_reg_gen(); - U64 mem_gen = ctrl_mem_gen(); - - ////////////////////////////// - //- rjf: loop: try to grab cached call stack; request; wait - // - B32 can_request = !ins_atomic_u64_eval(&ctrl_state->ctrl_thread_run_state); - for(U64 retry_idx = 0;; retry_idx += 1) - { - //- rjf: [read-only] try to look for current call stack; wait if working - B32 node_exists = 0; - B32 node_stale = 1; - B32 node_working = 0; - MutexScopeR(stripe->rw_mutex) for(;;) - { - CTRL_CallStackCacheNode *node = 0; - for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) - { - if(ctrl_handle_match(n->thread, thread_handle)) - { - node = n; - node_exists = 1; - node_stale = (reg_gen > n->reg_gen || mem_gen > n->mem_gen); - node_working = (n->working_count > 0); - break; - } - } - if(node_exists && (!can_request || !node_stale || os_now_microseconds() >= endt_us)) - { - call_stack = node->call_stack; - ctrl_scope_touch_call_stack_node__stripe_r_guarded(scope, stripe, node); - break; - } - else if(node_working) - { - cond_var_wait_rw_r(stripe->cv, stripe->rw_mutex, endt_us); - } - else - { - break; - } - } - - //- rjf: out of time, or got new result => exit - if((retry_idx > 0 && os_now_microseconds() >= endt_us) || !node_stale) - { - break; - } - - //- rjf: [write] node does not exist => create; request if new or stale - B32 need_request = (!node_exists || node_stale); - CTRL_CallStackCacheNode *node_to_request = 0; - if(can_request && need_request) MutexScopeW(stripe->rw_mutex) - { - CTRL_CallStackCacheNode *node = 0; - for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) - { - if(ctrl_handle_match(n->thread, thread_handle)) - { - node = n; - break; - } - } - if(node == 0) - { - node = push_array(stripe->arena, CTRL_CallStackCacheNode, 1); - DLLPushBack(slot->first, slot->last, node); - node->thread = thread_handle; - } - if(node->working_count == 0) - { - node->working_count += 1; - node_to_request = node; - } - } - - //- rjf: request if needed - if(node_to_request != 0) - { - if(ctrl_u2csb_enqueue_req(thread_handle, endt_us)) - { - async_push_work(ctrl_call_stack_build_work, .priority = high_priority ? ASYNC_Priority_High : ASYNC_Priority_Low); - } - else MutexScopeW(stripe->rw_mutex) - { - node_to_request->working_count -= 1; - } - } - } - - return call_stack; -} - -//////////////////////////////// -//~ rjf: Call Stack Tree Cache Functions - -internal CTRL_CallStackTree -ctrl_call_stack_tree(CTRL_Scope *scope, U64 endt_us) -{ - CTRL_CallStackTree result = {&ctrl_call_stack_tree_node_nil}; - { - U64 reg_gen = ctrl_reg_gen(); - U64 mem_gen = ctrl_mem_gen(); - CTRL_CallStackTreeCache *cache = &ctrl_state->call_stack_tree_cache; - MutexScopeR(cache->rw_mutex) for(;;) - { - // rjf: unpack cache/time state - B32 is_stale = (cache->reg_gen != reg_gen || cache->mem_gen != mem_gen); - B32 out_of_time = (os_now_microseconds() >= endt_us); - - // rjf: is stale? -> request new calculation - if(is_stale && !ins_atomic_u64_eval_cond_assign(&cache->request_count, 1, 0)) - { - rw_mutex_drop_r(cache->rw_mutex); - async_push_work(ctrl_call_stack_tree_build_work); - rw_mutex_take_r(cache->rw_mutex); - } - - // rjf: is not stale, or we're out of time? -> grab cached result & touch, exit - if(!is_stale || out_of_time) - { - result = cache->tree; - ins_atomic_u64_inc_eval(&cache->scope_touch_count); - scope->call_stack_tree_touch_count += 1; - break; - } - - // rjf: wait for new results - cond_var_wait_rw_r(cache->cv, cache->rw_mutex, endt_us); - } - } - return result; -} - //////////////////////////////// //~ rjf: Halting All Attached Processes @@ -7082,384 +6853,6 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work) return 0; } -//////////////////////////////// -//~ rjf: Asynchronous Unwinding Functions - -//- rjf: user -> memory stream communication - -internal B32 -ctrl_u2csb_enqueue_req(CTRL_Handle thread, U64 endt_us) -{ - B32 good = 0; - MutexScope(ctrl_state->u2csb_ring_mutex) for(;;) - { - U64 unconsumed_size = ctrl_state->u2csb_ring_write_pos - ctrl_state->u2csb_ring_read_pos; - U64 available_size = ctrl_state->u2csb_ring_size - unconsumed_size; - if(available_size >= sizeof(thread)) - { - good = 1; - ctrl_state->u2csb_ring_write_pos += ring_write_struct(ctrl_state->u2csb_ring_base, ctrl_state->u2csb_ring_size, ctrl_state->u2csb_ring_write_pos, &thread); - break; - } - if(os_now_microseconds() >= endt_us) - { - break; - } - cond_var_wait(ctrl_state->u2csb_ring_cv, ctrl_state->u2csb_ring_mutex, endt_us); - } - if(good) - { - cond_var_broadcast(ctrl_state->u2csb_ring_cv); - } - return good; -} - -internal void -ctrl_u2csb_dequeue_req(CTRL_Handle *out_thread) -{ - MutexScope(ctrl_state->u2csb_ring_mutex) for(;;) - { - U64 unconsumed_size = ctrl_state->u2csb_ring_write_pos - ctrl_state->u2csb_ring_read_pos; - if(unconsumed_size >= sizeof(*out_thread)) - { - ctrl_state->u2csb_ring_read_pos += ring_read_struct(ctrl_state->u2csb_ring_base, ctrl_state->u2csb_ring_size, ctrl_state->u2csb_ring_read_pos, out_thread); - break; - } - cond_var_wait(ctrl_state->u2csb_ring_cv, ctrl_state->u2csb_ring_mutex, max_U64); - } - cond_var_broadcast(ctrl_state->u2csb_ring_cv); -} - -//- rjf: entry point - -ASYNC_WORK_DEF(ctrl_call_stack_build_work) -{ - Temp scratch = scratch_begin(0, 0); - CTRL_CallStackCache *cache = &ctrl_state->call_stack_cache; - - //- rjf: get next request & unpack - CTRL_Handle thread_handle = {0}; - ctrl_u2csb_dequeue_req(&thread_handle); - U64 hash = ctrl_hash_from_handle(thread_handle); - U64 slot_idx = hash%cache->slots_count; - U64 stripe_idx = hash%cache->stripes_count; - CTRL_CallStackCacheSlot *slot = &cache->slots[slot_idx]; - CTRL_CallStackCacheStripe *stripe = &cache->stripes[stripe_idx]; - - //- rjf: produce mini entity context for just this process - CTRL_EntityCtx *entity_ctx = push_array(scratch.arena, CTRL_EntityCtx, 1); - MutexScopeR(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) - { - CTRL_EntityCtx *src_ctx = &ctrl_state->ctrl_thread_entity_store->ctx; - CTRL_EntityCtx *dst_ctx = entity_ctx; - { - dst_ctx->root = &ctrl_entity_nil; - dst_ctx->hash_slots_count = 1024; - dst_ctx->hash_slots = push_array(scratch.arena, CTRL_EntityHashSlot, dst_ctx->hash_slots_count); - MemoryCopyArray(dst_ctx->entity_kind_counts, src_ctx->entity_kind_counts); - MemoryCopyArray(dst_ctx->entity_kind_alloc_gens, src_ctx->entity_kind_alloc_gens); - } - CTRL_Entity *src_thread = ctrl_entity_from_handle(src_ctx, thread_handle); - CTRL_Entity *src_process = ctrl_process_from_entity(src_thread); - { - CTRL_EntityRec rec = {0}; - CTRL_Entity *dst_parent = &ctrl_entity_nil; - for(CTRL_Entity *src_e = src_process; src_e != &ctrl_entity_nil; src_e = rec.next) - { - rec = ctrl_entity_rec_depth_first_pre(src_e, src_process); - - // rjf: copy this entity - CTRL_Entity *dst_e = push_array(scratch.arena, CTRL_Entity, 1); - { - dst_e->first = dst_e->last = dst_e->next = dst_e->prev = &ctrl_entity_nil; - dst_e->parent = dst_parent; - dst_e->kind = src_e->kind; - dst_e->arch = src_e->arch; - dst_e->is_frozen = src_e->is_frozen; - dst_e->is_soloed = src_e->is_soloed; - dst_e->rgba = src_e->rgba; - dst_e->handle = src_e->handle; - dst_e->id = src_e->id; - dst_e->vaddr_range = src_e->vaddr_range; - dst_e->stack_base = src_e->stack_base; - dst_e->timestamp = src_e->timestamp; - dst_e->bp_flags = src_e->bp_flags; - dst_e->string = push_str8_copy(scratch.arena, src_e->string); - } - if(dst_parent == &ctrl_entity_nil) - { - dst_ctx->root = dst_e; - } - else - { - DLLPushBack_NPZ(&ctrl_entity_nil, dst_parent->first, dst_parent->last, dst_e, next, prev); - } - - // rjf: insert into hash map - { - U64 hash = ctrl_hash_from_handle(dst_e->handle); - U64 slot_idx = hash%dst_ctx->hash_slots_count; - CTRL_EntityHashSlot *slot = &dst_ctx->hash_slots[slot_idx]; - CTRL_EntityHashNode *node = 0; - for(CTRL_EntityHashNode *n = slot->first; n != 0; n = n->next) - { - if(ctrl_handle_match(n->entity->handle, dst_e->handle)) - { - node = n; - break; - } - } - if(node == 0) - { - node = push_array(scratch.arena, CTRL_EntityHashNode, 1); - MemoryZeroStruct(node); - DLLPushBack(slot->first, slot->last, node); - node->entity = dst_e; - } - } - - // rjf: push/pop - if(rec.push_count) - { - dst_parent = dst_e; - } - else for(S32 pop_idx = 0; pop_idx < rec.pop_count; pop_idx += 1) - { - dst_parent = dst_parent->parent; - } - } - } - } - - //- rjf: do task - { - CTRL_Entity *thread = ctrl_entity_from_handle(entity_ctx, thread_handle); - CTRL_Entity *process = ctrl_process_from_entity(thread); - - //- rjf: compute unwind to find list of all concrete frames, then - // call stack, to determine list of all concrete & inline frames - Arena *arena = arena_alloc(); - U64 pre_reg_gen = 0; - U64 post_reg_gen = 0; - U64 pre_mem_gen = 0; - U64 post_mem_gen = 0; - CTRL_Unwind unwind = {0}; - CTRL_CallStack call_stack = {0}; - { - pre_reg_gen = ctrl_reg_gen(); - pre_mem_gen = ctrl_mem_gen(); - unwind = ctrl_unwind_from_thread(arena, entity_ctx, thread_handle, os_now_microseconds()+5000); - call_stack = ctrl_call_stack_from_unwind(arena, process, &unwind); - post_reg_gen = ctrl_reg_gen(); - post_mem_gen = ctrl_mem_gen(); - } - - //- rjf: store new results in cache - Arena *last_arena = arena; - if(pre_reg_gen == post_reg_gen && - pre_mem_gen == post_mem_gen) - { - B32 found = 0; - B32 committed = 0; - MutexScopeW(stripe->rw_mutex) for(;;) - { - // rjf: try to find node & commit - for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) - { - if(ctrl_handle_match(n->thread, thread_handle)) - { - found = 1; - if(n->scope_touch_count == 0) - { - committed = 1; - if(unwind.flags == 0 || call_stack.frames_count >= n->call_stack.frames_count) - { - last_arena = n->arena; - n->arena = arena; - n->call_stack = call_stack; - } - if(unwind.flags == 0) - { - n->reg_gen = pre_reg_gen; - n->mem_gen = pre_mem_gen; - } - } - break; - } - } - - // rjf: not found, or committed? -> abort - if(!found || committed) - { - break; - } - - // rjf: found, not committed? -> wait & retry - if(found && !committed) - { - cond_var_wait_rw_w(stripe->cv, stripe->rw_mutex, os_now_microseconds()+10); - } - } - } - - //- rjf: release last results - if(last_arena != 0) - { - arena_release(last_arena); - } - - //- rjf: mark work as done - MutexScopeW(stripe->rw_mutex) for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next) - { - if(ctrl_handle_match(n->thread, thread_handle)) - { - ins_atomic_u64_dec_eval(&n->working_count); - break; - } - } - - //- rjf: broadcast update - cond_var_broadcast(stripe->cv); - if(ctrl_state->wakeup_hook != 0) - { - ctrl_state->wakeup_hook(); - } - } - - scratch_end(scratch); - return 0; -} - -//////////////////////////////// -//~ rjf: Asynchronous Call Stack Tree Building Functions - -ASYNC_WORK_DEF(ctrl_call_stack_tree_build_work) -{ - Temp scratch = scratch_begin(0, 0); - CTRL_Scope *ctrl_scope = ctrl_scope_open(); - - //- rjf: gather list of all thread handles - U64 threads_count = 0; - CTRL_Handle *threads = 0; - CTRL_Handle *threads_processes = 0; - Arch *threads_arches = 0; - MutexScopeR(ctrl_state->ctrl_thread_entity_ctx_rw_mutex) - { - CTRL_EntityCtx *ctx = &ctrl_state->ctrl_thread_entity_store->ctx; - CTRL_EntityArray thread_entities = ctrl_entity_array_from_kind(ctx, CTRL_EntityKind_Thread); - threads_count = thread_entities.count; - threads = push_array(scratch.arena, CTRL_Handle, threads_count); - threads_processes = push_array(scratch.arena, CTRL_Handle, threads_count); - threads_arches = push_array(scratch.arena, Arch, threads_count); - for EachIndex(idx, threads_count) - { - threads[idx] = thread_entities.v[idx]->handle; - threads_processes[idx] = thread_entities.v[idx]->parent->handle; - threads_arches[idx] = thread_entities.v[idx]->arch; - } - } - - //- rjf: gather all callstacks - U64 pre_mem_gen = ctrl_mem_gen(); - U64 pre_reg_gen = ctrl_reg_gen(); - CTRL_CallStack *call_stacks = push_array(scratch.arena, CTRL_CallStack, threads_count); - { - for EachIndex(idx, threads_count) - { - call_stacks[idx] = ctrl_call_stack_from_thread(ctrl_scope, threads[idx], 0, os_now_microseconds()+1000); - } - } - U64 post_mem_gen = ctrl_mem_gen(); - U64 post_reg_gen = ctrl_reg_gen(); - - //- rjf: build call stack tree - Arena *arena = 0; - CTRL_CallStackTree tree = {&ctrl_call_stack_tree_node_nil}; - if(pre_mem_gen == post_mem_gen && - pre_reg_gen == post_reg_gen) - { - U64 id_gen = 0; - arena = arena_alloc(); - tree.root = push_array(arena, CTRL_CallStackTreeNode, 1); - MemoryCopyStruct(tree.root, &ctrl_call_stack_tree_node_nil); - tree.root->id = id_gen; - tree.slots_count = Max(1, threads_count); - tree.slots = push_array(arena, CTRL_CallStackTreeNode *, tree.slots_count); - id_gen += 1; - for EachIndex(thread_idx, threads_count) - { - CTRL_Handle thread = threads[thread_idx]; - CTRL_Handle process = threads_processes[thread_idx]; - Arch arch = threads_arches[thread_idx]; - CTRL_CallStack call_stack = call_stacks[thread_idx]; - CTRL_CallStackTreeNode *thread_node = tree.root; - for EachIndex(frame_idx, call_stack.frames_count) - { - U64 vaddr = regs_rip_from_arch_block(arch, call_stack.frames[frame_idx].regs); - U64 depth = call_stack.frames[frame_idx].inline_depth; - CTRL_CallStackTreeNode *next_node = &ctrl_call_stack_tree_node_nil; - for(CTRL_CallStackTreeNode *child = thread_node->first; child != &ctrl_call_stack_tree_node_nil; child = child->next) - { - if(ctrl_handle_match(child->process, process) && child->vaddr == vaddr && child->depth == depth) - { - next_node = child; - break; - } - } - if(next_node == &ctrl_call_stack_tree_node_nil) - { - next_node = push_array(arena, CTRL_CallStackTreeNode, 1); - MemoryCopyStruct(next_node, &ctrl_call_stack_tree_node_nil); - next_node->id = id_gen; - SLLStackPush_N(tree.slots[next_node->id%tree.slots_count], next_node, hash_next); - id_gen += 1; - SLLQueuePush_NZ(&ctrl_call_stack_tree_node_nil, thread_node->first, thread_node->last, next_node, next); - next_node->parent = thread_node; - thread_node->child_count += 1; - } - thread_node = next_node; - } - ctrl_handle_list_push(arena, &thread_node->threads, &thread); - for(CTRL_CallStackTreeNode *n = thread_node; n != &ctrl_call_stack_tree_node_nil; n = n->parent) - { - n->all_descendant_threads_count += 1; - } - } - } - - //- rjf: commit to cache - Arena *old_arena = 0; - CTRL_CallStackTreeCache *cache = &ctrl_state->call_stack_tree_cache; - if(tree.root != &ctrl_call_stack_tree_node_nil) - { - MutexScopeW(cache->rw_mutex) for(;;) - { - if(cache->scope_touch_count == 0) - { - old_arena = cache->arena; - cache->arena = arena; - cache->tree = tree; - cache->reg_gen = post_reg_gen; - cache->mem_gen = post_mem_gen; - cache->request_count -= 1; - break; - } - cond_var_wait_rw_w(cache->cv, cache->rw_mutex, max_U64); - } - } - cond_var_broadcast(cache->cv); - - //- rjf: release old arena - if(old_arena) - { - arena_release(old_arena); - } - - ctrl_scope_close(ctrl_scope); - scratch_end(scratch); - return 0; -} - //////////////////////////////// //~ rjf: Process Memory Artifact Cache Hooks / Lookups diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index b2d72f6d..fb2cf401 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -646,53 +646,6 @@ struct CTRL_ThreadRegCache CTRL_ThreadRegCacheStripe *stripes; }; -//////////////////////////////// -//~ rjf: Call Stack Cache Types - -typedef struct CTRL_CallStackCacheNode CTRL_CallStackCacheNode; -struct CTRL_CallStackCacheNode -{ - CTRL_CallStackCacheNode *next; - CTRL_CallStackCacheNode *prev; - - // rjf: key - CTRL_Handle thread; - U64 reg_gen; - U64 mem_gen; - - // rjf: counters - U64 scope_touch_count; - U64 working_count; - - // rjf: value - Arena *arena; - CTRL_CallStack call_stack; -}; - -typedef struct CTRL_CallStackCacheSlot CTRL_CallStackCacheSlot; -struct CTRL_CallStackCacheSlot -{ - CTRL_CallStackCacheNode *first; - CTRL_CallStackCacheNode *last; -}; - -typedef struct CTRL_CallStackCacheStripe CTRL_CallStackCacheStripe; -struct CTRL_CallStackCacheStripe -{ - Arena *arena; - RWMutex rw_mutex; - CondVar cv; -}; - -typedef struct CTRL_CallStackCache CTRL_CallStackCache; -struct CTRL_CallStackCache -{ - U64 slots_count; - CTRL_CallStackCacheSlot *slots; - U64 stripes_count; - CTRL_CallStackCacheStripe *stripes; -}; - //////////////////////////////// //~ rjf: Module Image Info Cache Types @@ -780,34 +733,6 @@ struct CTRL_EvalScope E_InterpretCtx interpret_ctx; }; -//////////////////////////////// -//~ rjf: Control Cache Accessing Scopes - -typedef struct CTRL_ScopeCallStackTouch CTRL_ScopeCallStackTouch; -struct CTRL_ScopeCallStackTouch -{ - CTRL_ScopeCallStackTouch *next; - CTRL_CallStackCacheStripe *stripe; - CTRL_CallStackCacheNode *node; -}; - -typedef struct CTRL_Scope CTRL_Scope; -struct CTRL_Scope -{ - CTRL_Scope *next; - CTRL_ScopeCallStackTouch *first_call_stack_touch; - CTRL_ScopeCallStackTouch *last_call_stack_touch; - U64 call_stack_tree_touch_count; -}; - -typedef struct CTRL_TCTX CTRL_TCTX; -struct CTRL_TCTX -{ - Arena *arena; - CTRL_Scope *free_scope; - CTRL_ScopeCallStackTouch *free_call_stack_touch; -}; - //////////////////////////////// //~ rjf: Module Requirement Cache Types @@ -857,7 +782,6 @@ struct CTRL_State // rjf: caches CTRL_ProcessMemoryCache process_memory_cache; CTRL_ThreadRegCache thread_reg_cache; - CTRL_CallStackCache call_stack_cache; CTRL_ModuleImageInfoCache module_image_info_cache; CTRL_CallStackTreeCache call_stack_tree_cache; @@ -921,14 +845,6 @@ struct CTRL_State U64 u2ms_ring_read_pos; Mutex u2ms_ring_mutex; CondVar u2ms_ring_cv; - - // rjf: user -> call stack builder ring buffer - U64 u2csb_ring_size; - U8 *u2csb_ring_base; - U64 u2csb_ring_write_pos; - U64 u2csb_ring_read_pos; - Mutex u2csb_ring_mutex; - CondVar u2csb_ring_cv; }; //////////////////////////////// @@ -951,7 +867,6 @@ read_only global CTRL_CallStackTreeNode ctrl_call_stack_tree_node_nil = &ctrl_call_stack_tree_node_nil, &ctrl_call_stack_tree_node_nil, }; -thread_static CTRL_TCTX *ctrl_tctx = 0; thread_static CTRL_EntityCtxLookupAccel *ctrl_entity_ctx_lookup_accel = 0; //////////////////////////////// @@ -1078,13 +993,6 @@ internal CTRL_Entity *ctrl_thread_from_id(CTRL_EntityCtx *ctx, U64 id); //- rjf: applying events to entity caches internal void ctrl_entity_store_apply_events(CTRL_EntityCtxRWStore *store, CTRL_EventList *list); -//////////////////////////////// -//~ rjf: Cache Accessing Scopes - -internal CTRL_Scope *ctrl_scope_open(void); -internal void ctrl_scope_close(CTRL_Scope *scope); -internal void ctrl_scope_touch_call_stack_node__stripe_r_guarded(CTRL_Scope *scope, CTRL_CallStackCacheStripe *stripe, CTRL_CallStackCacheNode *node); - //////////////////////////////// //~ rjf: Main Layer Initialization @@ -1153,16 +1061,6 @@ internal CTRL_Unwind ctrl_unwind_from_thread(Arena *arena, CTRL_EntityCtx *ctx, internal CTRL_CallStack ctrl_call_stack_from_unwind(Arena *arena, CTRL_Entity *process, CTRL_Unwind *base_unwind); internal CTRL_CallStackFrame *ctrl_call_stack_frame_from_unwind_and_inline_depth(CTRL_CallStack *call_stack, U64 unwind_count, U64 inline_depth); -//////////////////////////////// -//~ rjf: Call Stack Cache Functions - -internal CTRL_CallStack ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Handle thread_handle, B32 high_priority, U64 endt_us); - -//////////////////////////////// -//~ rjf: Call Stack Tree Cache Functions - -internal CTRL_CallStackTree ctrl_call_stack_tree(CTRL_Scope *scope, U64 endt_us); - //////////////////////////////// //~ rjf: Halting All Attached Processes @@ -1235,21 +1133,6 @@ internal void ctrl_u2ms_dequeue_req(C_Key *out_key, CTRL_Handle *out_process, Rn //- rjf: entry point ASYNC_WORK_DEF(ctrl_mem_stream_work); -//////////////////////////////// -//~ rjf: Asynchronous Call Stack Building Functions - -//- rjf: user -> memory stream communication -internal B32 ctrl_u2csb_enqueue_req(CTRL_Handle thread, U64 endt_us); -internal void ctrl_u2csb_dequeue_req(CTRL_Handle *out_thread); - -//- rjf: entry point -ASYNC_WORK_DEF(ctrl_call_stack_build_work); - -//////////////////////////////// -//~ rjf: Asynchronous Call Stack Tree Building Functions - -ASYNC_WORK_DEF(ctrl_call_stack_tree_build_work); - //////////////////////////////// //~ rjf: Process Memory Artifact Cache Hooks / Lookups diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 6ddf6c8c..05d4fd96 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -11497,10 +11497,8 @@ rd_frame(void) // Access *frame_access_restore = rd_state->frame_access; DI_Scope *frame_di_scope_restore = rd_state->frame_di_scope; - CTRL_Scope *frame_ctrl_scope_restore = rd_state->frame_ctrl_scope; rd_state->frame_access = access_open(); rd_state->frame_di_scope = di_scope_open(); - rd_state->frame_ctrl_scope = ctrl_scope_open(); rd_state->got_frame_call_stack_tree = 0; ////////////////////////////// @@ -17327,10 +17325,8 @@ rd_frame(void) // access_close(rd_state->frame_access); di_scope_close(rd_state->frame_di_scope); - ctrl_scope_close(rd_state->frame_ctrl_scope); rd_state->frame_access = frame_access_restore; rd_state->frame_di_scope = frame_di_scope_restore; - rd_state->frame_ctrl_scope = frame_ctrl_scope_restore; ////////////////////////////// //- rjf: submit rendering to all windows diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 388be833..c58aff29 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -601,7 +601,6 @@ struct RD_State F32 frame_dt; Access *frame_access; DI_Scope *frame_di_scope; - CTRL_Scope *frame_ctrl_scope; CTRL_CallStackTree frame_call_stack_tree; B32 got_frame_call_stack_tree;