mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-07-09 11:01:37 -07:00
complete first pass of fuzzy matching symbol lister for go-to-name, and setting function breakpoints
This commit is contained in:
@@ -58,7 +58,7 @@ ctrl_init(CTRL_WakeupFunctionType *wakeup_hook)
|
||||
ctrl_state->u2ms_ring_mutex = os_mutex_alloc();
|
||||
ctrl_state->u2ms_ring_cv = os_condition_variable_alloc();
|
||||
ctrl_state->ctrl_thread = os_launch_thread(ctrl_thread__entry_point, 0, 0);
|
||||
ctrl_state->ms_thread_count = Min(4, os_logical_core_count()-1);
|
||||
ctrl_state->ms_thread_count = Clamp(1, os_logical_core_count()-1, 4);
|
||||
ctrl_state->ms_threads = push_array(arena, OS_Handle, ctrl_state->ms_thread_count);
|
||||
for(U64 idx = 0; idx < ctrl_state->ms_thread_count; idx += 1)
|
||||
{
|
||||
|
||||
+221
-20
@@ -30,6 +30,16 @@ dbgi_init(void)
|
||||
dbgi_shared->binary_stripes[idx].rw_mutex = os_rw_mutex_alloc();
|
||||
dbgi_shared->binary_stripes[idx].cv = os_condition_variable_alloc();
|
||||
}
|
||||
dbgi_shared->fuzzy_search_slots_count = 64;
|
||||
dbgi_shared->fuzzy_search_stripes_count = 8;
|
||||
dbgi_shared->fuzzy_search_slots = push_array(arena, DBGI_FuzzySearchSlot, dbgi_shared->fuzzy_search_slots_count);
|
||||
dbgi_shared->fuzzy_search_stripes = push_array(arena, DBGI_FuzzySearchStripe, dbgi_shared->fuzzy_search_stripes_count);
|
||||
for(U64 idx = 0; idx < dbgi_shared->fuzzy_search_stripes_count; idx += 1)
|
||||
{
|
||||
dbgi_shared->fuzzy_search_stripes[idx].arena = arena_alloc();
|
||||
dbgi_shared->fuzzy_search_stripes[idx].rw_mutex = os_rw_mutex_alloc();
|
||||
dbgi_shared->fuzzy_search_stripes[idx].cv = os_condition_variable_alloc();
|
||||
}
|
||||
dbgi_shared->u2p_ring_mutex = os_mutex_alloc();
|
||||
dbgi_shared->u2p_ring_cv = os_condition_variable_alloc();
|
||||
dbgi_shared->u2p_ring_size = KB(64);
|
||||
@@ -44,6 +54,17 @@ dbgi_init(void)
|
||||
{
|
||||
dbgi_shared->parse_threads[idx] = os_launch_thread(dbgi_parse_thread_entry_point, (void *)idx, 0);
|
||||
}
|
||||
dbgi_shared->fuzzy_thread_count = Clamp(1, os_logical_core_count()-1, 4);
|
||||
dbgi_shared->fuzzy_threads = push_array(arena, DBGI_FuzzySearchThread, dbgi_shared->fuzzy_thread_count);
|
||||
for(U64 idx = 0; idx < dbgi_shared->fuzzy_thread_count; idx += 1)
|
||||
{
|
||||
DBGI_FuzzySearchThread *thread = &dbgi_shared->fuzzy_threads[idx];
|
||||
thread->u2f_ring_mutex = os_mutex_alloc();
|
||||
thread->u2f_ring_cv = os_condition_variable_alloc();
|
||||
thread->u2f_ring_size = KB(64);
|
||||
thread->u2f_ring_base = push_array_no_zero(dbgi_shared->arena, U8, thread->u2f_ring_size);
|
||||
thread->thread = os_launch_thread(dbgi_fuzzy_thread__entry_point, (void *)idx, 0);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
@@ -169,6 +190,12 @@ dbgi_scope_close(DBGI_Scope *scope)
|
||||
ins_atomic_u64_dec_eval(&tb->binary->scope_touch_count);
|
||||
SLLStackPush(dbgi_tctx->free_tb, tb);
|
||||
}
|
||||
for(DBGI_TouchedFuzzySearch *tfs = scope->first_tfs, *next = 0; tfs != 0; tfs = next)
|
||||
{
|
||||
next = tfs->next;
|
||||
ins_atomic_u64_dec_eval(&tfs->node->scope_touch_count);
|
||||
SLLStackPush(dbgi_tctx->free_tfs, tfs);
|
||||
}
|
||||
SLLStackPush(dbgi_tctx->free_scope, scope);
|
||||
}
|
||||
|
||||
@@ -192,7 +219,18 @@ dbgi_scope_touch_binary__stripe_mutex_r_guarded(DBGI_Scope *scope, DBGI_Binary *
|
||||
internal void
|
||||
dbgi_scope_touch_fuzzy_search__stripe_mutex_r_guarded(DBGI_Scope *scope, DBGI_FuzzySearchNode *node)
|
||||
{
|
||||
|
||||
DBGI_TouchedFuzzySearch *tfs = dbgi_tctx->free_tfs;
|
||||
ins_atomic_u64_inc_eval(&node->scope_touch_count);
|
||||
if(tfs != 0)
|
||||
{
|
||||
SLLStackPop(dbgi_tctx->free_tfs);
|
||||
}
|
||||
else
|
||||
{
|
||||
tfs = push_array(dbgi_tctx->arena, DBGI_TouchedFuzzySearch, 1);
|
||||
}
|
||||
tfs->node = node;
|
||||
SLLQueuePush(scope->first_tfs, scope->last_tfs, tfs);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
@@ -297,6 +335,7 @@ dbgi_parse_from_exe_path(DBGI_Scope *scope, String8 exe_path, U64 endt_us)
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
exe_path = path_normalized_from_string(scratch.arena, exe_path);
|
||||
DBGI_Parse *parse = &dbgi_parse_nil;
|
||||
if(exe_path.size != 0)
|
||||
{
|
||||
U64 hash = dbgi_hash_from_string(exe_path);
|
||||
U64 slot_idx = hash%dbgi_shared->binary_slots_count;
|
||||
@@ -346,17 +385,22 @@ dbgi_parse_from_exe_path(DBGI_Scope *scope, String8 exe_path, U64 endt_us)
|
||||
//~ rjf: Fuzzy Search Cache Functions
|
||||
|
||||
internal DBGI_FuzzySearchItemArray
|
||||
dbgi_fuzzy_search_items_from_key_exe_query(DBGI_Scope *scope, U128 key, String8 exe_path, String8 query, U64 endt_us)
|
||||
dbgi_fuzzy_search_items_from_key_exe_query(DBGI_Scope *scope, U128 key, String8 exe_path, String8 query, U64 endt_us, B32 *stale_out)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DBGI_FuzzySearchItemArray items = {0};
|
||||
#if 0
|
||||
exe_path = path_normalized_from_string(scratch.arena, exe_path);
|
||||
{
|
||||
//- rjf: unpack key
|
||||
U64 slot_idx = key.u64[1]%dbgi_shared->fuzzy_search_slots_count;
|
||||
U64 stripe_idx = slot_idx%dbgi_shared->fuzzy_search_stripes_count;
|
||||
DBGI_FuzzySearchSlot *slot = &dbgi_shared->fuzzy_search_slots[slot_idx];
|
||||
DBGI_FuzzySearchStripe *stripe = &dbgi_shared->fuzzy_search_stripes[stripe_idx];
|
||||
|
||||
//- rjf: query and/or request
|
||||
OS_MutexScopeR(stripe->rw_mutex) for(;;)
|
||||
{
|
||||
// rjf: map key -> node
|
||||
DBGI_FuzzySearchNode *node = 0;
|
||||
for(DBGI_FuzzySearchNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
@@ -366,34 +410,56 @@ dbgi_fuzzy_search_items_from_key_exe_query(DBGI_Scope *scope, U128 key, String8
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: no node? -> allocate
|
||||
if(node == 0) OS_MutexScopeRWPromote(stripe->rw_mutex)
|
||||
{
|
||||
node = push_array(stripe->arena, DBGI_FuzzySearchNode, 1);
|
||||
DLLPushBack(slot->first, slot->last, node);
|
||||
SLLQueuePush(slot->first, slot->last, node);
|
||||
node->key = key;
|
||||
}
|
||||
B32 stale = 1;
|
||||
if(node->gen > 0)
|
||||
{
|
||||
U64 v_idx = (node->gen-1)%ArrayCount(node->v);
|
||||
if(str8_match(exe_path, node->v[v_idx].exe_path, 0))
|
||||
for(U64 idx = 0; idx < ArrayCount(node->buckets); idx += 1)
|
||||
{
|
||||
items = node->v[v_idx].items;
|
||||
stale = str8_match(query, node->v[v_idx].query, 0);
|
||||
node->buckets[idx].arena = arena_alloc();
|
||||
}
|
||||
}
|
||||
if(stale && node->submitted != 0) OS_MutexScopeRWPromote(stripe->rw_mutex)
|
||||
|
||||
// rjf: try to grab last valid results for this key/query; determine if stale
|
||||
B32 stale = 1;
|
||||
if(str8_match(exe_path, node->buckets[node->gen%ArrayCount(node->buckets)].exe_path, 0) && node->gen != 0)
|
||||
{
|
||||
node->submitted = (U64)!!dbgi_u2f_enqueue_req(key, exe_path, query, endt_us);
|
||||
dbgi_scope_touch_fuzzy_search__stripe_mutex_r_guarded(scope, node);
|
||||
items = node->gen_items;
|
||||
stale = !str8_match(query, node->buckets[node->gen%ArrayCount(node->buckets)].query, 0);
|
||||
*stale_out = stale;
|
||||
}
|
||||
|
||||
// rjf: if stale -> request again
|
||||
if(stale) OS_MutexScopeRWPromote(stripe->rw_mutex)
|
||||
{
|
||||
if(node->submit_gen == node->gen)
|
||||
{
|
||||
node->submit_gen += 1;
|
||||
arena_clear(node->buckets[node->submit_gen%ArrayCount(node->buckets)].arena);
|
||||
node->buckets[node->submit_gen%ArrayCount(node->buckets)].exe_path = push_str8_copy(node->buckets[node->submit_gen%ArrayCount(node->buckets)].arena, exe_path);
|
||||
node->buckets[node->submit_gen%ArrayCount(node->buckets)].query = push_str8_copy(node->buckets[node->submit_gen%ArrayCount(node->buckets)].arena, query);
|
||||
}
|
||||
if(os_now_microseconds() >= node->last_time_submitted_us+100000 && dbgi_u2f_enqueue_req(key, endt_us))
|
||||
{
|
||||
node->last_time_submitted_us = os_now_microseconds();
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: not stale, or timeout -> break
|
||||
if(!stale || os_now_microseconds() >= endt_us)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// rjf: no results, but have time to wait -> wait
|
||||
os_condition_variable_wait_rw_r(stripe->cv, stripe->rw_mutex, endt_us);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
scratch_end(scratch);
|
||||
return items;
|
||||
}
|
||||
|
||||
@@ -963,19 +1029,154 @@ dbgi_parse_thread_entry_point(void *p)
|
||||
//~ rjf: Fuzzy Searching Threads
|
||||
|
||||
internal B32
|
||||
dbgi_u2f_enqueue_req(U128 key, String8 exe_path, String8 query, U64 endt_us)
|
||||
dbgi_u2f_enqueue_req(U128 key, U64 endt_us)
|
||||
{
|
||||
return 0;
|
||||
B32 sent = 0;
|
||||
DBGI_FuzzySearchThread *thread = &dbgi_shared->fuzzy_threads[key.u64[1]%dbgi_shared->fuzzy_thread_count];
|
||||
OS_MutexScope(thread->u2f_ring_mutex) for(;;)
|
||||
{
|
||||
U64 unconsumed_size = thread->u2f_ring_write_pos - thread->u2f_ring_read_pos;
|
||||
U64 available_size = thread->u2f_ring_size - unconsumed_size;
|
||||
if(available_size >= sizeof(U128))
|
||||
{
|
||||
sent = 1;
|
||||
thread->u2f_ring_write_pos += ring_write_struct(thread->u2f_ring_base, thread->u2f_ring_size, thread->u2f_ring_write_pos, &key);
|
||||
break;
|
||||
}
|
||||
os_condition_variable_wait(thread->u2f_ring_cv, thread->u2f_ring_mutex, endt_us);
|
||||
}
|
||||
if(sent)
|
||||
{
|
||||
os_condition_variable_broadcast(thread->u2f_ring_cv);
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
||||
internal void
|
||||
dbgi_u2f_dequeue_req(Arena *arena, U128 *key_out, String8 *exe_path_out, String8 *query_out)
|
||||
dbgi_u2f_dequeue_req(Arena *arena, DBGI_FuzzySearchThread *thread, U128 *key_out)
|
||||
{
|
||||
|
||||
OS_MutexScope(thread->u2f_ring_mutex) for(;;)
|
||||
{
|
||||
U64 unconsumed_size = thread->u2f_ring_write_pos - thread->u2f_ring_read_pos;
|
||||
if(unconsumed_size >= sizeof(U128))
|
||||
{
|
||||
thread->u2f_ring_read_pos += ring_read_struct(thread->u2f_ring_base, thread->u2f_ring_size, thread->u2f_ring_read_pos, key_out);
|
||||
break;
|
||||
}
|
||||
os_condition_variable_wait(thread->u2f_ring_cv, thread->u2f_ring_mutex, max_U64);
|
||||
}
|
||||
os_condition_variable_broadcast(thread->u2f_ring_cv);
|
||||
}
|
||||
|
||||
internal void
|
||||
dbgi_fuzzy_thread__entry_point(void *p)
|
||||
{
|
||||
|
||||
TCTX tctx_;
|
||||
tctx_init_and_equip(&tctx_);
|
||||
ProfThreadName("[dbgi] fuzzy search #%I64U", (U64)p);
|
||||
DBGI_FuzzySearchThread *thread = &dbgi_shared->fuzzy_threads[(U64)p];
|
||||
for(;;)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DBGI_Scope *scope = dbgi_scope_open();
|
||||
|
||||
//- rjf: dequeue next request
|
||||
U128 key = {0};
|
||||
dbgi_u2f_dequeue_req(scratch.arena, thread, &key);
|
||||
U64 slot_idx = key.u64[1]%dbgi_shared->fuzzy_search_slots_count;
|
||||
U64 stripe_idx = slot_idx%dbgi_shared->fuzzy_search_stripes_count;
|
||||
DBGI_FuzzySearchSlot *slot = &dbgi_shared->fuzzy_search_slots[slot_idx];
|
||||
DBGI_FuzzySearchStripe *stripe = &dbgi_shared->fuzzy_search_stripes[stripe_idx];
|
||||
|
||||
//- rjf: grab next exe_path/query for this key
|
||||
B32 task_is_good = 0;
|
||||
Arena *task_arena = 0;
|
||||
String8 exe_path = {0};
|
||||
String8 query = {0};
|
||||
OS_MutexScopeW(stripe->rw_mutex)
|
||||
{
|
||||
for(DBGI_FuzzySearchNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(u128_match(n->key, key))
|
||||
{
|
||||
task_is_good = 1;
|
||||
task_arena = n->buckets[n->submit_gen%ArrayCount(n->buckets)].arena;
|
||||
exe_path = n->buckets[n->submit_gen%ArrayCount(n->buckets)].exe_path;
|
||||
query = n->buckets[n->submit_gen%ArrayCount(n->buckets)].query;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: form space-separated search needles
|
||||
U8 splits[] = {' '};
|
||||
String8List query_needles = str8_split(scratch.arena, query, splits, ArrayCount(splits), 0);
|
||||
|
||||
//- rjf: exe_path -> dbgi_parse, raddbg
|
||||
DBGI_Parse *dbgi = dbgi_parse_from_exe_path(scope, exe_path, max_U64);
|
||||
RADDBG_Parsed *rdbg = &dbgi->rdbg;
|
||||
|
||||
//- rjf: rdbg * query -> item list
|
||||
DBGI_FuzzySearchItemChunkList items_list = {0};
|
||||
if(task_is_good)
|
||||
{
|
||||
for(U64 procedure_idx = 0; procedure_idx < rdbg->procedure_count; procedure_idx += 1)
|
||||
{
|
||||
RADDBG_Procedure *procedure = &rdbg->procedures[procedure_idx];
|
||||
U64 name_size = 0;
|
||||
U8 *name_base = raddbg_string_from_idx(rdbg, procedure->name_string_idx, &name_size);
|
||||
String8 name = str8(name_base, name_size);
|
||||
if(name.size == 0) { continue; }
|
||||
FuzzyMatchRangeList matches = fuzzy_match_find(task_arena, query_needles, name);
|
||||
if(matches.count == query_needles.node_count)
|
||||
{
|
||||
DBGI_FuzzySearchItemChunk *chunk = items_list.last;
|
||||
if(chunk == 0 || chunk->count >= chunk->cap)
|
||||
{
|
||||
chunk = push_array(scratch.arena, DBGI_FuzzySearchItemChunk, 1);
|
||||
chunk->cap = 512;
|
||||
chunk->count = 0;
|
||||
chunk->v = push_array_no_zero(scratch.arena, DBGI_FuzzySearchItem, chunk->cap);
|
||||
SLLQueuePush(items_list.first, items_list.last, chunk);
|
||||
items_list.chunk_count += 1;
|
||||
}
|
||||
chunk->v[chunk->count].procedure_idx = procedure_idx;
|
||||
chunk->v[chunk->count].match_ranges = matches;
|
||||
chunk->count += 1;
|
||||
items_list.total_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: item list -> item array
|
||||
DBGI_FuzzySearchItemArray items = {0};
|
||||
if(task_is_good)
|
||||
{
|
||||
items.count = items_list.total_count;
|
||||
items.v = push_array_no_zero(task_arena, DBGI_FuzzySearchItem, items.count);
|
||||
U64 idx = 0;
|
||||
for(DBGI_FuzzySearchItemChunk *chunk = items_list.first; chunk != 0; chunk = chunk->next)
|
||||
{
|
||||
MemoryCopy(items.v+idx, chunk->v, sizeof(DBGI_FuzzySearchItemChunk)*chunk->count);
|
||||
idx += chunk->count;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: commit to cache
|
||||
if(task_is_good) OS_MutexScopeW(stripe->rw_mutex)
|
||||
{
|
||||
for(DBGI_FuzzySearchNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(u128_match(n->key, key))
|
||||
{
|
||||
n->gen += 1;
|
||||
n->gen_items = items;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dbgi_scope_close(scope);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
}
|
||||
|
||||
+24
-19
@@ -103,13 +103,14 @@ struct DBGI_BinaryStripe
|
||||
typedef struct DBGI_FuzzySearchItem DBGI_FuzzySearchItem;
|
||||
struct DBGI_FuzzySearchItem
|
||||
{
|
||||
U64 function_idx;
|
||||
U64 procedure_idx;
|
||||
FuzzyMatchRangeList match_ranges;
|
||||
};
|
||||
|
||||
typedef struct DBGI_FuzzySearchItemChunk DBGI_FuzzySearchItemChunk;
|
||||
struct DBGI_FuzzySearchItemChunk
|
||||
{
|
||||
DBGI_FuzzySearchItemChunk *next;
|
||||
DBGI_FuzzySearchItem *v;
|
||||
U64 count;
|
||||
U64 cap;
|
||||
@@ -131,25 +132,25 @@ struct DBGI_FuzzySearchItemArray
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct DBGI_FuzzySearchResult DBGI_FuzzySearchResult;
|
||||
struct DBGI_FuzzySearchResult
|
||||
typedef struct DBGI_FuzzySearchBucket DBGI_FuzzySearchBucket;
|
||||
struct DBGI_FuzzySearchBucket
|
||||
{
|
||||
Arena *arena;
|
||||
String8 exe_path;
|
||||
String8 query;
|
||||
DBGI_FuzzySearchItemArray items;
|
||||
};
|
||||
|
||||
typedef struct DBGI_FuzzySearchNode DBGI_FuzzySearchNode;
|
||||
struct DBGI_FuzzySearchNode
|
||||
{
|
||||
DBGI_FuzzySearchNode *next;
|
||||
DBGI_FuzzySearchNode *prev;
|
||||
U128 key;
|
||||
U64 submitted;
|
||||
U64 scope_touch_count;
|
||||
U64 last_time_submitted_us;
|
||||
DBGI_FuzzySearchBucket buckets[2];
|
||||
U64 gen;
|
||||
DBGI_FuzzySearchResult v[2];
|
||||
U64 submit_gen;
|
||||
DBGI_FuzzySearchItemArray gen_items;
|
||||
};
|
||||
|
||||
typedef struct DBGI_FuzzySearchSlot DBGI_FuzzySearchSlot;
|
||||
@@ -167,6 +168,18 @@ struct DBGI_FuzzySearchStripe
|
||||
OS_Handle cv;
|
||||
};
|
||||
|
||||
typedef struct DBGI_FuzzySearchThread DBGI_FuzzySearchThread;
|
||||
struct DBGI_FuzzySearchThread
|
||||
{
|
||||
OS_Handle thread;
|
||||
OS_Handle u2f_ring_mutex;
|
||||
OS_Handle u2f_ring_cv;
|
||||
U64 u2f_ring_size;
|
||||
U8 *u2f_ring_base;
|
||||
U64 u2f_ring_write_pos;
|
||||
U64 u2f_ring_read_pos;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Weak Access Scope Types
|
||||
|
||||
@@ -273,14 +286,6 @@ struct DBGI_Shared
|
||||
U64 u2p_ring_write_pos;
|
||||
U64 u2p_ring_read_pos;
|
||||
|
||||
// rjf: user -> fuzzy ring
|
||||
OS_Handle u2f_ring_mutex;
|
||||
OS_Handle u2f_ring_cv;
|
||||
U64 u2f_ring_size;
|
||||
U8 *u2f_ring_base;
|
||||
U64 u2f_ring_write_pos;
|
||||
U64 u2f_ring_read_pos;
|
||||
|
||||
// rjf: parse -> user event ring
|
||||
OS_Handle p2u_ring_mutex;
|
||||
OS_Handle p2u_ring_cv;
|
||||
@@ -293,7 +298,7 @@ struct DBGI_Shared
|
||||
U64 parse_thread_count;
|
||||
OS_Handle *parse_threads;
|
||||
U64 fuzzy_thread_count;
|
||||
OS_Handle *fuzzy_threads;
|
||||
DBGI_FuzzySearchThread *fuzzy_threads;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -342,7 +347,7 @@ internal DBGI_Parse *dbgi_parse_from_exe_path(DBGI_Scope *scope, String8 exe_pat
|
||||
////////////////////////////////
|
||||
//~ rjf: Fuzzy Search Cache Functions
|
||||
|
||||
internal DBGI_FuzzySearchItemArray dbgi_fuzzy_search_items_from_key_exe_query(DBGI_Scope *scope, U128 key, String8 exe_path, String8 query, U64 endt_us);
|
||||
internal DBGI_FuzzySearchItemArray dbgi_fuzzy_search_items_from_key_exe_query(DBGI_Scope *scope, U128 key, String8 exe_path, String8 query, U64 endt_us, B32 *stale_out);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Parse Threads
|
||||
@@ -358,8 +363,8 @@ internal void dbgi_parse_thread_entry_point(void *p);
|
||||
////////////////////////////////
|
||||
//~ rjf: Fuzzy Searching Threads
|
||||
|
||||
internal B32 dbgi_u2f_enqueue_req(U128 key, String8 exe_path, String8 query, U64 endt_us);
|
||||
internal void dbgi_u2f_dequeue_req(Arena *arena, U128 *key_out, String8 *exe_path_out, String8 *query_out);
|
||||
internal B32 dbgi_u2f_enqueue_req(U128 key, U64 endt_us);
|
||||
internal void dbgi_u2f_dequeue_req(Arena *arena, DBGI_FuzzySearchThread *thread, U128 *key_out);
|
||||
|
||||
internal void dbgi_fuzzy_thread__entry_point(void *p);
|
||||
|
||||
|
||||
+2
-1
@@ -10495,7 +10495,7 @@ df_fancy_string_list_from_code_string(Arena *arena, F32 alpha, B32 indirection_s
|
||||
return fancy_strings;
|
||||
}
|
||||
|
||||
internal void
|
||||
internal UI_Box *
|
||||
df_code_label(F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String8 string)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
@@ -10503,6 +10503,7 @@ df_code_label(F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String
|
||||
UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero());
|
||||
ui_box_equip_display_fancy_strings(box, &fancy_strings);
|
||||
scratch_end(scratch);
|
||||
return box;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
+1
-1
@@ -1046,7 +1046,7 @@ internal B32 df_do_dasm_controls(DASM_Handle handle, U64 line_count_per_page, Tx
|
||||
internal UI_Signal df_error_label(String8 string);
|
||||
internal B32 df_help_label(String8 string);
|
||||
internal D_FancyStringList df_fancy_string_list_from_code_string(Arena *arena, F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String8 string);
|
||||
internal void df_code_label(F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String8 string);
|
||||
internal UI_Box *df_code_label(F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String8 string);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: UI Widgets: Line Edit
|
||||
|
||||
@@ -52,10 +52,10 @@ DF_DefaultBindingTable:
|
||||
//- rjf: focused panel changing
|
||||
{ "next_panel" Comma ctrl 0 0 }
|
||||
{ "prev_panel" Comma ctrl shift 0 }
|
||||
{ "focus_panel_right" Right ctrl shift alt }
|
||||
{ "focus_panel_left" Left ctrl shift alt }
|
||||
{ "focus_panel_up" Up ctrl shift alt }
|
||||
{ "focus_panel_down" Down ctrl shift alt }
|
||||
{ "focus_panel_right" Right ctrl 0 alt }
|
||||
{ "focus_panel_left" Left ctrl 0 alt }
|
||||
{ "focus_panel_up" Up ctrl 0 alt }
|
||||
{ "focus_panel_down" Down ctrl 0 alt }
|
||||
|
||||
//- rjf: undo/redo
|
||||
//{ "undo" Z ctrl 0 0 }
|
||||
@@ -76,8 +76,8 @@ DF_DefaultBindingTable:
|
||||
{ "move_tab_right" PageDown ctrl shift 0 }
|
||||
{ "move_tab_left" PageUp ctrl shift 0 }
|
||||
{ "close_tab" W ctrl 0 0 }
|
||||
{ "tab_bar_top" Up ctrl 0 alt }
|
||||
{ "tab_bar_bottom" Down ctrl 0 alt }
|
||||
{ "tab_bar_top" Up ctrl shift alt }
|
||||
{ "tab_bar_bottom" Down ctrl shift alt }
|
||||
|
||||
//- rjf: files
|
||||
{ "open" O ctrl 0 0 }
|
||||
|
||||
@@ -2803,8 +2803,124 @@ DF_VIEW_CMD_FUNCTION_DEF(SymbolLister)
|
||||
|
||||
DF_VIEW_UI_FUNCTION_DEF(SymbolLister)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DBGI_Scope *scope = dbgi_scope_open();
|
||||
F32 row_height_px = floor_f32(ui_top_font_size()*2.5f);
|
||||
DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view);
|
||||
DF_Entity *thread = df_entity_from_handle(ctrl_ctx.thread);
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
|
||||
U64 thread_unwind_rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, ctrl_ctx.unwind_count);
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, thread_unwind_rip_vaddr);
|
||||
DF_Entity *binary = df_binary_file_from_module(module);
|
||||
String8 exe_path = df_full_path_from_entity(scratch.arena, binary);
|
||||
String8 query = str8(view->query_buffer, view->query_string_size);
|
||||
TG_Graph *graph = tg_graph_begin(bit_size_from_arch(df_architecture_from_entity(thread))/8, 256);
|
||||
|
||||
//- rjf: grab state
|
||||
typedef struct DF_SymbolListerViewState DF_SymbolListerViewState;
|
||||
struct DF_SymbolListerViewState
|
||||
{
|
||||
Vec2S64 cursor;
|
||||
};
|
||||
DF_SymbolListerViewState *slv = df_view_user_state(view, DF_SymbolListerViewState);
|
||||
|
||||
//- rjf: query -> raddbg, filtered items
|
||||
U128 fuzzy_search_key = {(U64)view, df_hash_from_string(str8_struct(&view))};
|
||||
DBGI_Parse *dbgi = dbgi_parse_from_exe_path(scope, exe_path, os_now_microseconds()+100);
|
||||
RADDBG_Parsed *rdbg = &dbgi->rdbg;
|
||||
B32 items_stale = 0;
|
||||
DBGI_FuzzySearchItemArray items = dbgi_fuzzy_search_items_from_key_exe_query(scope, fuzzy_search_key, exe_path, query, os_now_microseconds()+100, &items_stale);
|
||||
if(items_stale)
|
||||
{
|
||||
df_gfx_request_frame();
|
||||
}
|
||||
|
||||
//- rjf: submit best match when hitting enter w/ no selection
|
||||
if(slv->cursor.y == 0 && items.count != 0 && os_key_press(ui_events(), ui_window(), 0, OS_Key_Return))
|
||||
{
|
||||
U64 procedure_idx = items.v[0].procedure_idx;
|
||||
if(0 < procedure_idx && procedure_idx < rdbg->procedure_count)
|
||||
{
|
||||
RADDBG_Procedure *procedure = &rdbg->procedures[procedure_idx];
|
||||
U64 name_size = 0;
|
||||
U8 *name_base = raddbg_string_from_idx(rdbg, procedure->name_string_idx, &name_size);
|
||||
String8 name = str8(name_base, name_size);
|
||||
DF_CmdParams p = df_cmd_params_from_view(ws, panel, view);
|
||||
p.string = name;
|
||||
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_String);
|
||||
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_CompleteQuery));
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: build contents
|
||||
Rng1S64 visible_row_range = {0};
|
||||
UI_ScrollListParams scroll_list_params = {0};
|
||||
{
|
||||
Vec2F32 content_dim = dim_2f32(rect);
|
||||
scroll_list_params.flags = UI_ScrollListFlag_All;
|
||||
scroll_list_params.row_height_px = row_height_px;
|
||||
scroll_list_params.dim_px = v2f32(content_dim.x, content_dim.y);
|
||||
scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(0, items.count));
|
||||
scroll_list_params.item_range = r1s64(0, items.count);
|
||||
scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1;
|
||||
}
|
||||
UI_ScrollListSignal scroll_list_sig = {0};
|
||||
UI_Focus(UI_FocusKind_On)
|
||||
UI_ScrollList(&scroll_list_params, &view->scroll_pos.y, &slv->cursor, &visible_row_range, &scroll_list_sig)
|
||||
UI_Focus(UI_FocusKind_Null)
|
||||
UI_Font(df_font_from_slot(DF_FontSlot_Code))
|
||||
{
|
||||
//- rjf: build rows
|
||||
for(U64 idx = visible_row_range.min;
|
||||
idx <= visible_row_range.max && idx < items.count;
|
||||
idx += 1)
|
||||
UI_Focus((slv->cursor.y == idx+1) ? UI_FocusKind_On : UI_FocusKind_Off)
|
||||
{
|
||||
DBGI_FuzzySearchItem *item = &items.v[idx];
|
||||
if(item->procedure_idx >= rdbg->procedure_count) { continue; }
|
||||
RADDBG_Procedure *procedure = &rdbg->procedures[item->procedure_idx];
|
||||
U64 name_size = 0;
|
||||
U8 *name_base = raddbg_string_from_idx(rdbg, procedure->name_string_idx, &name_size);
|
||||
String8 name = str8(name_base, name_size);
|
||||
TG_Key type_key = tg_key_zero();
|
||||
if(procedure->type_idx < rdbg->type_node_count)
|
||||
{
|
||||
RADDBG_TypeNode *type_node = &rdbg->type_nodes[procedure->type_idx];
|
||||
type_key = tg_key_ext(tg_kind_from_raddbg_type_kind(type_node->kind), procedure->type_idx);
|
||||
}
|
||||
ui_set_next_hover_cursor(OS_Cursor_HandPoint);
|
||||
UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable|
|
||||
UI_BoxFlag_DrawBackground|
|
||||
UI_BoxFlag_DrawBorder|
|
||||
UI_BoxFlag_DrawText|
|
||||
UI_BoxFlag_DrawHotEffects|
|
||||
UI_BoxFlag_DrawActiveEffects,
|
||||
"###procedure_%I64x", item->procedure_idx);
|
||||
UI_Parent(box) UI_PrefWidth(ui_text_dim(10, 1))
|
||||
{
|
||||
UI_Box *box = df_code_label(1.f, 0, df_rgba_from_theme_color(DF_ThemeColor_CodeFunction), name);
|
||||
df_box_equip_fuzzy_match_range_list_vis(box, item->match_ranges);
|
||||
if(!tg_key_match(tg_key_zero(), type_key))
|
||||
{
|
||||
String8 type_string = tg_string_from_key(scratch.arena, graph, rdbg, type_key);
|
||||
df_code_label(0.5f, 0, df_rgba_from_theme_color(DF_ThemeColor_WeakText), type_string);
|
||||
}
|
||||
}
|
||||
UI_Signal sig = ui_signal_from_box(box);
|
||||
if(sig.clicked)
|
||||
{
|
||||
DF_CmdParams p = df_cmd_params_from_view(ws, panel, view);
|
||||
p.string = name;
|
||||
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_String);
|
||||
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_CompleteQuery));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dbgi_scope_close(scope);
|
||||
scratch_end(scratch);
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
@@ -956,10 +956,10 @@ DF_StringBindingPair df_g_default_binding_table[] =
|
||||
{str8_lit_comp("rotate_panel_columns"), {OS_Key_2, 0 |OS_EventFlag_Ctrl }},
|
||||
{str8_lit_comp("next_panel"), {OS_Key_Comma, 0 |OS_EventFlag_Ctrl }},
|
||||
{str8_lit_comp("prev_panel"), {OS_Key_Comma, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
|
||||
{str8_lit_comp("focus_panel_right"), {OS_Key_Right, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}},
|
||||
{str8_lit_comp("focus_panel_left"), {OS_Key_Left, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}},
|
||||
{str8_lit_comp("focus_panel_up"), {OS_Key_Up, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}},
|
||||
{str8_lit_comp("focus_panel_down"), {OS_Key_Down, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}},
|
||||
{str8_lit_comp("focus_panel_right"), {OS_Key_Right, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
|
||||
{str8_lit_comp("focus_panel_left"), {OS_Key_Left, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
|
||||
{str8_lit_comp("focus_panel_up"), {OS_Key_Up, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
|
||||
{str8_lit_comp("focus_panel_down"), {OS_Key_Down, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
|
||||
{str8_lit_comp("close_panel"), {OS_Key_P, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
|
||||
{str8_lit_comp("next_tab"), {OS_Key_PageDown, 0 |OS_EventFlag_Ctrl }},
|
||||
{str8_lit_comp("prev_tab"), {OS_Key_PageUp, 0 |OS_EventFlag_Ctrl }},
|
||||
@@ -968,8 +968,8 @@ DF_StringBindingPair df_g_default_binding_table[] =
|
||||
{str8_lit_comp("move_tab_right"), {OS_Key_PageDown, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
|
||||
{str8_lit_comp("move_tab_left"), {OS_Key_PageUp, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
|
||||
{str8_lit_comp("close_tab"), {OS_Key_W, 0 |OS_EventFlag_Ctrl }},
|
||||
{str8_lit_comp("tab_bar_top"), {OS_Key_Up, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
|
||||
{str8_lit_comp("tab_bar_bottom"), {OS_Key_Down, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
|
||||
{str8_lit_comp("tab_bar_top"), {OS_Key_Up, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}},
|
||||
{str8_lit_comp("tab_bar_bottom"), {OS_Key_Down, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}},
|
||||
{str8_lit_comp("open"), {OS_Key_O, 0 |OS_EventFlag_Ctrl }},
|
||||
{str8_lit_comp("reload_active"), {OS_Key_R, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
|
||||
{str8_lit_comp("switch"), {OS_Key_I, 0 |OS_EventFlag_Ctrl }},
|
||||
|
||||
@@ -24,11 +24,11 @@ fs_init(void)
|
||||
fs_shared->u2s_ring_base = push_array_no_zero(arena, U8, fs_shared->u2s_ring_size);
|
||||
fs_shared->u2s_ring_cv = os_condition_variable_alloc();
|
||||
fs_shared->u2s_ring_mutex = os_mutex_alloc();
|
||||
fs_shared->streamer_count = Min(4, os_logical_core_count()-1);
|
||||
fs_shared->streamer_count = Clamp(1, os_logical_core_count()-1, 4);
|
||||
fs_shared->streamers = push_array(arena, OS_Handle, 1);
|
||||
for(U64 idx = 0; idx < fs_shared->streamer_count; idx += 1)
|
||||
{
|
||||
fs_shared->streamers[idx] = os_launch_thread(fs_streamer_thread__entry_point, &idx, 0);
|
||||
fs_shared->streamers[idx] = os_launch_thread(fs_streamer_thread__entry_point, (void *)idx, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ geo_init(void)
|
||||
geo_shared->u2x_ring_base = push_array_no_zero(arena, U8, geo_shared->u2x_ring_size);
|
||||
geo_shared->u2x_ring_cv = os_condition_variable_alloc();
|
||||
geo_shared->u2x_ring_mutex = os_mutex_alloc();
|
||||
geo_shared->xfer_thread_count = Min(4, os_logical_core_count()-1);
|
||||
geo_shared->xfer_thread_count = Clamp(1, os_logical_core_count()-1, 4);
|
||||
geo_shared->xfer_threads = push_array(arena, OS_Handle, geo_shared->xfer_thread_count);
|
||||
for(U64 idx = 0; idx < geo_shared->xfer_thread_count; idx += 1)
|
||||
{
|
||||
|
||||
@@ -412,7 +412,7 @@ txt_init(void)
|
||||
txt_shared->u2p_ring_base = push_array_no_zero(arena, U8, txt_shared->u2p_ring_size);
|
||||
txt_shared->u2p_ring_cv = os_condition_variable_alloc();
|
||||
txt_shared->u2p_ring_mutex = os_mutex_alloc();
|
||||
txt_shared->parse_thread_count = Min(4, os_logical_core_count()-1);
|
||||
txt_shared->parse_thread_count = Clamp(1, os_logical_core_count()-1, 4);
|
||||
txt_shared->parse_threads = push_array(arena, OS_Handle, txt_shared->parse_thread_count);
|
||||
for(U64 idx = 0; idx < txt_shared->parse_thread_count; idx += 1)
|
||||
{
|
||||
|
||||
@@ -48,7 +48,7 @@ tex_init(void)
|
||||
tex_shared->u2x_ring_base = push_array_no_zero(arena, U8, tex_shared->u2x_ring_size);
|
||||
tex_shared->u2x_ring_cv = os_condition_variable_alloc();
|
||||
tex_shared->u2x_ring_mutex = os_mutex_alloc();
|
||||
tex_shared->xfer_thread_count = Min(4, os_logical_core_count()-1);
|
||||
tex_shared->xfer_thread_count = Clamp(1, os_logical_core_count()-1, 4);
|
||||
tex_shared->xfer_threads = push_array(arena, OS_Handle, tex_shared->xfer_thread_count);
|
||||
for(U64 idx = 0; idx < tex_shared->xfer_thread_count; idx += 1)
|
||||
{
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ txti_init(void)
|
||||
txti_state->entity_map_stripes.v[idx].cv = os_condition_variable_alloc();
|
||||
txti_state->entity_map_stripes.v[idx].rw_mutex = os_rw_mutex_alloc();
|
||||
}
|
||||
txti_state->mut_thread_count = Min(4, os_logical_core_count());
|
||||
txti_state->mut_thread_count = Clamp(1, os_logical_core_count(), 4);
|
||||
txti_state->mut_threads = push_array(txti_state->arena, TXTI_MutThread, txti_state->mut_thread_count);
|
||||
for(U64 idx = 0; idx < txti_state->mut_thread_count; idx += 1)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user