mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-24 12:44:59 -07:00
provide u64 broadcasting mechanism in base layer wavefront lane context, allows more flexible data sharing mechanism which does not depend on statics; reshape dasm building codepath for clicking into artifact cache
This commit is contained in:
@@ -221,10 +221,26 @@ ac_tick(void)
|
||||
lane_sync();
|
||||
|
||||
// rjf: compute val
|
||||
void *val = reqs[idx].create(reqs[idx].key);
|
||||
B32 retry = 0;
|
||||
void *val = reqs[idx].create(reqs[idx].key, &retry);
|
||||
|
||||
// rjf: retry? -> resubmit request
|
||||
if(retry && lane_idx() == 0)
|
||||
{
|
||||
MutexScope(ac_shared->req_mutex)
|
||||
{
|
||||
AC_RequestNode *n = push_array(ac_shared->req_arena, AC_RequestNode, 1);
|
||||
SLLQueuePush(ac_shared->first_req, ac_shared->last_req, n);
|
||||
ac_shared->req_count += 1;
|
||||
MemoryCopyStruct(&n->v, &reqs[idx]);
|
||||
n->v.key = str8_copy(ac_shared->req_arena, n->v.key);
|
||||
}
|
||||
ins_atomic_u32_eval_assign(&async_loop_again, 1);
|
||||
}
|
||||
|
||||
// rjf: create function -> cache
|
||||
AC_Cache *cache = 0;
|
||||
if(!retry)
|
||||
{
|
||||
U64 cache_hash = u64_hash_from_str8(str8_struct(&reqs[idx].create));
|
||||
U64 cache_slot_idx = cache_hash%ac_shared->cache_slots_count;
|
||||
@@ -243,7 +259,7 @@ ac_tick(void)
|
||||
}
|
||||
|
||||
// rjf: write value into cache
|
||||
if(lane_idx() == 0)
|
||||
if(!retry && lane_idx() == 0)
|
||||
{
|
||||
U64 hash = u64_hash_from_str8(reqs[idx].key);
|
||||
U64 slot_idx = hash%cache->slots_count;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Artifact Computation Function Types
|
||||
|
||||
typedef void *AC_CreateFunctionType(String8 key);
|
||||
typedef void *AC_CreateFunctionType(String8 key, B32 *retry_out);
|
||||
typedef void AC_DestroyFunctionType(void *artifact);
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
@@ -117,6 +117,7 @@ main_thread_base_entry_point(int arguments_count, char **arguments)
|
||||
U64 num_main_threads_clamped = Min(num_async_threads, num_main_threads);
|
||||
num_async_threads -= num_main_threads_clamped;
|
||||
num_async_threads = Max(1, num_async_threads);
|
||||
U64 lane_broadcast_val = 0;
|
||||
Barrier barrier = barrier_alloc(num_async_threads);
|
||||
LaneCtx *lane_ctxs = push_array(scratch.arena, LaneCtx, num_async_threads);
|
||||
async_threads_count = num_async_threads;
|
||||
@@ -126,6 +127,7 @@ main_thread_base_entry_point(int arguments_count, char **arguments)
|
||||
lane_ctxs[idx].lane_idx = idx;
|
||||
lane_ctxs[idx].lane_count = num_async_threads;
|
||||
lane_ctxs[idx].barrier = barrier;
|
||||
lane_ctxs[idx].broadcast_memory = &lane_broadcast_val;
|
||||
async_threads[idx] = thread_launch(async_thread_entry_point, &lane_ctxs[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#if PROFILE_TELEMETRY
|
||||
# include "rad_tm.h"
|
||||
# if OS_WINDOWS
|
||||
# pragma comment(lib, "ws2_32.lib")
|
||||
# pragma comment(lib, "rad_tm_win64.lib")
|
||||
# endif
|
||||
#elif PROFILE_SPALL
|
||||
@@ -44,8 +45,8 @@
|
||||
# define ProfLockTake(...) tmAcquiredLock(0, 0, __VA_ARGS__)
|
||||
# define ProfLockDrop(...) tmReleasedLock(0, __VA_ARGS__)
|
||||
# define ProfColor(color) tmZoneColor((((color) & 0xff000000) >> 24) / 255.f, (((color) & 0x00ff0000) >> 16) / 255.f, (((color) & 0x0000ff00) >> 8) / 255.f)
|
||||
# define ProfBeginV(...) \
|
||||
if (TM_API_PTR) { \
|
||||
# define ProfBeginV(...) \
|
||||
if (TM_API_PTR) { \
|
||||
static tm_uint64 file_id = 0; TM_API_PTR->_tmStaticString(&file_id, __FILE__); \
|
||||
Temp scratch = scratch_begin(0,0); \
|
||||
String8 string = push_str8f(scratch.arena, __VA_ARGS__); \
|
||||
@@ -54,8 +55,8 @@ hash = TM_API_PTR->_tmSendDynamicString(hash, (char*)string.str); \
|
||||
TM_API_PTR->_tmEnterZoneFast_Core(0, 0, file_id, __LINE__, hash); \
|
||||
scratch_end(scratch); \
|
||||
}
|
||||
# define ProfNoteV(...) \
|
||||
if (TM_API_PTR) { \
|
||||
# define ProfNoteV(...) \
|
||||
if (TM_API_PTR) { \
|
||||
static tm_uint64 file_id = 0; TM_API_PTR->_tmStaticString(&file_id, __FILE__); \
|
||||
Temp scratch = scratch_begin(0,0); \
|
||||
String8 string = push_str8f(scratch.arena, __VA_ARGS__); \
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
C_LINKAGE thread_static TCTX* tctx_thread_local;
|
||||
C_LINKAGE thread_static TCTX *tctx_thread_local;
|
||||
#if !BUILD_SUPPLEMENTARY_UNIT
|
||||
C_LINKAGE thread_static TCTX* tctx_thread_local = 0;
|
||||
C_LINKAGE thread_static TCTX *tctx_thread_local = 0;
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
@@ -85,12 +85,21 @@ tctx_set_lane_ctx(LaneCtx lane_ctx)
|
||||
}
|
||||
|
||||
internal void
|
||||
tctx_lane_barrier_wait(void)
|
||||
tctx_lane_barrier_wait(void *broadcast_ptr, U64 broadcast_size, U64 broadcast_src_lane_idx)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
ProfColor(0x00000ff);
|
||||
TCTX *tctx = tctx_selected();
|
||||
U64 broadcast_size_clamped = ClampTop(broadcast_size, sizeof(tctx->lane_ctx.broadcast_memory[0]));
|
||||
if(broadcast_ptr != 0 && lane_idx() == broadcast_src_lane_idx)
|
||||
{
|
||||
MemoryCopy(tctx->lane_ctx.broadcast_memory, broadcast_ptr, broadcast_size_clamped);
|
||||
}
|
||||
os_barrier_wait(tctx->lane_ctx.barrier);
|
||||
if(broadcast_ptr != 0 && lane_idx() != broadcast_src_lane_idx)
|
||||
{
|
||||
MemoryCopy(broadcast_ptr, tctx->lane_ctx.broadcast_memory, broadcast_size_clamped);
|
||||
}
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#define BASE_THREAD_CONTEXT_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Lane Group Context
|
||||
//~ rjf: Lane Context
|
||||
|
||||
typedef struct LaneCtx LaneCtx;
|
||||
struct LaneCtx
|
||||
@@ -13,6 +13,7 @@ struct LaneCtx
|
||||
U64 lane_idx;
|
||||
U64 lane_count;
|
||||
Barrier barrier;
|
||||
U64 *broadcast_memory;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -87,12 +88,13 @@ internal Arena *tctx_get_scratch(Arena **conflicts, U64 count);
|
||||
|
||||
//- rjf: lane metadata
|
||||
internal LaneCtx tctx_set_lane_ctx(LaneCtx lane_ctx);
|
||||
internal void tctx_lane_barrier_wait(void);
|
||||
internal void tctx_lane_barrier_wait(void *broadcast_ptr, U64 broadcast_size, U64 broadcast_src_lane_idx);
|
||||
#define lane_idx() (tctx_selected()->lane_ctx.lane_idx)
|
||||
#define lane_count() (tctx_selected()->lane_ctx.lane_count)
|
||||
#define lane_from_task_idx(idx) ((idx)%lane_count())
|
||||
#define lane_ctx(ctx) tctx_set_lane_ctx((ctx))
|
||||
#define lane_sync() tctx_lane_barrier_wait()
|
||||
#define lane_sync() tctx_lane_barrier_wait(0, 0, 0)
|
||||
#define lane_sync_u64(ptr, src_lane_idx) tctx_lane_barrier_wait((ptr), sizeof(U64), (src_lane_idx))
|
||||
#define lane_range(count) m_range_from_n_idx_m_count(lane_idx(), lane_count(), (count))
|
||||
|
||||
//- rjf: thread names
|
||||
|
||||
+364
-102
@@ -277,108 +277,6 @@ dasm_init(void)
|
||||
dasm_shared->req_arena = arena_alloc();
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Cache Lookups
|
||||
|
||||
internal DASM_Info
|
||||
dasm_info_from_hash_params(Access *access, 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; create node if needed
|
||||
for(B32 write_mode = 0; write_mode <= 1; write_mode += 1)
|
||||
{
|
||||
B32 found = 0;
|
||||
RWMutexScope(stripe->rw_mutex, write_mode)
|
||||
{
|
||||
// rjf: find existing node
|
||||
DASM_Node *node = 0;
|
||||
for(DASM_Node *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(u128_match(hash, n->hash) && dasm_params_match(params, &n->params))
|
||||
{
|
||||
node = n;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: [write mode] allocate node if needed, and kick off request
|
||||
if(write_mode && node == 0)
|
||||
{
|
||||
node = stripe->free_node;
|
||||
if(node)
|
||||
{
|
||||
SLLStackPop(stripe->free_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
node = push_array_no_zero(stripe->arena, DASM_Node, 1);
|
||||
}
|
||||
MemoryZeroStruct(node);
|
||||
DLLPushBack(slot->first, slot->last, node);
|
||||
node->hash = hash;
|
||||
MemoryCopyStruct(&node->params, params);
|
||||
node->root = c_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);
|
||||
ins_atomic_u64_inc_eval(&node->working_count);
|
||||
MutexScope(dasm_shared->req_mutex)
|
||||
{
|
||||
DASM_RequestNode *req_n = push_array(dasm_shared->req_arena, DASM_RequestNode, 1);
|
||||
SLLQueuePush(dasm_shared->first_req, dasm_shared->last_req, req_n);
|
||||
dasm_shared->req_count += 1;
|
||||
req_n->v.root = node->root;
|
||||
req_n->v.hash = hash;
|
||||
MemoryCopyStruct(&req_n->v.params, params);
|
||||
req_n->v.params.dbgi_key = di_key_copy(dasm_shared->req_arena, &req_n->v.params.dbgi_key);
|
||||
}
|
||||
cond_var_broadcast(async_tick_start_cond_var);
|
||||
}
|
||||
|
||||
// rjf: nonzero node, request if needed - touch & return results
|
||||
if(node != 0)
|
||||
{
|
||||
access_touch(access, &node->access_pt, stripe->cv);
|
||||
MemoryCopyStruct(&info, &node->info);
|
||||
}
|
||||
}
|
||||
if(found)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
internal DASM_Info
|
||||
dasm_info_from_key_params(Access *access, C_Key key, DASM_Params *params, U128 *hash_out)
|
||||
{
|
||||
DASM_Info result = {0};
|
||||
for(U64 rewind_idx = 0; rewind_idx < C_KEY_HASH_HISTORY_COUNT; rewind_idx += 1)
|
||||
{
|
||||
U128 hash = c_hash_from_key(key, rewind_idx);
|
||||
result = dasm_info_from_hash_params(access, hash, params);
|
||||
if(result.lines.count != 0)
|
||||
{
|
||||
if(hash_out)
|
||||
{
|
||||
*hash_out = hash;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Ticks
|
||||
|
||||
@@ -734,3 +632,367 @@ dasm_tick(void)
|
||||
scratch_end(scratch);
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Artifact Cache Hooks / Lookups
|
||||
|
||||
typedef struct DASM_Artifact DASM_Artifact;
|
||||
struct DASM_Artifact
|
||||
{
|
||||
Arena *arena;
|
||||
DASM_Info info;
|
||||
};
|
||||
|
||||
internal void *
|
||||
dasm_artifact_create(String8 key, B32 *retry_out)
|
||||
{
|
||||
void *result = 0;
|
||||
if(lane_idx() == 0)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
Access *access = access_open();
|
||||
DI_Scope *di_scope = di_scope_open();
|
||||
|
||||
//- rjf: unpack key
|
||||
U128 hash = {0};
|
||||
DASM_Params params = {0};
|
||||
U64 key_read_off = 0;
|
||||
key_read_off += str8_deserial_read_struct(key, key_read_off, &hash);
|
||||
key_read_off += str8_deserial_read_struct(key, key_read_off, ¶ms);
|
||||
params.dbgi_key.path.str = key.str + key_read_off;
|
||||
String8 data = c_data_from_hash(access, hash);
|
||||
|
||||
//- rjf: get dbg info
|
||||
B32 stale = 0;
|
||||
RDI_Parsed *rdi = &rdi_parsed_nil;
|
||||
if(params.dbgi_key.path.size != 0)
|
||||
{
|
||||
rdi = di_rdi_from_key(di_scope, ¶ms.dbgi_key, 1, 0);
|
||||
}
|
||||
stale = (stale || (rdi == &rdi_parsed_nil));
|
||||
|
||||
//- rjf: data * arch * addr * dbg -> decode artifacts
|
||||
DASM_LineChunkList line_list = {0};
|
||||
String8List inst_strings = {0};
|
||||
switch(params.arch)
|
||||
{
|
||||
default:{}break;
|
||||
|
||||
//- rjf: x86/x64 decoding
|
||||
case Arch_x64:
|
||||
case Arch_x86:
|
||||
{
|
||||
// rjf: disassemble
|
||||
RDI_SourceFile *last_file = &rdi_nil_element_union.source_file;
|
||||
RDI_Line *last_line = 0;
|
||||
for(U64 off = 0; off < data.size;)
|
||||
{
|
||||
// rjf: disassemble one instruction
|
||||
DASM_Inst inst = dasm_inst_from_code(scratch.arena, params.arch, params.vaddr+off, str8_skip(data, off), params.syntax);
|
||||
if(inst.size == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// rjf: push strings derived from voff -> line info
|
||||
if(params.style_flags & (DASM_StyleFlag_SourceFilesNames|DASM_StyleFlag_SourceLines) &&
|
||||
rdi != &rdi_parsed_nil)
|
||||
{
|
||||
U64 voff = (params.vaddr+off) - params.base_vaddr;
|
||||
U32 unit_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_UnitVMap, voff);
|
||||
RDI_Unit *unit = rdi_element_from_name_idx(rdi, Units, unit_idx);
|
||||
RDI_LineTable *line_table = rdi_element_from_name_idx(rdi, LineTables, unit->line_table_idx);
|
||||
RDI_ParsedLineTable unit_line_info = {0};
|
||||
rdi_parsed_from_line_table(rdi, line_table, &unit_line_info);
|
||||
U64 line_info_idx = rdi_line_info_idx_from_voff(&unit_line_info, voff);
|
||||
if(line_info_idx < unit_line_info.count)
|
||||
{
|
||||
RDI_Line *line = &unit_line_info.lines[line_info_idx];
|
||||
RDI_SourceFile *file = rdi_element_from_name_idx(rdi, SourceFiles, line->file_idx);
|
||||
String8 file_normalized_full_path = {0};
|
||||
file_normalized_full_path.str = rdi_string_from_idx(rdi, file->normal_full_path_string_idx, &file_normalized_full_path.size);
|
||||
if(file != last_file)
|
||||
{
|
||||
if(params.style_flags & DASM_StyleFlag_SourceFilesNames &&
|
||||
file->normal_full_path_string_idx != 0 && file_normalized_full_path.size != 0)
|
||||
{
|
||||
String8 inst_string = push_str8f(scratch.arena, "> %S", file_normalized_full_path);
|
||||
DASM_Line inst = {u32_from_u64_saturate(off), DASM_LineFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count,
|
||||
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
|
||||
dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &inst);
|
||||
str8_list_push(scratch.arena, &inst_strings, inst_string);
|
||||
}
|
||||
if(params.style_flags & DASM_StyleFlag_SourceFilesNames && file->normal_full_path_string_idx == 0)
|
||||
{
|
||||
String8 inst_string = str8_lit(">");
|
||||
DASM_Line inst = {u32_from_u64_saturate(off), DASM_LineFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count,
|
||||
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
|
||||
dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &inst);
|
||||
str8_list_push(scratch.arena, &inst_strings, inst_string);
|
||||
}
|
||||
last_file = file;
|
||||
}
|
||||
if(line && line != last_line && file->normal_full_path_string_idx != 0 &&
|
||||
params.style_flags & DASM_StyleFlag_SourceLines &&
|
||||
file_normalized_full_path.size != 0)
|
||||
{
|
||||
FileProperties props = os_properties_from_file_path(file_normalized_full_path);
|
||||
if(props.modified != 0)
|
||||
{
|
||||
// TODO(rjf): need redirection path - this may map to a different path on the local machine,
|
||||
// need frontend to communicate path remapping info to this layer
|
||||
C_Key key = fs_key_from_path_range(file_normalized_full_path, r1u64(0, max_U64), 0);
|
||||
TXT_LangKind lang_kind = txt_lang_kind_from_extension(file_normalized_full_path);
|
||||
U64 endt_us = max_U64;
|
||||
U128 hash = {0};
|
||||
TXT_TextInfo text_info = txt_text_info_from_key_lang(access, key, lang_kind, &hash);
|
||||
stale = (stale || u128_match(hash, u128_zero()));
|
||||
if(0 < line->line_num && line->line_num < text_info.lines_count)
|
||||
{
|
||||
String8 data = c_data_from_hash(access, hash);
|
||||
String8 line_text = str8_skip_chop_whitespace(str8_substr(data, text_info.lines_ranges[line->line_num-1]));
|
||||
if(line_text.size != 0)
|
||||
{
|
||||
String8 inst_string = push_str8f(scratch.arena, "> %S", line_text);
|
||||
DASM_Line inst = {u32_from_u64_saturate(off), DASM_LineFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count,
|
||||
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
|
||||
dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &inst);
|
||||
str8_list_push(scratch.arena, &inst_strings, inst_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
last_line = line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: push line
|
||||
String8 addr_part = {0};
|
||||
if(params.style_flags & DASM_StyleFlag_Addresses)
|
||||
{
|
||||
addr_part = push_str8f(scratch.arena, "%s0x%016I64x ", rdi != &rdi_parsed_nil ? " " : "", params.vaddr+off);
|
||||
}
|
||||
String8 code_bytes_part = {0};
|
||||
if(params.style_flags & DASM_StyleFlag_CodeBytes)
|
||||
{
|
||||
String8List code_bytes_strings = {0};
|
||||
str8_list_push(scratch.arena, &code_bytes_strings, str8_lit("{"));
|
||||
for(U64 byte_idx = 0; byte_idx < inst.size || byte_idx < 16; byte_idx += 1)
|
||||
{
|
||||
if(byte_idx < inst.size)
|
||||
{
|
||||
str8_list_pushf(scratch.arena, &code_bytes_strings, "%02x%s ", (U32)data.str[off+byte_idx], byte_idx == inst.size-1 ? "}" : "");
|
||||
}
|
||||
else if(byte_idx < 8)
|
||||
{
|
||||
str8_list_push(scratch.arena, &code_bytes_strings, str8_lit(" "));
|
||||
}
|
||||
}
|
||||
str8_list_push(scratch.arena, &code_bytes_strings, str8_lit(" "));
|
||||
code_bytes_part = str8_list_join(scratch.arena, &code_bytes_strings, 0);
|
||||
}
|
||||
String8 symbol_part = {0};
|
||||
if(inst.jump_dest_vaddr != 0 && rdi != &rdi_parsed_nil && params.style_flags & DASM_StyleFlag_SymbolNames)
|
||||
{
|
||||
RDI_U32 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, inst.jump_dest_vaddr-params.base_vaddr);
|
||||
if(scope_idx != 0)
|
||||
{
|
||||
RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx);
|
||||
RDI_U32 procedure_idx = scope->proc_idx;
|
||||
RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, procedure_idx);
|
||||
String8 procedure_name = {0};
|
||||
procedure_name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &procedure_name.size);
|
||||
if(procedure_name.size != 0)
|
||||
{
|
||||
symbol_part = push_str8f(scratch.arena, " (%S)", procedure_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
String8 inst_string = push_str8f(scratch.arena, "%S%S%S%S", addr_part, code_bytes_part, inst.string, symbol_part);
|
||||
DASM_Line line = {u32_from_u64_saturate(off), 0, inst.jump_dest_vaddr, r1u64(inst_strings.total_size + inst_strings.node_count,
|
||||
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
|
||||
dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &line);
|
||||
str8_list_push(scratch.arena, &inst_strings, inst_string);
|
||||
|
||||
// rjf: increment
|
||||
off += inst.size;
|
||||
}
|
||||
}break;
|
||||
}
|
||||
|
||||
//- rjf: artifacts -> value bundle
|
||||
Arena *info_arena = 0;
|
||||
DASM_Info info = {0};
|
||||
if(!stale)
|
||||
{
|
||||
//- rjf: produce joined text
|
||||
Arena *text_arena = arena_alloc();
|
||||
StringJoin text_join = {0};
|
||||
text_join.sep = str8_lit("\n");
|
||||
String8 text = str8_list_join(text_arena, &inst_strings, &text_join);
|
||||
|
||||
//- rjf: produce unique key for this disassembly's text
|
||||
C_Key text_key = c_key_make(c_root_alloc(), c_id_make(0, 0));
|
||||
|
||||
//- rjf: submit text data to hash store
|
||||
U128 text_hash = c_submit_data(text_key, &text_arena, text);
|
||||
|
||||
//- rjf: produce value bundle
|
||||
info_arena = arena_alloc();
|
||||
info.text_key = text_key;
|
||||
info.lines = dasm_line_array_from_chunk_list(info_arena, &line_list);
|
||||
}
|
||||
|
||||
//- rjf: if stale, retry
|
||||
if(stale)
|
||||
{
|
||||
retry_out[0] = 1;
|
||||
}
|
||||
|
||||
//- rjf: fill result
|
||||
if(info_arena != 0)
|
||||
{
|
||||
DASM_Artifact *artifact = push_array(info_arena, DASM_Artifact, 1);
|
||||
artifact->arena = info_arena;
|
||||
artifact->info = info;
|
||||
result = artifact;
|
||||
}
|
||||
|
||||
di_scope_close(di_scope);
|
||||
access_close(access);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
lane_sync_u64(&result, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void
|
||||
dasm_artifact_destroy(void *ptr)
|
||||
{
|
||||
if(ptr == 0) { return; }
|
||||
DASM_Artifact *artifact = (DASM_Artifact *)ptr;
|
||||
c_close_key(artifact->info.text_key);
|
||||
arena_release(artifact->arena);
|
||||
}
|
||||
|
||||
internal DASM_Info
|
||||
dasm_info_from_hash_params(Access *access, U128 hash, DASM_Params *params)
|
||||
{
|
||||
DASM_Info info = {0};
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
|
||||
// rjf: form key
|
||||
String8List key_parts = {0};
|
||||
str8_list_push(scratch.arena, &key_parts, str8_struct(&hash));
|
||||
str8_list_push(scratch.arena, &key_parts, str8_struct(params));
|
||||
str8_list_push(scratch.arena, &key_parts, params->dbgi_key.path);
|
||||
String8 key = str8_list_join(scratch.arena, &key_parts, 0);
|
||||
|
||||
// rjf: get info
|
||||
DASM_Artifact *artifact = ac_artifact_from_key(access, key, fs_change_gen(), dasm_artifact_create, dasm_artifact_destroy, 1024);
|
||||
if(artifact)
|
||||
{
|
||||
info = artifact->info;
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
return info;
|
||||
#if 0
|
||||
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; create node if needed
|
||||
for(B32 write_mode = 0; write_mode <= 1; write_mode += 1)
|
||||
{
|
||||
B32 found = 0;
|
||||
RWMutexScope(stripe->rw_mutex, write_mode)
|
||||
{
|
||||
// rjf: find existing node
|
||||
DASM_Node *node = 0;
|
||||
for(DASM_Node *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(u128_match(hash, n->hash) && dasm_params_match(params, &n->params))
|
||||
{
|
||||
node = n;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: [write mode] allocate node if needed, and kick off request
|
||||
if(write_mode && node == 0)
|
||||
{
|
||||
node = stripe->free_node;
|
||||
if(node)
|
||||
{
|
||||
SLLStackPop(stripe->free_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
node = push_array_no_zero(stripe->arena, DASM_Node, 1);
|
||||
}
|
||||
MemoryZeroStruct(node);
|
||||
DLLPushBack(slot->first, slot->last, node);
|
||||
node->hash = hash;
|
||||
MemoryCopyStruct(&node->params, params);
|
||||
node->root = c_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);
|
||||
ins_atomic_u64_inc_eval(&node->working_count);
|
||||
MutexScope(dasm_shared->req_mutex)
|
||||
{
|
||||
DASM_RequestNode *req_n = push_array(dasm_shared->req_arena, DASM_RequestNode, 1);
|
||||
SLLQueuePush(dasm_shared->first_req, dasm_shared->last_req, req_n);
|
||||
dasm_shared->req_count += 1;
|
||||
req_n->v.root = node->root;
|
||||
req_n->v.hash = hash;
|
||||
MemoryCopyStruct(&req_n->v.params, params);
|
||||
req_n->v.params.dbgi_key = di_key_copy(dasm_shared->req_arena, &req_n->v.params.dbgi_key);
|
||||
}
|
||||
cond_var_broadcast(async_tick_start_cond_var);
|
||||
}
|
||||
|
||||
// rjf: nonzero node, request if needed - touch & return results
|
||||
if(node != 0)
|
||||
{
|
||||
access_touch(access, &node->access_pt, stripe->cv);
|
||||
MemoryCopyStruct(&info, &node->info);
|
||||
}
|
||||
}
|
||||
if(found)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return info;
|
||||
#endif
|
||||
}
|
||||
|
||||
internal DASM_Info
|
||||
dasm_info_from_key_params(Access *access, C_Key key, DASM_Params *params, U128 *hash_out)
|
||||
{
|
||||
DASM_Info result = {0};
|
||||
for(U64 rewind_idx = 0; rewind_idx < C_KEY_HASH_HISTORY_COUNT; rewind_idx += 1)
|
||||
{
|
||||
U128 hash = c_hash_from_key(key, rewind_idx);
|
||||
result = dasm_info_from_hash_params(access, hash, params);
|
||||
if(result.lines.count != 0)
|
||||
{
|
||||
if(hash_out)
|
||||
{
|
||||
*hash_out = hash;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -284,15 +284,18 @@ internal U64 dasm_line_array_code_off_from_idx(DASM_LineArray *array, U64 idx);
|
||||
|
||||
internal void dasm_init(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Cache Lookups
|
||||
|
||||
internal DASM_Info dasm_info_from_hash_params(Access *access, U128 hash, DASM_Params *params);
|
||||
internal DASM_Info dasm_info_from_key_params(Access *access, C_Key key, DASM_Params *params, U128 *hash_out);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Ticks
|
||||
|
||||
internal void dasm_tick(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Artifact Cache Hooks / Lookups
|
||||
|
||||
internal void *dasm_artifact_create(String8 key, B32 *retry_out);
|
||||
internal void dasm_artifact_destroy(void *ptr);
|
||||
|
||||
internal DASM_Info dasm_info_from_hash_params(Access *access, U128 hash, DASM_Params *params);
|
||||
internal DASM_Info dasm_info_from_key_params(Access *access, C_Key key, DASM_Params *params, U128 *hash_out);
|
||||
|
||||
#endif // DASM_CACHE_H
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#if PROFILE_TELEMETRY
|
||||
# include "rad_tm.h"
|
||||
# if OS_WINDOWS
|
||||
# pragma comment(lib, "ws2_32.lib")
|
||||
# pragma comment(lib, "rad_tm_win64.lib")
|
||||
# endif
|
||||
#endif
|
||||
@@ -44,25 +45,25 @@
|
||||
# define ProfLockDrop(...) tmReleasedLock(0, __VA_ARGS__)
|
||||
# define ProfColor(color) tmZoneColorSticky(color)
|
||||
# define ProfBeginV(...) \
|
||||
if (TM_API_PTR) { \
|
||||
static tm_uint64 file_id = 0; TM_API_PTR->_tmStaticString(&file_id, __FILE__); \
|
||||
Temp scratch = scratch_begin(0,0); \
|
||||
String8 string = push_str8f(scratch.arena, __VA_ARGS__); \
|
||||
tm_uint64 hash = TM_API_PTR->_tmHash((char*)string.str, string.size); \
|
||||
hash = TM_API_PTR->_tmSendDynamicString(hash, (char*)string.str); \
|
||||
TM_API_PTR->_tmEnterZoneFast_Core(0, 0, file_id, __LINE__, hash); \
|
||||
scratch_end(scratch); \
|
||||
}
|
||||
if (TM_API_PTR) { \
|
||||
static tm_uint64 file_id = 0; TM_API_PTR->_tmStaticString(&file_id, __FILE__); \
|
||||
Temp scratch = scratch_begin(0,0); \
|
||||
String8 string = push_str8f(scratch.arena, __VA_ARGS__); \
|
||||
tm_uint64 hash = TM_API_PTR->_tmHash((char*)string.str, string.size); \
|
||||
hash = TM_API_PTR->_tmSendDynamicString(hash, (char*)string.str); \
|
||||
TM_API_PTR->_tmEnterZoneFast_Core(0, 0, file_id, __LINE__, hash); \
|
||||
scratch_end(scratch); \
|
||||
}
|
||||
# define ProfNoteV(...) \
|
||||
if (TM_API_PTR) { \
|
||||
static tm_uint64 file_id = 0; TM_API_PTR->_tmStaticString(&file_id, __FILE__); \
|
||||
Temp scratch = scratch_begin(0,0); \
|
||||
String8 string = push_str8f(scratch.arena, __VA_ARGS__); \
|
||||
tm_uint64 hash = TM_API_PTR->_tmHash((char*)string.str, string.size); \
|
||||
hash = TM_API_PTR->_tmSendDynamicString(hash, (char*)string.str); \
|
||||
TM_API_PTR->_tmMessageFast_Core(0, TMMF_ICON_NOTE, file_id, __LINE__, hash); \
|
||||
scratch_end(scratch); \
|
||||
}
|
||||
if (TM_API_PTR) { \
|
||||
static tm_uint64 file_id = 0; TM_API_PTR->_tmStaticString(&file_id, __FILE__); \
|
||||
Temp scratch = scratch_begin(0,0); \
|
||||
String8 string = push_str8f(scratch.arena, __VA_ARGS__); \
|
||||
tm_uint64 hash = TM_API_PTR->_tmHash((char*)string.str, string.size); \
|
||||
hash = TM_API_PTR->_tmSendDynamicString(hash, (char*)string.str); \
|
||||
TM_API_PTR->_tmMessageFast_Core(0, TMMF_ICON_NOTE, file_id, __LINE__, hash); \
|
||||
scratch_end(scratch); \
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
+5
-3
@@ -26,12 +26,14 @@ rb_entry_point(CmdLine *cmdline)
|
||||
Thread *threads = push_array(scratch.arena, Thread, threads_count);
|
||||
RB_ThreadParams *threads_params = push_array(scratch.arena, RB_ThreadParams, threads_count);
|
||||
Barrier barrier = barrier_alloc(threads_count);
|
||||
U64 broadcast_val = 0;
|
||||
for EachIndex(idx, threads_count)
|
||||
{
|
||||
threads_params[idx].cmdline = cmdline;
|
||||
threads_params[idx].lane_ctx.lane_idx = idx;
|
||||
threads_params[idx].lane_ctx.lane_count = threads_count;
|
||||
threads_params[idx].lane_ctx.barrier = barrier;
|
||||
threads_params[idx].lane_ctx.lane_idx = idx;
|
||||
threads_params[idx].lane_ctx.lane_count = threads_count;
|
||||
threads_params[idx].lane_ctx.barrier = barrier;
|
||||
threads_params[idx].lane_ctx.broadcast_memory = &broadcast_val;
|
||||
threads[idx] = thread_launch(rb_thread_entry_point, &threads_params[idx]);
|
||||
}
|
||||
for EachIndex(idx, threads_count)
|
||||
|
||||
@@ -1969,19 +1969,19 @@ struct TXT_ArtifactCreateShared
|
||||
};
|
||||
|
||||
internal void *
|
||||
txt_artifact_create(String8 key)
|
||||
txt_artifact_create(String8 key, B32 *retry_out)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
Access *access = access_open();
|
||||
|
||||
//- rjf: get shared state
|
||||
local_persist TXT_ArtifactCreateShared *shared = 0;
|
||||
TXT_ArtifactCreateShared *shared = 0;
|
||||
if(lane_idx() == 0)
|
||||
{
|
||||
shared = push_array(scratch.arena, TXT_ArtifactCreateShared, 1);
|
||||
}
|
||||
lane_sync();
|
||||
lane_sync_u64(&shared, 0);
|
||||
|
||||
//- rjf: unpack key
|
||||
U128 hash = {0};
|
||||
|
||||
@@ -203,7 +203,7 @@ internal TXT_ScopeNode *txt_scope_node_from_info_pt(TXT_TextInfo *info, TxtPt pt
|
||||
////////////////////////////////
|
||||
//~ rjf: Artifact Cache Hooks / Lookups
|
||||
|
||||
internal void *txt_artifact_create(String8 key);
|
||||
internal void *txt_artifact_create(String8 key, B32 *retry_out);
|
||||
internal void txt_artifact_destroy(void *ptr);
|
||||
internal TXT_TextInfo txt_text_info_from_hash_lang(Access *access, U128 hash, TXT_LangKind lang);
|
||||
internal TXT_TextInfo txt_text_info_from_key_lang(Access *access, C_Key key, TXT_LangKind lang, U128 *hash_out);
|
||||
|
||||
Reference in New Issue
Block a user