pass over hash store layer / all users, to switch to explicit 64-bit root alloc/dealloc, and 128-bit ids, for a full 192-bit hs key

This commit is contained in:
Ryan Fleury
2025-05-19 14:52:28 -07:00
parent 8b4e2a099f
commit b9e3df4cae
26 changed files with 567 additions and 307 deletions
+7
View File
@@ -61,6 +61,7 @@ async_push_work_(ASYNC_WorkFunctionType *work_function, ASYNC_WorkParams *params
work.output = params->output;
work.semaphore = params->semaphore;
work.completion_counter = params->completion_counter;
work.working_counter = params->working_counter;
// rjf: loop; try to write into user -> writer ring buffer. if we're on a
// worker thread, determine if we need to execute this task locally on this
@@ -227,6 +228,12 @@ async_execute_work(ASYNC_Work work)
{
ins_atomic_u64_inc_eval(work.completion_counter);
}
//- rjf: decrement working counter
if(work.working_counter != 0)
{
ins_atomic_u64_dec_eval(work.working_counter);
}
}
////////////////////////////////
+2
View File
@@ -29,6 +29,7 @@ struct ASYNC_WorkParams
void **output;
OS_Handle semaphore;
U64 *completion_counter;
U64 *working_counter;
U64 endt_us;
ASYNC_Priority priority;
};
@@ -41,6 +42,7 @@ struct ASYNC_Work
void **output;
OS_Handle semaphore;
U64 *completion_counter;
U64 *working_counter;
};
////////////////////////////////
+206 -45
View File
@@ -1577,8 +1577,188 @@ ctrl_set_wakeup_hook(CTRL_WakeupFunctionType *wakeup_hook)
////////////////////////////////
//~ rjf: Process Memory Functions
//- rjf: process memory cache key reading
internal HS_Key
ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us, B32 *out_is_stale)
{
CTRL_ProcessMemoryCache *cache = &ctrl_state->process_memory_cache;
//- rjf: unpack process key
U64 process_hash = ctrl_hash_from_handle(process);
U64 process_slot_idx = process_hash%cache->slots_count;
U64 process_stripe_idx = process_slot_idx%cache->stripes_count;
CTRL_ProcessMemoryCacheSlot *process_slot = &cache->slots[process_slot_idx];
CTRL_ProcessMemoryCacheStripe *process_stripe = &cache->stripes[process_stripe_idx];
//- rjf: get the hash store root for this process; construct process node if it
// doesn't exist
HS_Root root = {0};
{
B32 node_found = 0;
OS_MutexScopeR(process_stripe->rw_mutex)
{
for(CTRL_ProcessMemoryCacheNode *n = process_slot->first; n != 0; n = n->next)
{
if(ctrl_handle_match(n->handle, process))
{
node_found = 1;
root = n->root;
break;
}
}
}
if(!node_found) OS_MutexScopeW(process_stripe->rw_mutex)
{
for(CTRL_ProcessMemoryCacheNode *n = process_slot->first; n != 0; n = n->next)
{
if(ctrl_handle_match(n->handle, process))
{
node_found = 1;
root = n->root;
break;
}
}
if(!node_found)
{
Arena *node_arena = arena_alloc();
CTRL_ProcessMemoryCacheNode *node = push_array(node_arena, CTRL_ProcessMemoryCacheNode, 1);
DLLPushBack(process_slot->first, process_slot->last, node);
node->arena = node_arena;
node->handle = process;
node->root = hs_root_alloc();
node->range_hash_slots_count = 1024;
node->range_hash_slots = push_array(node_arena, CTRL_ProcessMemoryRangeHashSlot, node->range_hash_slots_count);
root = node->root;
}
}
}
//- rjf: form ID for this process memory query
HS_ID id = {0};
{
id.u128[0].u64[0] = vaddr_range.min & 0x00ffffffffffffffull;
id.u128[0].u64[1] = vaddr_range.max & 0x00ffffffffffffffull;
if(zero_terminated)
{
id.u128[0].u64[0] |= (1ull << 63);
}
}
U64 range_hash = hs_little_hash_from_data(str8_struct(&id));
//- rjf: form full key
HS_Key key = hs_key_make(root, id);
//- rjf: loop: try to look for current results, request if not there, wait if we can, repeat until we can't
U64 mem_gen = ctrl_mem_gen();
B32 key_is_stale = 0;
for(;;)
{
//- rjf: step 1: [read-only] try to look for current results for key's ID
B32 id_exists = 0;
B32 id_stale = 0;
OS_MutexScopeR(process_stripe->rw_mutex)
{
for(CTRL_ProcessMemoryCacheNode *process_n = process_slot->first; process_n != 0; process_n = process_n->next)
{
if(ctrl_handle_match(process_n->handle, process))
{
U64 range_slot_idx = range_hash%process_n->range_hash_slots_count;
CTRL_ProcessMemoryRangeHashSlot *range_slot = &process_n->range_hash_slots[range_slot_idx];
for(CTRL_ProcessMemoryRangeHashNode *n = range_slot->first; n != 0; n = n->next)
{
if(hs_id_match(n->id, id))
{
id_exists = 1;
id_stale = (n->mem_gen < mem_gen);
goto end_fast_lookup;
}
}
}
}
end_fast_lookup:;
}
key_is_stale = id_stale;
//- rjf: step 2: if the ID exists and is not stale, then we're done;
// the hash store contains the most up-to-date representation of the
// process memory for this key.
if(id_exists && !id_stale)
{
break;
}
//- rjf: step 3: if the ID does not exist in the process' cache, then we
// need to build a node for it. if that, or if the ID is stale, then also
// request that that range is streamed.
if(!id_exists || (id_exists && id_stale))
{
B32 node_needs_stream = 0;
U64 *node_working_count = 0;
OS_MutexScopeW(process_stripe->rw_mutex)
{
for(CTRL_ProcessMemoryCacheNode *process_n = process_slot->first; process_n != 0; process_n = process_n->next)
{
if(ctrl_handle_match(process_n->handle, process))
{
U64 range_slot_idx = range_hash%process_n->range_hash_slots_count;
CTRL_ProcessMemoryRangeHashSlot *range_slot = &process_n->range_hash_slots[range_slot_idx];
CTRL_ProcessMemoryRangeHashNode *range_n = 0;
for(CTRL_ProcessMemoryRangeHashNode *n = range_slot->first; n != 0; n = n->next)
{
if(hs_id_match(n->id, id))
{
range_n = n;
break;
}
}
if(range_n == 0)
{
range_n = push_array(process_n->arena, CTRL_ProcessMemoryRangeHashNode, 1);
SLLQueuePush(range_slot->first, range_slot->last, range_n);
range_n->vaddr_range = vaddr_range;
range_n->zero_terminated = zero_terminated;
range_n->id = id;
range_n->working_count += 1;
node_needs_stream = 1;
}
else
{
node_needs_stream = (range_n->mem_gen < mem_gen);
}
node_working_count = &range_n->working_count;
break;
}
}
}
if(node_needs_stream)
{
ctrl_u2ms_enqueue_req(key, process, vaddr_range, zero_terminated, max_U64);
async_push_work(ctrl_mem_stream_work, .working_counter = node_working_count);
}
}
//- rjf: step 4: if we have no time to wait, then abort; otherwise,
// wait on this process' stripe
if(os_now_microseconds() >= endt_us)
{
break;
}
else OS_MutexScopeR(process_stripe->rw_mutex)
{
os_condition_variable_wait_rw_r(process_stripe->cv, process_stripe->rw_mutex, endt_us);
}
}
if(out_is_stale)
{
*out_is_stale = key_is_stale;
}
return key;
}
//- rjf: process memory cache interaction
#if 0 // TODO(rjf): @hs
internal U128
ctrl_calc_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated)
{
@@ -1758,9 +1938,11 @@ ctrl_stored_hash_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B3
ProfEnd();
return result;
}
#endif
//- rjf: bundled key/stream helper
#if 0 // TODO(rjf): @hs
internal U128
ctrl_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated)
{
@@ -1768,6 +1950,7 @@ ctrl_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range,
ctrl_stored_hash_from_process_vaddr_range(process, range, zero_terminated, 0, 0);
return key;
}
#endif
//- rjf: process memory cache reading helpers
@@ -1798,9 +1981,9 @@ ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rn
for(U64 page_idx = 0; page_idx < page_count; page_idx += 1)
{
U64 page_base_vaddr = page_range.min + page_idx*page_size;
U128 page_key = ctrl_calc_hash_store_key_from_process_vaddr_range(process, r1u64(page_base_vaddr, page_base_vaddr+page_size), 0);
B32 page_is_stale = 0;
U128 page_hash = ctrl_stored_hash_from_process_vaddr_range(process, r1u64(page_base_vaddr, page_base_vaddr+page_size), 0, &page_is_stale, endt_us);
HS_Key page_key = ctrl_key_from_process_vaddr_range(process, r1u64(page_base_vaddr, page_base_vaddr+page_size), 0, endt_us, &page_is_stale);
U128 page_hash = hs_hash_from_key(page_key, 0);
U128 page_last_hash = hs_hash_from_key(page_key, 1);
result.stale = (result.stale || page_is_stale);
page_hashes[page_idx] = page_hash;
@@ -6542,16 +6725,17 @@ ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
//- rjf: user -> memory stream communication
internal B32
ctrl_u2ms_enqueue_req(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us)
ctrl_u2ms_enqueue_req(HS_Key key, CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us)
{
B32 good = 0;
OS_MutexScope(ctrl_state->u2ms_ring_mutex) for(;;)
{
U64 unconsumed_size = ctrl_state->u2ms_ring_write_pos-ctrl_state->u2ms_ring_read_pos;
U64 available_size = ctrl_state->u2ms_ring_size-unconsumed_size;
if(available_size >= sizeof(process)+sizeof(vaddr_range)+sizeof(zero_terminated))
if(available_size >= sizeof(key)+sizeof(process)+sizeof(vaddr_range)+sizeof(zero_terminated))
{
good = 1;
ctrl_state->u2ms_ring_write_pos += ring_write_struct(ctrl_state->u2ms_ring_base, ctrl_state->u2ms_ring_size, ctrl_state->u2ms_ring_write_pos, &key);
ctrl_state->u2ms_ring_write_pos += ring_write_struct(ctrl_state->u2ms_ring_base, ctrl_state->u2ms_ring_size, ctrl_state->u2ms_ring_write_pos, &process);
ctrl_state->u2ms_ring_write_pos += ring_write_struct(ctrl_state->u2ms_ring_base, ctrl_state->u2ms_ring_size, ctrl_state->u2ms_ring_write_pos, &vaddr_range);
ctrl_state->u2ms_ring_write_pos += ring_write_struct(ctrl_state->u2ms_ring_base, ctrl_state->u2ms_ring_size, ctrl_state->u2ms_ring_write_pos, &zero_terminated);
@@ -6565,13 +6749,14 @@ ctrl_u2ms_enqueue_req(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_termina
}
internal void
ctrl_u2ms_dequeue_req(CTRL_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated)
ctrl_u2ms_dequeue_req(HS_Key *out_key, CTRL_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated)
{
OS_MutexScope(ctrl_state->u2ms_ring_mutex) for(;;)
{
U64 unconsumed_size = ctrl_state->u2ms_ring_write_pos-ctrl_state->u2ms_ring_read_pos;
if(unconsumed_size >= sizeof(*out_process)+sizeof(*out_vaddr_range)+sizeof(*out_zero_terminated))
if(unconsumed_size >= sizeof(*out_key)+sizeof(*out_process)+sizeof(*out_vaddr_range)+sizeof(*out_zero_terminated))
{
ctrl_state->u2ms_ring_read_pos += ring_read_struct(ctrl_state->u2ms_ring_base, ctrl_state->u2ms_ring_size, ctrl_state->u2ms_ring_read_pos, out_key);
ctrl_state->u2ms_ring_read_pos += ring_read_struct(ctrl_state->u2ms_ring_base, ctrl_state->u2ms_ring_size, ctrl_state->u2ms_ring_read_pos, out_process);
ctrl_state->u2ms_ring_read_pos += ring_read_struct(ctrl_state->u2ms_ring_base, ctrl_state->u2ms_ring_size, ctrl_state->u2ms_ring_read_pos, out_vaddr_range);
ctrl_state->u2ms_ring_read_pos += ring_read_struct(ctrl_state->u2ms_ring_base, ctrl_state->u2ms_ring_size, ctrl_state->u2ms_ring_read_pos, out_zero_terminated);
@@ -6590,50 +6775,29 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work)
CTRL_ProcessMemoryCache *cache = &ctrl_state->process_memory_cache;
//- rjf: unpack next request
HS_Key key = {0};
CTRL_Handle process = {0};
Rng1U64 vaddr_range = {0};
B32 zero_terminated = 0;
ctrl_u2ms_dequeue_req(&process, &vaddr_range, &zero_terminated);
U128 key = ctrl_calc_hash_store_key_from_process_vaddr_range(process, vaddr_range, zero_terminated);
ctrl_u2ms_dequeue_req(&key, &process, &vaddr_range, &zero_terminated);
ProfBegin("memory stream request");
//- rjf: unpack process memory cache key
U64 process_hash = ctrl_hash_from_string(str8_struct(&process));
//- rjf: unpack process key
U64 process_hash = ctrl_hash_from_handle(process);
U64 process_slot_idx = process_hash%cache->slots_count;
U64 process_stripe_idx = process_slot_idx%cache->stripes_count;
CTRL_ProcessMemoryCacheSlot *process_slot = &cache->slots[process_slot_idx];
CTRL_ProcessMemoryCacheStripe *process_stripe = &cache->stripes[process_stripe_idx];
//- rjf: unpack address range hash cache key
U64 range_hash = ctrl_hash_from_string(str8_struct(&vaddr_range));
U64 range_hash = hs_little_hash_from_data(str8_struct(&key.id));
//- rjf: take task
B32 got_task = 0;
U64 preexisting_mem_gen = 0;
U128 preexisting_hash = {0};
Rng1U64 vaddr_range_clamped = {0};
OS_MutexScopeW(process_stripe->rw_mutex)
//- rjf: clamp vaddr range
Rng1U64 vaddr_range_clamped = vaddr_range;
{
for(CTRL_ProcessMemoryCacheNode *n = process_slot->first; n != 0; n = n->next)
{
if(ctrl_handle_match(n->handle, process))
{
U64 range_slot_idx = range_hash%n->range_hash_slots_count;
CTRL_ProcessMemoryRangeHashSlot *range_slot = &n->range_hash_slots[range_slot_idx];
for(CTRL_ProcessMemoryRangeHashNode *range_n = range_slot->first; range_n != 0; range_n = range_n->next)
{
if(MemoryMatchStruct(&range_n->vaddr_range, &vaddr_range) && range_n->zero_terminated == zero_terminated)
{
got_task = !ins_atomic_u32_eval_cond_assign(&range_n->is_taken, 1, 0);
preexisting_mem_gen = range_n->mem_gen;
preexisting_hash = range_n->hash;
vaddr_range_clamped = range_n->vaddr_range_clamped;
goto take_task__break_all;
}
}
}
}
take_task__break_all:;
vaddr_range_clamped.max = Max(vaddr_range_clamped.max, vaddr_range_clamped.min);
U64 max_size_cap = Min(max_U64-vaddr_range_clamped.min, GB(1));
vaddr_range_clamped.max = Min(vaddr_range_clamped.max, vaddr_range_clamped.min+max_size_cap);
}
//- rjf: task was taken -> read memory
@@ -6641,9 +6805,8 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work)
Arena *range_arena = 0;
void *range_base = 0;
U64 zero_terminated_size = 0;
U64 pre_read_mem_gen = dmn_mem_gen();
U64 pre_read_mem_gen = ctrl_mem_gen();
U64 post_read_mem_gen = 0;
if(got_task && pre_read_mem_gen != preexisting_mem_gen)
{
range_size = dim_1u64(vaddr_range_clamped);
U64 page_size = os_get_system_info()->page_size;
@@ -6708,7 +6871,7 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work)
//- rjf: read successful -> submit to hash store
U128 hash = {0};
if(got_task && range_base != 0 && pre_read_mem_gen == post_read_mem_gen)
if(range_base != 0 && pre_read_mem_gen == post_read_mem_gen)
{
hash = hs_submit_data(key, &range_arena, str8((U8*)range_base, zero_terminated_size));
}
@@ -6717,8 +6880,8 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work)
arena_release(range_arena);
}
//- rjf: commit hash to cache
if(got_task) OS_MutexScopeW(process_stripe->rw_mutex)
//- rjf: commit new info to cache
OS_MutexScopeW(process_stripe->rw_mutex)
{
for(CTRL_ProcessMemoryCacheNode *n = process_slot->first; n != 0; n = n->next)
{
@@ -6728,14 +6891,12 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work)
CTRL_ProcessMemoryRangeHashSlot *range_slot = &n->range_hash_slots[range_slot_idx];
for(CTRL_ProcessMemoryRangeHashNode *range_n = range_slot->first; range_n != 0; range_n = range_n->next)
{
if(MemoryMatchStruct(&range_n->vaddr_range, &vaddr_range) && range_n->zero_terminated == zero_terminated)
if(hs_id_match(range_n->id, key.id))
{
if(!u128_match(u128_zero(), hash))
{
range_n->hash = hash;
range_n->mem_gen = post_read_mem_gen;
}
ins_atomic_u32_eval_assign(&range_n->is_taken, 0);
goto commit__break_all;
}
}
+19 -5
View File
@@ -505,13 +505,19 @@ typedef struct CTRL_ProcessMemoryRangeHashNode CTRL_ProcessMemoryRangeHashNode;
struct CTRL_ProcessMemoryRangeHashNode
{
CTRL_ProcessMemoryRangeHashNode *next;
// rjf: key
Rng1U64 vaddr_range;
B32 zero_terminated;
Rng1U64 vaddr_range_clamped;
U128 hash;
HS_ID id;
// rjf: staleness info
U64 mem_gen;
// rjf: metadata
U64 working_count;
U64 last_time_requested_us;
B32 is_taken;
U64 last_user_clock_idx_touched;
};
typedef struct CTRL_ProcessMemoryRangeHashSlot CTRL_ProcessMemoryRangeHashSlot;
@@ -528,6 +534,7 @@ struct CTRL_ProcessMemoryCacheNode
CTRL_ProcessMemoryCacheNode *prev;
Arena *arena;
CTRL_Handle handle;
HS_Root root;
U64 range_hash_slots_count;
CTRL_ProcessMemoryRangeHashSlot *range_hash_slots;
};
@@ -983,12 +990,19 @@ internal void ctrl_set_wakeup_hook(CTRL_WakeupFunctionType *wakeup_hook);
////////////////////////////////
//~ rjf: Process Memory Functions
//- rjf: process memory cache key reading
internal HS_Key ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us, B32 *out_is_stale);
//- rjf: process memory cache interaction
#if 0 // TODO(rjf): @hs
internal U128 ctrl_calc_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated);
internal U128 ctrl_stored_hash_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated, B32 *out_is_stale, U64 endt_us);
#endif
//- rjf: bundled key/stream helper
#if 0 // TODO(rjf): @hs
internal U128 ctrl_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated);
#endif
//- rjf: process memory cache reading helpers
internal CTRL_ProcessMemorySlice ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rng1U64 range, U64 endt_us);
@@ -1114,8 +1128,8 @@ internal void ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
//~ rjf: Asynchronous Memory Streaming Functions
//- rjf: user -> memory stream communication
internal B32 ctrl_u2ms_enqueue_req(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us);
internal void ctrl_u2ms_dequeue_req(CTRL_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated);
internal B32 ctrl_u2ms_enqueue_req(HS_Key key, CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us);
internal void ctrl_u2ms_dequeue_req(HS_Key *out_key, CTRL_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated);
//- rjf: entry point
ASYNC_WORK_DEF(ctrl_mem_stream_work);
+38 -67
View File
@@ -345,10 +345,13 @@ dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params)
DASM_Info info = {0};
if(!u128_match(hash, u128_zero()))
{
//- 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: try to get existing results
B32 found = 0;
OS_MutexScopeR(stripe->rw_mutex)
{
@@ -363,9 +366,13 @@ dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params)
}
}
}
B32 node_is_new = 0;
//- rjf: miss -> kick off work to fill cache
if(!found)
{
B32 node_is_new = 0;
U64 *node_working_count = 0;
HS_Root root = {0};
OS_MutexScopeW(stripe->rw_mutex)
{
DASM_Node *node = 0;
@@ -379,16 +386,7 @@ dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params)
}
if(node == 0)
{
LogInfoNamedBlockF("dasm_new_node")
{
log_infof("hash: [0x%I64x 0x%I64x]\n", hash.u64[0], hash.u64[1]);
log_infof("vaddr: 0x%I64x\n", params->vaddr);
log_infof("arch: %S\n", string_from_arch(params->arch));
log_infof("style_flags: 0x%x\n", params->style_flags);
log_infof("syntax: %i\n", params->syntax);
log_infof("base_vaddr: 0x%I64x\n", params->base_vaddr);
log_infof("dbgi_key: [%S 0x%I64x]\n", params->dbgi_key.path, params->dbgi_key.min_timestamp);
}
// rjf: allocate node
node = stripe->free_node;
if(node)
{
@@ -399,26 +397,34 @@ 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;
}
}
}
if(node_is_new)
{
dasm_u2p_enqueue_req(hash, params, max_U64);
async_push_work(dasm_parse_work);
if(node_is_new)
{
dasm_u2p_enqueue_req(root, hash, params, max_U64);
async_push_work(dasm_parse_work, .working_counter = node_working_count);
}
}
}
return info;
}
internal DASM_Info
dasm_info_from_key_params(DASM_Scope *scope, U128 key, DASM_Params *params, U128 *hash_out)
dasm_info_from_key_params(DASM_Scope *scope, HS_Key key, DASM_Params *params, U128 *hash_out)
{
DASM_Info result = {0};
for(U64 rewind_idx = 0; rewind_idx < HS_KEY_HASH_HISTORY_COUNT; rewind_idx += 1)
@@ -441,16 +447,17 @@ dasm_info_from_key_params(DASM_Scope *scope, U128 key, DASM_Params *params, U128
//~ rjf: Parse Threads
internal B32
dasm_u2p_enqueue_req(U128 hash, DASM_Params *params, U64 endt_us)
dasm_u2p_enqueue_req(HS_Root root, U128 hash, DASM_Params *params, U64 endt_us)
{
B32 good = 0;
OS_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(hash)+sizeof(U64)+sizeof(Arch)+sizeof(DASM_StyleFlags)+sizeof(DASM_Syntax)+sizeof(U64)+sizeof(U64)+params->dbgi_key.path.size+sizeof(U64))
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, &params->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, &params->arch);
@@ -476,13 +483,14 @@ dasm_u2p_enqueue_req(U128 hash, DASM_Params *params, U64 endt_us)
}
internal void
dasm_u2p_dequeue_req(Arena *arena, U128 *hash_out, DASM_Params *params_out)
dasm_u2p_dequeue_req(Arena *arena, HS_Root *root_out, U128 *hash_out, DASM_Params *params_out)
{
OS_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, &params_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, &params_out->arch);
@@ -509,9 +517,10 @@ ASYNC_WORK_DEF(dasm_parse_work)
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, &hash, &params);
dasm_u2p_dequeue_req(scratch.arena, &root, &hash, &params);
U64 change_gen = fs_change_gen();
//- rjf: unpack hash
@@ -520,38 +529,19 @@ ASYNC_WORK_DEF(dasm_parse_work)
DASM_Slot *slot = &dasm_shared->slots[slot_idx];
DASM_Stripe *stripe = &dasm_shared->stripes[stripe_idx];
//- rjf: take task
B32 got_task = 0;
OS_MutexScopeR(stripe->rw_mutex)
{
for(DASM_Node *n = slot->first; n != 0; n = n->next)
{
if(u128_match(n->hash, hash) && dasm_params_match(&n->params, &params))
{
got_task = !ins_atomic_u32_eval_cond_assign(&n->is_working, 1, 0);
break;
}
}
}
//- rjf: get dbg info
RDI_Parsed *rdi = &rdi_parsed_nil;
if(got_task && params.dbgi_key.path.size != 0)
if(params.dbgi_key.path.size != 0)
{
rdi = di_rdi_from_key(di_scope, &params.dbgi_key, max_U64);
}
//- rjf: hash -> data
String8 data = {0};
if(got_task)
{
data = hs_data_from_hash(hs_scope, hash);
}
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};
if(got_task)
{
switch(params.arch)
{
@@ -621,7 +611,7 @@ ASYNC_WORK_DEF(dasm_parse_work)
{
// 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
U128 key = fs_key_from_path_range(file_normalized_full_path, r1u64(0, max_U64));
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};
@@ -712,7 +702,6 @@ ASYNC_WORK_DEF(dasm_parse_work)
//- rjf: artifacts -> value bundle
Arena *info_arena = 0;
DASM_Info info = {0};
if(got_task)
{
//- rjf: produce joined text
Arena *text_arena = arena_alloc();
@@ -721,21 +710,7 @@ ASYNC_WORK_DEF(dasm_parse_work)
String8 text = str8_list_join(text_arena, &inst_strings, &text_join);
//- rjf: produce unique key for this disassembly's text
U128 text_key = {0};
{
U64 hash_data[] =
{
hash.u64[0],
hash.u64[1],
params.vaddr,
(U64)params.arch,
(U64)params.style_flags,
(U64)params.syntax,
(U64)rdi,
0x4d534144,
};
text_key = hs_hash_from_data(str8((U8 *)hash_data, sizeof(hash_data)));
}
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);
@@ -747,7 +722,7 @@ ASYNC_WORK_DEF(dasm_parse_work)
}
//- rjf: commit results to cache
if(got_task) OS_MutexScopeW(stripe->rw_mutex)
OS_MutexScopeW(stripe->rw_mutex)
{
for(DASM_Node *n = slot->first; n != 0; n = n->next)
{
@@ -763,8 +738,6 @@ ASYNC_WORK_DEF(dasm_parse_work)
{
n->change_gen = 0;
}
ins_atomic_u32_eval_assign(&n->is_working, 0);
ins_atomic_u64_inc_eval(&n->load_count);
break;
}
}
@@ -807,8 +780,7 @@ dasm_evictor_detector_thread__entry_point(void *p)
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 &&
n->load_count != 0 &&
n->is_working == 0)
ins_atomic_u64_eval(&n->working_count) == 0)
{
slot_has_work = 1;
break;
@@ -830,8 +802,7 @@ dasm_evictor_detector_thread__entry_point(void *p)
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 &&
n->load_count != 0 &&
n->is_working == 0)
ins_atomic_u64_eval(&n->working_count) == 0)
{
DLLRemove(slot->first, slot->last, n);
if(n->info_arena != 0)
@@ -844,7 +815,7 @@ dasm_evictor_detector_thread__entry_point(void *p)
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))
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();
+8 -6
View File
@@ -159,7 +159,7 @@ struct DASM_Result
typedef struct DASM_Info DASM_Info;
struct DASM_Info
{
U128 text_key;
HS_Key text_key;
DASM_LineArray lines;
};
@@ -177,6 +177,9 @@ struct DASM_Node
U128 hash;
DASM_Params params;
// rjf: root
HS_Root root;
// rjf: generations
U64 change_gen;
@@ -185,11 +188,10 @@ struct DASM_Node
DASM_Info info;
// rjf: metadata
B32 is_working;
U64 working_count;
U64 scope_ref_count;
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;
};
@@ -309,13 +311,13 @@ internal void dasm_scope_touch_node__stripe_r_guarded(DASM_Scope *scope, DASM_No
//~ rjf: Cache Lookups
internal DASM_Info dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params);
internal DASM_Info dasm_info_from_key_params(DASM_Scope *scope, U128 key, DASM_Params *params, U128 *hash_out);
internal DASM_Info dasm_info_from_key_params(DASM_Scope *scope, HS_Key key, DASM_Params *params, U128 *hash_out);
////////////////////////////////
//~ rjf: Parse Threads
internal B32 dasm_u2p_enqueue_req(U128 hash, DASM_Params *params, U64 endt_us);
internal void dasm_u2p_dequeue_req(Arena *arena, U128 *hash_out, DASM_Params *params_out);
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);
////////////////////////////////
+1 -1
View File
@@ -1443,7 +1443,7 @@ d_init(void)
d_state = push_array(arena, D_State, 1);
d_state->arena = arena;
d_state->cmds_arena = arena_alloc();
d_state->output_log_key = hs_hash_from_data(str8_lit("output_log_key"));
d_state->output_log_key = hs_key_make(hs_root_alloc(), hs_id_make(0, 0));
hs_submit_data(d_state->output_log_key, 0, str8_zero());
d_state->ctrl_entity_store = ctrl_entity_ctx_rw_store_alloc();
d_state->ctrl_stop_arena = arena_alloc();
+1 -1
View File
@@ -312,7 +312,7 @@ struct D_State
D_CmdList cmds;
// rjf: output log key
U128 output_log_key;
HS_Key output_log_key;
// rjf: per-run caches
D_UnwindCache unwind_cache;
+137 -109
View File
@@ -71,125 +71,151 @@ fs_change_gen(void)
////////////////////////////////
//~ rjf: Cache Interaction
internal U128
fs_hash_from_path_range(String8 path, Rng1U64 range, U64 endt_us)
internal HS_Key
fs_key_from_path_range(String8 path, Rng1U64 range, U64 endt_us)
{
Temp scratch = scratch_begin(0, 0);
//- rjf: unpack args
path = path_normalized_from_string(scratch.arena, path);
U128 key = fs_big_hash_from_string_range(path, range);
U64 path_little_hash = fs_little_hash_from_string(path);
U64 path_slot_idx = path_little_hash%fs_shared->slots_count;
U64 path_stripe_idx = path_slot_idx%fs_shared->stripes_count;
FS_Slot *path_slot = &fs_shared->slots[path_slot_idx];
FS_Stripe *path_stripe = &fs_shared->stripes[path_stripe_idx];
//- rjf: loop through key -> hash history; obtain most recent hash for this key
U128 result = {0};
for(U64 rewind_idx = 0; rewind_idx < HS_KEY_HASH_HISTORY_COUNT; rewind_idx += 1)
//- rjf: get root for this path
HS_Root root = {0};
OS_MutexScopeR(path_stripe->rw_mutex)
{
result = hs_hash_from_key(key, rewind_idx);
//- rjf: nonzero hash -> got valid results, return
if(!u128_match(result, u128_zero()))
B32 node_found = 0;
for(FS_Node *n = path_slot->first; n != 0; n = n->next)
{
break;
}
//- rjf: zero hash, not rewound? -> send new stream request if needed
else if(u128_match(result, u128_zero()) && rewind_idx == 0)
{
// rjf: unpack path cache info
U64 path_little_hash = fs_little_hash_from_string(path);
U64 path_slot_idx = path_little_hash%fs_shared->slots_count;
U64 path_stripe_idx = path_slot_idx%fs_shared->stripes_count;
FS_Slot *path_slot = &fs_shared->slots[path_slot_idx];
FS_Stripe *path_stripe = &fs_shared->stripes[path_stripe_idx];
// rjf: loop: request, check for results, return until we can't
OS_MutexScopeW(path_stripe->rw_mutex) for(;;)
if(str8_match(n->path, path, 0))
{
// rjf: path -> node
FS_Node *node = 0;
for(FS_Node *n = path_slot->first; n != 0; n = n->next)
{
if(str8_match(path, n->path, 0))
{
node = n;
break;
}
}
// rjf: node does not exist? -> create & store
if(node == 0)
{
node = push_array(path_stripe->arena, FS_Node, 1);
SLLQueuePush(path_slot->first, path_slot->last, node);
node->path = push_str8_copy(path_stripe->arena, path);
node->slots_count = 64;
node->slots = push_array(path_stripe->arena, FS_RangeSlot, node->slots_count);
}
// rjf: range -> node
U64 range_hash = fs_little_hash_from_string(str8_struct(&range));
U64 range_slot_idx = range_hash%node->slots_count;
FS_RangeSlot *range_slot = &node->slots[range_slot_idx];
FS_RangeNode *range_node = 0;
for(FS_RangeNode *n = range_slot->first; n != 0; n = n->next)
{
if(MemoryMatchStruct(&n->range, &range))
{
range_node = n;
break;
}
}
// rjf: range node does not exist? create & store
if(range_node == 0)
{
range_node = push_array(path_stripe->arena, FS_RangeNode, 1);
SLLQueuePush(range_slot->first, range_slot->last, range_node);
range_node->range = range;
}
// rjf: try to send stream request
if((ins_atomic_u64_eval(&range_node->request_count) == ins_atomic_u64_eval(&range_node->completion_count) ||
ins_atomic_u64_eval(&range_node->last_time_requested_us)+100000 < os_now_microseconds()) &&
fs_u2s_enqueue_req(range, path, endt_us))
{
ins_atomic_u64_eval_assign(&range_node->last_time_requested_us, os_now_microseconds());
ins_atomic_u64_inc_eval(&range_node->request_count);
DeferLoop(os_rw_mutex_drop_w(path_stripe->rw_mutex), os_rw_mutex_take_w(path_stripe->rw_mutex))
{
async_push_work(fs_stream_work, .completion_counter = &range_node->completion_count);
}
}
// rjf: try to reobtain results
result = hs_hash_from_key(key, 0);
// rjf: have time to wait? -> wait on this stripe; otherwise exit
if(u128_match(result, u128_zero()) && os_now_microseconds() <= endt_us)
{
os_condition_variable_wait_rw_w(path_stripe->cv, path_stripe->rw_mutex, endt_us);
}
else
node_found = 1;
root = n->root;
break;
}
}
if(!node_found) OS_MutexScopeRWPromote(path_stripe->rw_mutex)
{
B32 node_found = 0;
for(FS_Node *n = path_slot->first; n != 0; n = n->next)
{
if(str8_match(n->path, path, 0))
{
node_found = 1;
root = n->root;
break;
}
}
if(!node_found)
{
FS_Node *node = push_array(path_stripe->arena, FS_Node, 1);
SLLQueuePush(path_slot->first, path_slot->last, node);
node->path = push_str8_copy(path_stripe->arena, path);
node->root = hs_root_alloc();
node->slots_count = 64;
node->slots = push_array(path_stripe->arena, FS_RangeSlot, node->slots_count);
root = node->root;
}
}
}
//- rjf: build a key for this path/range combo
HS_Key key = hs_key_make(root, hs_id_make(range.min, range.max));
//- rjf: if the most recent hash for this key is zero, then try to submit a new
// request to pull it in.
if(u128_match(hs_hash_from_key(key, 0), u128_zero()))
{
// rjf: loop: request, check for results, return until we can't
OS_MutexScopeW(path_stripe->rw_mutex) for(;;)
{
// rjf: path -> node
FS_Node *node = 0;
for(FS_Node *n = path_slot->first; n != 0; n = n->next)
{
if(str8_match(path, n->path, 0))
{
node = n;
break;
}
}
// rjf: no node? -> weird case, node should've been made at this point.
if(node == 0)
{
break;
}
// rjf: range -> node
U64 range_hash = fs_little_hash_from_string(str8_struct(&key.id));
U64 range_slot_idx = range_hash%node->slots_count;
FS_RangeSlot *range_slot = &node->slots[range_slot_idx];
FS_RangeNode *range_node = 0;
for(FS_RangeNode *n = range_slot->first; n != 0; n = n->next)
{
if(hs_id_match(n->id, key.id))
{
range_node = n;
break;
}
}
// rjf: range node does not exist? create & store
if(range_node == 0)
{
range_node = push_array(path_stripe->arena, FS_RangeNode, 1);
SLLQueuePush(range_slot->first, range_slot->last, range_node);
range_node->id = key.id;
}
// rjf: try to send stream request
if(ins_atomic_u64_eval(&range_node->working_count) == 0 &&
fs_u2s_enqueue_req(key, range, path, endt_us))
{
ins_atomic_u64_inc_eval(&range_node->working_count);
DeferLoop(os_rw_mutex_drop_w(path_stripe->rw_mutex), os_rw_mutex_take_w(path_stripe->rw_mutex))
{
async_push_work(fs_stream_work, .working_counter = &range_node->working_count);
}
}
// rjf: have time to wait? -> wait on this stripe; otherwise exit
B32 have_results = !u128_match(hs_hash_from_key(key, 0), u128_zero());
if(!have_results && os_now_microseconds() < endt_us)
{
os_condition_variable_wait_rw_w(path_stripe->cv, path_stripe->rw_mutex, endt_us);
}
else
{
break;
}
}
}
scratch_end(scratch);
return result;
return key;
}
internal U128
fs_key_from_path_range(String8 path, Rng1U64 range)
fs_hash_from_path_range(String8 path, Rng1U64 range, U64 endt_us)
{
Temp scratch = scratch_begin(0, 0);
String8 path_normalized = path_normalized_from_string(scratch.arena, path);
U128 key = fs_big_hash_from_string_range(path_normalized, range);
fs_hash_from_path_range(path_normalized, range, 0);
scratch_end(scratch);
return key;
U128 hash = {0};
{
HS_Key key = fs_key_from_path_range(path, range, endt_us);
for EachIndex(rewind_idx, HS_KEY_HASH_HISTORY_COUNT)
{
hash = hs_hash_from_key(key, rewind_idx);
if(!u128_match(hash, u128_zero()))
{
break;
}
}
}
return hash;
}
internal FileProperties
@@ -222,7 +248,7 @@ fs_properties_from_path(String8 path)
//~ rjf: Streamer Threads
internal B32
fs_u2s_enqueue_req(Rng1U64 range, String8 path, U64 endt_us)
fs_u2s_enqueue_req(HS_Key key, Rng1U64 range, String8 path, U64 endt_us)
{
B32 result = 0;
path.size = Min(path.size, fs_shared->u2s_ring_size);
@@ -230,10 +256,11 @@ fs_u2s_enqueue_req(Rng1U64 range, String8 path, U64 endt_us)
{
U64 unconsumed_size = fs_shared->u2s_ring_write_pos - fs_shared->u2s_ring_read_pos;
U64 available_size = fs_shared->u2s_ring_size - unconsumed_size;
U64 needed_size = sizeof(range.min) + sizeof(range.max) + sizeof(path.size) + path.size;
U64 needed_size = sizeof(key) + sizeof(range.min) + sizeof(range.max) + sizeof(path.size) + path.size;
if(available_size >= needed_size)
{
result = 1;
fs_shared->u2s_ring_write_pos += ring_write_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_write_pos, &key);
fs_shared->u2s_ring_write_pos += ring_write_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_write_pos, &range.min);
fs_shared->u2s_ring_write_pos += ring_write_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_write_pos, &range.max);
fs_shared->u2s_ring_write_pos += ring_write_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_write_pos, &path.size);
@@ -250,13 +277,14 @@ fs_u2s_enqueue_req(Rng1U64 range, String8 path, U64 endt_us)
}
internal void
fs_u2s_dequeue_req(Arena *arena, Rng1U64 *range_out, String8 *path_out)
fs_u2s_dequeue_req(Arena *arena, HS_Key *key_out, Rng1U64 *range_out, String8 *path_out)
{
OS_MutexScope(fs_shared->u2s_ring_mutex) for(;;)
{
U64 unconsumed_size = fs_shared->u2s_ring_write_pos - fs_shared->u2s_ring_read_pos;
if(unconsumed_size >= sizeof(U64))
if(unconsumed_size >= sizeof(*key_out) + sizeof(U64)*2 + sizeof(U64))
{
fs_shared->u2s_ring_read_pos += ring_read_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_read_pos, key_out);
fs_shared->u2s_ring_read_pos += ring_read_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_read_pos, &range_out->min);
fs_shared->u2s_ring_read_pos += ring_read_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_read_pos, &range_out->max);
fs_shared->u2s_ring_read_pos += ring_read_struct(fs_shared->u2s_ring_base, fs_shared->u2s_ring_size, fs_shared->u2s_ring_read_pos, &path_out->size);
@@ -275,12 +303,12 @@ ASYNC_WORK_DEF(fs_stream_work)
Temp scratch = scratch_begin(0, 0);
//- rjf: get next request
HS_Key key = {0};
Rng1U64 range = {0};
String8 path = {0};
fs_u2s_dequeue_req(scratch.arena, &range, &path);
fs_u2s_dequeue_req(scratch.arena, &key, &range, &path);
//- rjf: unpack request
U128 key = fs_big_hash_from_string_range(path, range);
U64 path_hash = fs_little_hash_from_string(path);
U64 path_slot_idx = path_hash%fs_shared->slots_count;
U64 path_stripe_idx = path_slot_idx%fs_shared->stripes_count;
@@ -387,12 +415,12 @@ fs_detector_thread__entry_point(void *p)
range_n != 0;
range_n = range_n->next)
{
if(ins_atomic_u64_eval(&range_n->request_count) == ins_atomic_u64_eval(&range_n->completion_count) &&
fs_u2s_enqueue_req(range_n->range, n->path, os_now_microseconds()+100000))
HS_Key key = hs_key_make(n->root, range_n->id);
if(ins_atomic_u64_eval(&range_n->working_count) == 0 &&
fs_u2s_enqueue_req(key, r1u64(key.id.u128[0].u64[0], key.id.u128[0].u64[1]), n->path, os_now_microseconds()+100000))
{
ins_atomic_u64_eval_assign(&range_n->last_time_requested_us, os_now_microseconds());
ins_atomic_u64_inc_eval(&range_n->request_count);
async_push_work(fs_stream_work, .completion_counter = &range_n->completion_count);
ins_atomic_u64_inc_eval(&range_n->working_count);
async_push_work(fs_stream_work, .working_counter = &range_n->working_count);
}
}
}
+8 -8
View File
@@ -11,10 +11,8 @@ typedef struct FS_RangeNode FS_RangeNode;
struct FS_RangeNode
{
FS_RangeNode *next;
Rng1U64 range;
U64 request_count;
U64 completion_count;
U64 last_time_requested_us;
HS_ID id;
U64 working_count;
};
typedef struct FS_RangeSlot FS_RangeSlot;
@@ -33,6 +31,9 @@ struct FS_Node
String8 path;
FileProperties props;
// rjf: hash store root
HS_Root root;
// rjf: sub-table of per-requested-file-range info
U64 slots_count;
FS_RangeSlot *slots;
@@ -104,16 +105,15 @@ internal U64 fs_change_gen(void);
////////////////////////////////
//~ rjf: Cache Interaction
internal HS_Key fs_key_from_path_range(String8 path, Rng1U64 range, U64 endt_us);
internal U128 fs_hash_from_path_range(String8 path, Rng1U64 range, U64 endt_us);
internal U128 fs_key_from_path_range(String8 path, Rng1U64 range);
internal FileProperties fs_properties_from_path(String8 path);
////////////////////////////////
//~ rjf: Streaming Work
internal B32 fs_u2s_enqueue_req(Rng1U64 range, String8 path, U64 endt_us);
internal void fs_u2s_dequeue_req(Arena *arena, Rng1U64 *range_out, String8 *path_out);
internal B32 fs_u2s_enqueue_req(HS_Key key, Rng1U64 range, String8 path, U64 endt_us);
internal void fs_u2s_dequeue_req(Arena *arena, HS_Key *key_out, Rng1U64 *range_out, String8 *path_out);
ASYNC_WORK_DEF(fs_stream_work);
////////////////////////////////
+1 -1
View File
@@ -181,7 +181,7 @@ geo_buffer_from_hash(GEO_Scope *scope, U128 hash)
}
internal R_Handle
geo_buffer_from_key(GEO_Scope *scope, U128 key)
geo_buffer_from_key(GEO_Scope *scope, HS_Key key)
{
R_Handle handle = {0};
for(U64 rewind_idx = 0; rewind_idx < HS_KEY_HASH_HISTORY_COUNT; rewind_idx += 1)
+1 -1
View File
@@ -118,7 +118,7 @@ internal void geo_scope_touch_node__stripe_r_guarded(GEO_Scope *scope, GEO_Node
//~ rjf: Cache Lookups
internal R_Handle geo_buffer_from_hash(GEO_Scope *scope, U128 hash);
internal R_Handle geo_buffer_from_key(GEO_Scope *scope, U128 key);
internal R_Handle geo_buffer_from_key(GEO_Scope *scope, HS_Key key);
////////////////////////////////
//~ rjf: Transfer Threads
+53 -14
View File
@@ -13,6 +13,13 @@
# include "third_party/xxHash/xxhash.h"
#endif
internal U64
hs_little_hash_from_data(String8 data)
{
U64 result = XXH3_64bits(data.str, data.size);
return result;
}
internal U128
hs_hash_from_data(String8 data)
{
@@ -22,6 +29,35 @@ hs_hash_from_data(String8 data)
return u128;
}
internal HS_ID
hs_id_make(U64 u64_0, U64 u64_1)
{
HS_ID id;
id.u128[0].u64[0] = u64_0;
id.u128[0].u64[1] = u64_1;
return id;
}
internal B32
hs_id_match(HS_ID a, HS_ID b)
{
B32 result = MemoryMatchStruct(&a, &b);
return result;
}
internal HS_Key
hs_key_make(HS_Root root, HS_ID id)
{
HS_Key key = {root, 0, id};
return key;
}
internal B32
hs_key_match(HS_Key a, HS_Key b)
{
return (MemoryMatchStruct(&a.root, &b.root) && hs_id_match(a.id, b.id));
}
////////////////////////////////
//~ rjf: Main Layer Initialization
@@ -73,11 +109,11 @@ hs_init(void)
////////////////////////////////
//~ rjf: Root Allocation/Deallocation
internal U128
internal HS_Root
hs_root_alloc(void)
{
U128 root = {0};
root.u64[1] = ins_atomic_u64_inc_eval(&hs_shared->root_id_gen);
HS_Root root = {0};
root.u64[0] = ins_atomic_u64_inc_eval(&hs_shared->root_id_gen);
U64 slot_idx = root.u64[1]%hs_shared->root_slots_count;
U64 stripe_idx = slot_idx%hs_shared->root_stripes_count;
HS_RootSlot *slot = &hs_shared->root_slots[slot_idx];
@@ -101,7 +137,7 @@ hs_root_alloc(void)
}
internal void
hs_root_release(U128 root)
hs_root_release(HS_Root root)
{
U64 slot_idx = root.u64[1]%hs_shared->root_slots_count;
U64 stripe_idx = slot_idx%hs_shared->root_stripes_count;
@@ -111,7 +147,7 @@ hs_root_release(U128 root)
{
for(HS_RootNode *n = slot->first; n != 0; n = n->next)
{
if(u128_match(n->root, root))
if(MemoryMatchStruct(&root, &n->root))
{
DLLRemove(slot->first, slot->last, n);
arena_release(n->arena);
@@ -126,9 +162,10 @@ hs_root_release(U128 root)
//~ rjf: Cache Submission
internal U128
hs_submit_data(U128 key, Arena **data_arena, String8 data)
hs_submit_data(HS_Key key, Arena **data_arena, String8 data)
{
U64 key_slot_idx = key.u64[1]%hs_shared->key_slots_count;
U64 key_hash = hs_little_hash_from_data(str8_struct(&key));
U64 key_slot_idx = key_hash%hs_shared->key_slots_count;
U64 key_stripe_idx = key_slot_idx%hs_shared->key_stripes_count;
HS_KeySlot *key_slot = &hs_shared->key_slots[key_slot_idx];
HS_Stripe *key_stripe = &hs_shared->key_stripes[key_stripe_idx];
@@ -192,7 +229,7 @@ hs_submit_data(U128 key, Arena **data_arena, String8 data)
HS_KeyNode *key_node = 0;
for(HS_KeyNode *n = key_slot->first; n != 0; n = n->next)
{
if(u128_match(n->key, key))
if(hs_key_match(n->key, key))
{
key_node = n;
break;
@@ -321,9 +358,10 @@ hs_scope_touch_node__stripe_r_guarded(HS_Scope *scope, HS_Node *node)
//~ rjf: Key Closing
internal void
hs_key_close(U128 key)
hs_key_close(HS_Key key)
{
U64 key_slot_idx = key.u64[1]%hs_shared->key_slots_count;
U64 key_hash = hs_little_hash_from_data(str8_struct(&key));
U64 key_slot_idx = key_hash%hs_shared->key_slots_count;
U64 key_stripe_idx = key_slot_idx%hs_shared->key_stripes_count;
HS_KeySlot *key_slot = &hs_shared->key_slots[key_slot_idx];
HS_Stripe *key_stripe = &hs_shared->key_stripes[key_stripe_idx];
@@ -331,7 +369,7 @@ hs_key_close(U128 key)
{
for(HS_KeyNode *n = key_slot->first; n != 0; n = n->next)
{
if(u128_match(n->key, key))
if(hs_key_match(n->key, key))
{
for(U64 history_idx = 0; history_idx < HS_KEY_HASH_HISTORY_STRONG_REF_COUNT && history_idx < n->hash_history_gen; history_idx += 1)
{
@@ -407,10 +445,11 @@ hs_hash_downstream_dec(U128 hash)
//~ rjf: Cache Lookup
internal U128
hs_hash_from_key(U128 key, U64 rewind_count)
hs_hash_from_key(HS_Key key, U64 rewind_count)
{
U128 result = {0};
U64 key_slot_idx = key.u64[1]%hs_shared->key_slots_count;
U64 key_hash = hs_little_hash_from_data(str8_struct(&key));
U64 key_slot_idx = key_hash%hs_shared->key_slots_count;
U64 key_stripe_idx = key_slot_idx%hs_shared->key_stripes_count;
HS_KeySlot *key_slot = &hs_shared->key_slots[key_slot_idx];
HS_Stripe *key_stripe = &hs_shared->key_stripes[key_stripe_idx];
@@ -418,7 +457,7 @@ hs_hash_from_key(U128 key, U64 rewind_count)
{
for(HS_KeyNode *n = key_slot->first; n != 0; n = n->next)
{
if(u128_match(n->key, key) && n->hash_history_gen > 0 && n->hash_history_gen-1 >= rewind_count)
if(hs_key_match(n->key, key) && n->hash_history_gen > 0 && n->hash_history_gen-1 >= rewind_count)
{
result = n->hash_history[(n->hash_history_gen-1-rewind_count)%ArrayCount(n->hash_history)];
break;
+43 -15
View File
@@ -40,23 +40,46 @@
// submit that data to the hash store, correllating with the root and key
// combo.
////////////////////////////////
//~ rjf: Key Types
typedef struct HS_Root HS_Root;
struct HS_Root
{
U64 u64[1];
};
typedef struct HS_ID HS_ID;
struct HS_ID
{
U128 u128[1];
};
typedef struct HS_Key HS_Key;
struct HS_Key
{
HS_Root root;
U64 _padding_;
HS_ID id;
};
////////////////////////////////
//~ rjf: Cache Types
typedef struct HS_RootKeyChunkNode HS_RootKeyChunkNode;
struct HS_RootKeyChunkNode
typedef struct HS_RootIDChunkNode HS_RootIDChunkNode;
struct HS_RootIDChunkNode
{
HS_RootKeyChunkNode *next;
HS_RootIDChunkNode *next;
U128 *v;
U64 count;
U64 cap;
};
typedef struct HS_RootKeyChunkList HS_RootKeyChunkList;
struct HS_RootKeyChunkList
typedef struct HS_RootIDChunkList HS_RootIDChunkList;
struct HS_RootIDChunkList
{
HS_RootKeyChunkNode *first;
HS_RootKeyChunkNode *last;
HS_RootIDChunkNode *first;
HS_RootIDChunkNode *last;
U64 chunk_count;
U64 total_count;
};
@@ -67,8 +90,8 @@ struct HS_RootNode
HS_RootNode *next;
HS_RootNode *prev;
Arena *arena;
U128 root;
HS_RootKeyChunkList keys;
HS_Root root;
HS_RootIDChunkList ids;
};
typedef struct HS_RootSlot HS_RootSlot;
@@ -86,7 +109,7 @@ struct HS_KeyNode
{
HS_KeyNode *next;
HS_KeyNode *prev;
U128 key;
HS_Key key;
U128 hash_history[HS_KEY_HASH_HISTORY_COUNT];
U64 hash_history_gen;
};
@@ -197,7 +220,12 @@ global HS_Shared *hs_shared = 0;
////////////////////////////////
//~ rjf: Basic Helpers
internal U64 hs_little_hash_from_data(String8 data);
internal U128 hs_hash_from_data(String8 data);
internal HS_ID hs_id_make(U64 u64_0, U64 u64_1);
internal B32 hs_id_match(HS_ID a, HS_ID b);
internal HS_Key hs_key_make(HS_Root root, HS_ID id);
internal B32 hs_key_match(HS_Key a, HS_Key b);
////////////////////////////////
//~ rjf: Main Layer Initialization
@@ -207,13 +235,13 @@ internal void hs_init(void);
////////////////////////////////
//~ rjf: Root Allocation/Deallocation
internal U128 hs_root_alloc(void);
internal void hs_root_release(U128 root);
internal HS_Root hs_root_alloc(void);
internal void hs_root_release(HS_Root root);
////////////////////////////////
//~ rjf: Cache Submission
internal U128 hs_submit_data(U128 key, Arena **data_arena, String8 data);
internal U128 hs_submit_data(HS_Key key, Arena **data_arena, String8 data);
////////////////////////////////
//~ rjf: Scoped Access
@@ -225,7 +253,7 @@ internal void hs_scope_touch_node__stripe_r_guarded(HS_Scope *scope, HS_Node *no
////////////////////////////////
//~ rjf: Key Closing
internal void hs_key_close(U128 key);
internal void hs_key_close(HS_Key key);
////////////////////////////////
//~ rjf: Downstream Accesses
@@ -236,7 +264,7 @@ internal void hs_hash_downstream_dec(U128 hash);
////////////////////////////////
//~ rjf: Cache Lookups
internal U128 hs_hash_from_key(U128 key, U64 rewind_count);
internal U128 hs_hash_from_key(HS_Key key, U64 rewind_count);
internal String8 hs_data_from_hash(HS_Scope *scope, U128 hash);
////////////////////////////////
+6 -5
View File
@@ -38,9 +38,10 @@ mtx_init(void)
//~ rjf: Buffer Operations
internal void
mtx_push_op(U128 buffer_key, MTX_Op op)
mtx_push_op(HS_Key buffer_key, MTX_Op op)
{
MTX_MutThread *thread = &mtx_shared->mut_threads[buffer_key.u64[1]%mtx_shared->mut_threads_count];
U64 hash = hs_little_hash_from_data(str8_struct(&buffer_key));
MTX_MutThread *thread = &mtx_shared->mut_threads[hash%mtx_shared->mut_threads_count];
mtx_enqueue_op(thread, buffer_key, op);
}
@@ -48,7 +49,7 @@ mtx_push_op(U128 buffer_key, MTX_Op op)
//~ rjf: Mutation Threads
internal void
mtx_enqueue_op(MTX_MutThread *thread, U128 buffer_key, MTX_Op op)
mtx_enqueue_op(MTX_MutThread *thread, HS_Key buffer_key, MTX_Op op)
{
// TODO(rjf): if op.replace is too big, need to split into multiple edits
OS_MutexScope(thread->mutex) for(;;)
@@ -70,7 +71,7 @@ mtx_enqueue_op(MTX_MutThread *thread, U128 buffer_key, MTX_Op op)
}
internal void
mtx_dequeue_op(Arena *arena, MTX_MutThread *thread, U128 *buffer_key_out, MTX_Op *op_out)
mtx_dequeue_op(Arena *arena, MTX_MutThread *thread, HS_Key *buffer_key_out, MTX_Op *op_out)
{
OS_MutexScope(thread->mutex) for(;;)
{
@@ -100,7 +101,7 @@ mtx_mut_thread__entry_point(void *p)
HS_Scope *hs_scope = hs_scope_open();
//- rjf: get next op
U128 buffer_key = {0};
HS_Key buffer_key = {0};
MTX_Op op = {0};
mtx_dequeue_op(scratch.arena, mut_thread, &buffer_key, &op);
+3 -3
View File
@@ -84,13 +84,13 @@ internal void mtx_init(void);
////////////////////////////////
//~ rjf: Buffer Operations
internal void mtx_push_op(U128 buffer_key, MTX_Op op);
internal void mtx_push_op(HS_Key buffer_key, MTX_Op op);
////////////////////////////////
//~ rjf: Mutation Threads
internal void mtx_enqueue_op(MTX_MutThread *thread, U128 buffer_key, MTX_Op op);
internal void mtx_dequeue_op(Arena *arena, MTX_MutThread *thread, U128 *buffer_key_out, MTX_Op *op_out);
internal void mtx_enqueue_op(MTX_MutThread *thread, HS_Key buffer_key, MTX_Op op);
internal void mtx_dequeue_op(Arena *arena, MTX_MutThread *thread, HS_Key *buffer_key_out, MTX_Op *op_out);
internal void mtx_mut_thread__entry_point(void *p);
#endif // MUTABLE_TEXT_H
+1 -1
View File
@@ -456,7 +456,7 @@ Rng1U64 rd_reg_slot_range_table[44] =
{OffsetOf(RD_Regs, file_path), OffsetOf(RD_Regs, file_path) + sizeof(String8)},
{OffsetOf(RD_Regs, cursor), OffsetOf(RD_Regs, cursor) + sizeof(TxtPt)},
{OffsetOf(RD_Regs, mark), OffsetOf(RD_Regs, mark) + sizeof(TxtPt)},
{OffsetOf(RD_Regs, text_key), OffsetOf(RD_Regs, text_key) + sizeof(U128)},
{OffsetOf(RD_Regs, text_key), OffsetOf(RD_Regs, text_key) + sizeof(HS_Key)},
{OffsetOf(RD_Regs, lang_kind), OffsetOf(RD_Regs, lang_kind) + sizeof(TXT_LangKind)},
{OffsetOf(RD_Regs, lines), OffsetOf(RD_Regs, lines) + sizeof(D_LineList)},
{OffsetOf(RD_Regs, dbgi_key), OffsetOf(RD_Regs, dbgi_key) + sizeof(DI_Key)},
+1 -1
View File
@@ -450,7 +450,7 @@ U64 inline_depth;
String8 file_path;
TxtPt cursor;
TxtPt mark;
U128 text_key;
HS_Key text_key;
TXT_LangKind lang_kind;
D_LineList lines;
DI_Key dbgi_key;
+1 -1
View File
@@ -712,7 +712,7 @@ RD_RegTable:
{String8 file_path FilePath }
{TxtPt cursor Cursor }
{TxtPt mark Mark }
{U128 text_key TextKey }
{HS_Key text_key TextKey }
{TXT_LangKind lang_kind LangKind }
{D_LineList lines Lines }
{DI_Key dbgi_key DbgiKey }
+21 -14
View File
@@ -1747,7 +1747,9 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range)
//- rjf: reads from hash store key
case E_SpaceKind_HashStoreKey:
{
U128 key = space.u128;
HS_Root root = {space.u64_0};
HS_ID id = {space.u128};
HS_Key key = hs_key_make(root, id);
U128 hash = hs_hash_from_key(key, 0);
HS_Scope *scope = hs_scope_open();
{
@@ -1778,7 +1780,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range)
containing_range.max -= containing_range.max%chunk_size;
// rjf: map to hash
U128 key = fs_key_from_path_range(file_path, containing_range);
HS_Key key = fs_key_from_path_range(file_path, containing_range, 0);
U128 hash = hs_hash_from_key(key, 0);
// rjf: look up from hash store
@@ -2136,28 +2138,30 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range)
//- rjf: asynchronous streamed reads -> hashes from spaces
internal U128
internal HS_Key
rd_key_from_eval_space_range(E_Space space, Rng1U64 range, B32 zero_terminated)
{
U128 result = {0};
HS_Key result = {0};
switch(space.kind)
{
case E_SpaceKind_HashStoreKey:
{
result = space.u128;
HS_Root root = {space.u64_0};
HS_ID id = {space.u128};
result = hs_key_make(root, id);
}break;
case E_SpaceKind_File:
{
U64 file_path_string_id = space.u64_0;
String8 file_path = e_string_from_id(file_path_string_id);
result = fs_key_from_path_range(file_path, range);
result = fs_key_from_path_range(file_path, range, 0);
}break;
case RD_EvalSpaceKind_CtrlEntity:
{
CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(space);
if(entity->kind == CTRL_EntityKind_Process)
{
result = ctrl_hash_store_key_from_process_vaddr_range(entity->handle, range, zero_terminated);
result = ctrl_key_from_process_vaddr_range(entity->handle, range, zero_terminated, 0, 0);
}
}break;
}
@@ -2174,7 +2178,9 @@ rd_whole_range_from_eval_space(E_Space space)
{
case E_SpaceKind_HashStoreKey:
{
U128 key = space.u128;
HS_Root root = {space.u64_0};
HS_ID id = {space.u128};
HS_Key key = hs_key_make(root, id);
U128 hash = hs_hash_from_key(key, 0);
HS_Scope *hs_scope = hs_scope_open();
{
@@ -2867,7 +2873,7 @@ rd_view_ui(Rng2F32 rect)
// rjf: unpack view's target expression & hash
E_Eval eval = e_eval_from_string(expr_string);
Rng1U64 range = r1u64(0, 1024);
U128 key = rd_key_from_eval_space_range(eval.space, range, 0);
HS_Key key = rd_key_from_eval_space_range(eval.space, range, 0);
U128 hash = hs_hash_from_key(key, 0);
// rjf: determine if hash's blob is ready, and which viewer to use
@@ -6519,7 +6525,7 @@ rd_window_frame(void)
if(ws->dev_menu_is_open) RD_Font(RD_FontSlot_Code)
{
ui_set_next_flags(UI_BoxFlag_ViewScrollY|UI_BoxFlag_AllowOverflowY|UI_BoxFlag_ViewClamp);
UI_PaneF(r2f32p(30, 30, 30+ui_top_font_size()*100, ui_top_font_size()*150), "###dev_ctx_menu")
UI_PaneF(r2f32p(30, 30, 30+ui_top_font_size()*100, ui_top_font_size()*60), "###dev_ctx_menu")
{
//- rjf: capture
if(!ProfIsCapturing() && ui_clicked(ui_buttonf("Begin Profiler Capture###prof_cap")))
@@ -6580,7 +6586,7 @@ rd_window_frame(void)
ui_labelf("mark: (L:%I64d, C:%I64d)", regs->mark.line, regs->mark.column);
ui_labelf("unwind_count: %I64u", regs->unwind_count);
ui_labelf("inline_depth: %I64u", regs->inline_depth);
ui_labelf("text_key: [0x%I64x, 0x%I64x]", regs->text_key.u64[0], regs->text_key.u64[1]);
ui_labelf("text_key: [0x%I64x / 0x%I64x:0x%I64x]", regs->text_key.root.u64[0], regs->text_key.id.u128[0].u64[0], regs->text_key.id.u128[0].u64[1]);
ui_labelf("lang_kind: '%S'", txt_extension_from_lang_kind(regs->lang_kind));
ui_labelf("vaddr_range: [0x%I64x, 0x%I64x)", regs->vaddr_range.min, regs->vaddr_range.max);
ui_labelf("voff_range: [0x%I64x, 0x%I64x)", regs->voff_range.min, regs->voff_range.max);
@@ -12174,12 +12180,13 @@ rd_frame(void)
//- rjf: add macro for output log
{
HS_Scope *hs_scope = hs_scope_open();
U128 key = d_state->output_log_key;
HS_Key key = d_state->output_log_key;
U128 hash = hs_hash_from_key(key, 0);
String8 data = hs_data_from_hash(hs_scope, hash);
E_Space space = e_space_make(E_SpaceKind_HashStoreKey);
space.u64_0 = key.root.u64[0];
space.u128 = key.id.u128[0];
E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0));
space.u128 = key;
expr->space = space;
expr->mode = E_Mode_Offset;
expr->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), data.size, 0);
@@ -15479,7 +15486,7 @@ rd_frame(void)
HS_Scope *hs_scope = hs_scope_open();
TXT_Scope *txt_scope = txt_scope_open();
RD_Regs *regs = rd_regs();
U128 text_key = regs->text_key;
HS_Key text_key = regs->text_key;
TXT_LangKind lang_kind = regs->lang_kind;
TxtRng range = txt_rng(regs->cursor, regs->mark);
U128 hash = {0};
+1 -1
View File
@@ -890,7 +890,7 @@ internal B32 rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range
internal B32 rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range);
//- rjf: asynchronous streamed reads -> hashes from spaces
internal U128 rd_key_from_eval_space_range(E_Space space, Rng1U64 range, B32 zero_terminated);
internal HS_Key rd_key_from_eval_space_range(E_Space space, Rng1U64 range, B32 zero_terminated);
//- rjf: space -> entire range
internal Rng1U64 rd_whole_range_from_eval_space(E_Space space);
+4 -4
View File
@@ -2381,7 +2381,7 @@ RD_VIEW_UI_FUNCTION_DEF(disasm)
syntax = DASM_Syntax_ATT;
}
}
U128 dasm_key = rd_key_from_eval_space_range(space, range, 0);
HS_Key dasm_key = rd_key_from_eval_space_range(space, range, 0);
U128 dasm_data_hash = {0};
DASM_Params dasm_params = {0};
{
@@ -3572,7 +3572,7 @@ RD_VIEW_UI_FUNCTION_DEF(bitmap)
//////////////////////////////
//- rjf: map expression artifacts -> texture
//
U128 texture_key = rd_key_from_eval_space_range(eval.space, offset_range, 0);
HS_Key texture_key = rd_key_from_eval_space_range(eval.space, offset_range, 0);
TEX_Topology topology = tex_topology_make(dim, fmt);
U128 data_hash = {0};
R_Handle texture = tex_texture_from_key_topology(tex_scope, texture_key, topology, &data_hash);
@@ -4058,8 +4058,8 @@ RD_VIEW_UI_FUNCTION_DEF(geo3d)
U64 base_offset = e_base_offset_from_eval(eval);
Rng1U64 idxs_range = r1u64(base_offset, base_offset+count*sizeof(U32));
Rng1U64 vtxs_range = r1u64(vtx_base_off, vtx_base_off+vtx_size);
U128 idxs_key = rd_key_from_eval_space_range(eval.space, idxs_range, 0);
U128 vtxs_key = rd_key_from_eval_space_range(eval.space, vtxs_range, 0);
HS_Key idxs_key = rd_key_from_eval_space_range(eval.space, idxs_range, 0);
HS_Key vtxs_key = rd_key_from_eval_space_range(eval.space, vtxs_range, 0);
R_Handle idxs_buffer = geo_buffer_from_key(geo_scope, idxs_key);
R_Handle vtxs_buffer = geo_buffer_from_key(geo_scope, vtxs_key);
+1 -1
View File
@@ -1771,7 +1771,7 @@ txt_text_info_from_hash_lang(TXT_Scope *scope, U128 hash, TXT_LangKind lang)
}
internal TXT_TextInfo
txt_text_info_from_key_lang(TXT_Scope *scope, U128 key, TXT_LangKind lang, U128 *hash_out)
txt_text_info_from_key_lang(TXT_Scope *scope, HS_Key key, TXT_LangKind lang, U128 *hash_out)
{
TXT_TextInfo result = {0};
for(U64 rewind_idx = 0; rewind_idx < HS_KEY_HASH_HISTORY_COUNT; rewind_idx += 1)
+1 -1
View File
@@ -274,7 +274,7 @@ internal void txt_scope_touch_node__stripe_r_guarded(TXT_Scope *scope, TXT_Node
//~ rjf: Cache Lookups
internal TXT_TextInfo txt_text_info_from_hash_lang(TXT_Scope *scope, U128 hash, TXT_LangKind lang);
internal TXT_TextInfo txt_text_info_from_key_lang(TXT_Scope *scope, U128 key, TXT_LangKind lang, U128 *hash_out);
internal TXT_TextInfo txt_text_info_from_key_lang(TXT_Scope *scope, HS_Key key, TXT_LangKind lang, U128 *hash_out);
////////////////////////////////
//~ rjf: Text Info Extractor Helpers
+1 -1
View File
@@ -196,7 +196,7 @@ tex_texture_from_hash_topology(TEX_Scope *scope, U128 hash, TEX_Topology topolog
}
internal R_Handle
tex_texture_from_key_topology(TEX_Scope *scope, U128 key, TEX_Topology topology, U128 *hash_out)
tex_texture_from_key_topology(TEX_Scope *scope, HS_Key key, TEX_Topology topology, U128 *hash_out)
{
R_Handle handle = {0};
for(U64 rewind_idx = 0; rewind_idx < HS_KEY_HASH_HISTORY_COUNT; rewind_idx += 1)
+1 -1
View File
@@ -135,7 +135,7 @@ internal void tex_scope_touch_node__stripe_r_guarded(TEX_Scope *scope, TEX_Node
//~ rjf: Cache Lookups
internal R_Handle tex_texture_from_hash_topology(TEX_Scope *scope, U128 hash, TEX_Topology topology);
internal R_Handle tex_texture_from_key_topology(TEX_Scope *scope, U128 key, TEX_Topology topology, U128 *hash_out);
internal R_Handle tex_texture_from_key_topology(TEX_Scope *scope, HS_Key key, TEX_Topology topology, U128 *hash_out);
////////////////////////////////
//~ rjf: Transfer Threads