mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
WIP change symbol extraction approach
This commit is contained in:
@@ -448,6 +448,7 @@ C_LINKAGE void __asan_unpoison_memory_region(void const volatile *addr, size_t s
|
||||
#endif
|
||||
|
||||
#define TryRead(func__, cursor__, label__) do { U64 size__ = (func__); if (size__ == 0) { Assert(0 && "failed read"); goto label__; } cursor__ += size__; } while (0)
|
||||
#define TryReadBreak(func__, cursor__) { U64 size__ = (func__); if (size__ == 0) { Assert(0 && "failed read"); break; } cursor__ += size__; }
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Base Types
|
||||
|
||||
@@ -24,6 +24,16 @@ void_node_concat_atomic(VoidNode **head, VoidNode *node)
|
||||
node->next = ins_atomic_ptr_eval_assign(head, node);
|
||||
}
|
||||
|
||||
internal VoidNode *
|
||||
void_list_push(Arena *arena, VoidList *list, void *v)
|
||||
{
|
||||
VoidNode *n = push_array(arena, VoidNode, 1);
|
||||
n->v = v;
|
||||
SLLQueuePush(list->first, list->last, n);
|
||||
list->count += 1;
|
||||
return n;
|
||||
}
|
||||
|
||||
internal void
|
||||
u64_list_push_node(U64List *list, U64Node *n)
|
||||
{
|
||||
|
||||
@@ -3,49 +3,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef struct VoidNode
|
||||
{
|
||||
struct VoidNode *next;
|
||||
void *v;
|
||||
} VoidNode;
|
||||
typedef struct VoidNode { void *v; struct VoidNode *next; } VoidNode;
|
||||
typedef struct U32Node { U32 data; struct U32Node *next; } U32Node;
|
||||
typedef struct U64Node { U64 data; struct U64Node *next; } U64Node;
|
||||
typedef struct S64Node { S64 v; struct S64Node *next; } S64Node;
|
||||
|
||||
typedef struct U32Node
|
||||
{
|
||||
struct U32Node *next;
|
||||
U32 data;
|
||||
} U32Node;
|
||||
typedef struct VoidList { U64 count; VoidNode *first, *last; } VoidList;
|
||||
typedef struct U64List { U64 count; U64Node *first, *last; } U64List;
|
||||
typedef struct S64List { U64 count; S64Node *first, *last; } S64List;
|
||||
|
||||
typedef struct U64Node
|
||||
{
|
||||
struct U64Node *next;
|
||||
U64 data;
|
||||
} U64Node;
|
||||
|
||||
typedef struct U64List
|
||||
{
|
||||
U64 count;
|
||||
U64Node *first;
|
||||
U64Node *last;
|
||||
} U64List;
|
||||
|
||||
typedef struct S64Node
|
||||
{
|
||||
S64 v;
|
||||
struct S64Node *next;
|
||||
} S64Node;
|
||||
|
||||
typedef struct S64List
|
||||
{
|
||||
U64 count;
|
||||
S64Node *first;
|
||||
S64Node *last;
|
||||
} S64List;
|
||||
|
||||
typedef struct S64Array
|
||||
{
|
||||
U64 count;
|
||||
S64 *v;
|
||||
} S64Array;
|
||||
typedef struct S64Array { U64 count; S64 *v; } S64Array;
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
|
||||
+155
-118
@@ -241,6 +241,67 @@ cv_data_from_symbol(Arena *arena, CV_Symbol *symbol, U64 align)
|
||||
return result;
|
||||
}
|
||||
|
||||
internal U64
|
||||
cv_read_symbol(String8 raw_data, U64 off, U64 align, CV_Symbol *symbol_out)
|
||||
{
|
||||
Assert(raw_data.size >= sizeof(CV_SymbolHeader));
|
||||
|
||||
U8 *symbol_ptr = raw_data.str + off;
|
||||
CV_SymbolHeader header = { .v = memory_read32(symbol_ptr) };
|
||||
|
||||
Assert(header.size >= sizeof(CV_SymKind));
|
||||
Assert(sizeof(CV_SymSize) + header.size <= raw_data.size);
|
||||
|
||||
symbol_out->kind = header.kind;
|
||||
symbol_out->data = str8(symbol_ptr + sizeof(CV_SymbolHeader), header.size - sizeof(CV_SymKind));
|
||||
|
||||
U64 symbol_size = AlignPow2(sizeof(CV_SymbolHeader) + symbol_out->data.size, align);
|
||||
Assert(symbol_size <= raw_data.size);
|
||||
return symbol_size;
|
||||
}
|
||||
|
||||
internal U8 *
|
||||
cv_ptr_from_symbol(CV_Symbol symbol)
|
||||
{
|
||||
return symbol.data.str - sizeof(CV_SymbolHeader);
|
||||
}
|
||||
|
||||
internal CV_SymKind *
|
||||
cv_kind_ptr_from_symbol(CV_Symbol symbol)
|
||||
{
|
||||
return &((CV_SymbolHeader *)cv_ptr_from_symbol(symbol))->kind;
|
||||
}
|
||||
|
||||
internal CV_Symbol
|
||||
cv_symbol_from_ptr(U8 *ptr)
|
||||
{
|
||||
CV_Symbol symbol = {0};
|
||||
cv_read_symbol(str8(ptr, max_U64), 0, 1, &symbol);
|
||||
return symbol;
|
||||
}
|
||||
|
||||
internal String8
|
||||
cv_raw_from_symbol(void *ptr)
|
||||
{
|
||||
CV_SymbolHeader *header = ptr;
|
||||
return str8(ptr, header->size + sizeof(header->size));
|
||||
}
|
||||
|
||||
internal B32
|
||||
cv_symbol_match(CV_Symbol a, CV_Symbol b)
|
||||
{
|
||||
B32 is_match = 0;
|
||||
|
||||
CV_SymbolHeader *a_ptr = (CV_SymbolHeader *)cv_ptr_from_symbol(a);
|
||||
CV_SymbolHeader *b_ptr = (CV_SymbolHeader *)cv_ptr_from_symbol(b);
|
||||
|
||||
if (a_ptr->size == b_ptr->size) {
|
||||
is_match = MemoryMatch(a_ptr + sizeof(CV_SymSize), b_ptr + sizeof(CV_SymSize), a_ptr->size);
|
||||
}
|
||||
|
||||
return is_match;
|
||||
}
|
||||
|
||||
internal String8
|
||||
cv_make_symbol(Arena *arena, CV_SymKind kind, String8 data)
|
||||
{
|
||||
@@ -949,144 +1010,58 @@ cv_pack_string_hash_table(Arena *arena, TP_Context *tp, CV_StringHashTable strin
|
||||
////////////////////////////////
|
||||
//~ Symbol Deduper
|
||||
|
||||
internal int
|
||||
cv_symbol_deduper_is_before(void *raw_a, void *raw_b)
|
||||
internal void *
|
||||
cv_symbol_deduper_insert_or_update(void **buckets, U64 bucket_cap, U64 hash, void *symbol_ptr)
|
||||
{
|
||||
return raw_a < raw_b;
|
||||
}
|
||||
|
||||
internal CV_SymbolNode **
|
||||
cv_symbol_deduper_insert_or_update(CV_SymbolNode ***buckets, U64 cap, U64 hash, CV_SymbolNode **new_bucket)
|
||||
{
|
||||
CV_SymbolNode **result = 0;
|
||||
B32 is_inserted_or_updated = 0;
|
||||
|
||||
U64 best_idx = hash % cap;
|
||||
U64 idx = best_idx;
|
||||
|
||||
CV_Symbol symbol = cv_symbol_from_ptr(symbol_ptr);
|
||||
U8 *result = 0;
|
||||
B32 is_inserted_or_updated = 0;
|
||||
U64 best_idx = hash % bucket_cap;
|
||||
U64 bucket_idx = best_idx;
|
||||
do {
|
||||
retry:;
|
||||
CV_SymbolNode **curr_bucket = buckets[idx];
|
||||
void *curr_ptr = buckets + bucket_idx;
|
||||
Assert(curr_ptr != symbol_ptr);
|
||||
|
||||
Assert(curr_bucket != new_bucket);
|
||||
|
||||
if (curr_bucket == 0) {
|
||||
CV_SymbolNode **compare_bucket = ins_atomic_ptr_eval_cond_assign(&buckets[idx], new_bucket, curr_bucket);
|
||||
|
||||
if (compare_bucket == curr_bucket) {
|
||||
if (curr_ptr == 0) {
|
||||
U8 *cmp = ins_atomic_ptr_eval_cond_assign(&buckets[bucket_idx], symbol_ptr, curr_ptr);
|
||||
if (cmp == curr_ptr) {
|
||||
// success, bucket was inserted
|
||||
is_inserted_or_updated = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// another thread took the bucket...
|
||||
goto retry;
|
||||
} else if ((*curr_bucket)->data.kind == (*new_bucket)->data.kind &&
|
||||
(*curr_bucket)->data.data.size == (*new_bucket)->data.data.size &&
|
||||
MemoryMatch((*curr_bucket)->data.data.str, (*new_bucket)->data.data.str, (*new_bucket)->data.data.size)) {
|
||||
if (cv_symbol_deduper_is_before(curr_bucket, new_bucket)) {
|
||||
result = new_bucket;
|
||||
} else {
|
||||
CV_Symbol curr = cv_symbol_from_ptr(curr_ptr);
|
||||
|
||||
is_inserted_or_updated = 1;
|
||||
if (cv_symbol_match(curr, symbol)) {
|
||||
if (curr_ptr < symbol_ptr) {
|
||||
// do not update, more recent symbol is in the bucket
|
||||
result = symbol_ptr;
|
||||
is_inserted_or_updated = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// don't need to update, more recent leaf is in the bucket
|
||||
break;
|
||||
void *cmp = ins_atomic_ptr_eval_cond_assign(&buckets[bucket_idx], symbol_ptr, curr_ptr);
|
||||
if (cmp == curr_ptr) {
|
||||
result = cmp;
|
||||
is_inserted_or_updated = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// another thread took the bucket...
|
||||
goto retry;
|
||||
}
|
||||
|
||||
CV_SymbolNode **compare_bucket = ins_atomic_ptr_eval_cond_assign(&buckets[idx], new_bucket, curr_bucket);
|
||||
if (compare_bucket == curr_bucket) {
|
||||
result = compare_bucket;
|
||||
|
||||
is_inserted_or_updated = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// another thread took the bucket...
|
||||
goto retry;
|
||||
}
|
||||
|
||||
// advance
|
||||
idx = (idx + 1) % cap;
|
||||
} while (idx != best_idx);
|
||||
|
||||
bucket_idx = (bucket_idx + 1) == bucket_cap ? 0 : bucket_idx + 1;
|
||||
} while (bucket_idx != best_idx);
|
||||
Assert(is_inserted_or_updated);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal
|
||||
THREAD_POOL_TASK_FUNC(cv_symbol_deduper_insert_task)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
CV_SymbolDeduperTask *task = raw_task;
|
||||
Rng1U64 range = task->ranges[task_id];
|
||||
for (U64 symbol_idx = range.min; symbol_idx < range.max; ++symbol_idx) {
|
||||
CV_SymbolNode **symbol_node = &task->symbols[symbol_idx];
|
||||
U64 hash = hash_from_cv_symbol(&(*symbol_node)->data);
|
||||
cv_symbol_deduper_insert_or_update(task->u.buckets, task->cap, hash, symbol_node);
|
||||
}
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
internal
|
||||
THREAD_POOL_TASK_FUNC(cv_symbol_deduper_deref_buckets_task)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
CV_SymbolDeduperTask *task = raw_task;
|
||||
Rng1U64 range = task->ranges[task_id];
|
||||
for (U64 bucket_idx = range.min; bucket_idx < range.max; ++bucket_idx) {
|
||||
CV_SymbolNode **bucket = task->u.buckets[bucket_idx];
|
||||
if (bucket) {
|
||||
task->u.deref_buckets[bucket_idx] = *bucket;
|
||||
}
|
||||
}
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
internal void
|
||||
cv_dedup_symbol_ptr_array(TP_Context *tp, CV_SymbolPtrArray *symbols)
|
||||
{
|
||||
ProfBeginDynamic("Dedup Symbols [Count %llu]", symbols->count);
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
|
||||
ProfBegin("Setup Task");
|
||||
CV_SymbolDeduperTask task = {0};
|
||||
task.symbols = symbols->v;
|
||||
task.cap = (U64)((F64)symbols->count * 1.3);
|
||||
task.u.buckets = push_array(scratch.arena, CV_SymbolNode **, task.cap);
|
||||
ProfEnd();
|
||||
|
||||
ProfBegin("Dedup");
|
||||
task.ranges = tp_divide_work(scratch.arena, symbols->count, tp->worker_count);
|
||||
tp_for_parallel(tp, 0, tp->worker_count, cv_symbol_deduper_insert_task, &task);
|
||||
ProfEnd();
|
||||
|
||||
ProfBegin("Deref Buckets");
|
||||
task.ranges = tp_divide_work(scratch.arena, task.cap, tp->worker_count);
|
||||
tp_for_parallel(tp, 0, tp->worker_count, cv_symbol_deduper_deref_buckets_task, &task);
|
||||
ProfEnd();
|
||||
|
||||
ProfBegin("Copy Extant Buckets");
|
||||
U64 unique_symbol_count = 0;
|
||||
for (U64 bucket_idx = 0; bucket_idx < task.cap; ++bucket_idx) {
|
||||
CV_SymbolNode *bucket = task.u.deref_buckets[bucket_idx];
|
||||
if (bucket) {
|
||||
symbols->v[unique_symbol_count++] = bucket;
|
||||
}
|
||||
}
|
||||
ProfEnd();
|
||||
|
||||
Assert(unique_symbol_count <= symbols->count);
|
||||
symbols->count = unique_symbol_count;
|
||||
|
||||
ProfBeginDynamic("Sort [Count %llu]", symbols->count);
|
||||
radsort(symbols->v, symbols->count, cv_symbol_deduper_is_before);
|
||||
ProfEnd();
|
||||
|
||||
scratch_end(scratch);
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ .debug$T helpers
|
||||
|
||||
@@ -1528,6 +1503,68 @@ cv_patch_symbol_tree_offsets(CV_SymbolList list, U64 base_offset, U64 align)
|
||||
return serial_size;
|
||||
}
|
||||
|
||||
internal U64
|
||||
cv_patch_symbol_tree_offsets_new(String8List raw_symbols, U64 base_offset, U64 align)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
struct Stack { struct Stack *next; CV_Symbol symbol; U64 offset; };
|
||||
struct Stack *stack = 0, *free_list = 0;
|
||||
U64 symbol_offset = safe_cast_u32(base_offset);
|
||||
for EachNode(n, String8Node, raw_symbols.first) {
|
||||
for (U64 cursor = 0, depth = 0; cursor + sizeof(CV_SymbolHeader) <= n->string.size; ) {
|
||||
CV_Symbol symbol = {0};
|
||||
U64 read_size = cv_read_symbol(n->string, cursor, CV_SymbolAlign, &symbol);
|
||||
if (read_size == 0) { break; }
|
||||
cursor += read_size;
|
||||
|
||||
if (symbol.kind == CV_SymKind_SKIP) { continue; }
|
||||
|
||||
if (cv_is_scope_symbol(symbol.kind)) {
|
||||
// NOTE: We don't patch 'next' offset in PROC symbols because
|
||||
// it's not used by visual studio and MSVC leaves the offsets
|
||||
// zeroed. LLD is on the same page.
|
||||
Assert(symbol.data.size >= sizeof(U32)*2);
|
||||
|
||||
// patch parent symbol offset
|
||||
if (stack) {
|
||||
memory_write32(symbol.data.str, stack->offset);
|
||||
}
|
||||
|
||||
// reuse/alloc frame
|
||||
struct Stack *frame = free_list;
|
||||
if (frame) { SLLStackPop(free_list); }
|
||||
else { frame = push_array_no_zero(scratch.arena, struct Stack, 1); }
|
||||
|
||||
// push frame to the stack
|
||||
frame->symbol = symbol;
|
||||
frame->offset = symbol_offset;
|
||||
SLLStackPush(stack, frame);
|
||||
|
||||
depth += 1;
|
||||
} else if (cv_is_end_symbol(symbol.kind)) {
|
||||
// patch symbol end
|
||||
U32 *end_off_ptr = (U32 *)stack->symbol.data.str + /* skip parent off */ 1;
|
||||
memory_write32(end_off_ptr, symbol_offset);
|
||||
|
||||
// recycle frame
|
||||
struct Stack *free_frame = stack;
|
||||
SLLStackPop(stack);
|
||||
SLLStackPush(free_list, free_frame);
|
||||
|
||||
if (depth == 0) { Assert(0 && "malformed symbol stream"); goto next_block; }
|
||||
depth -= 1;
|
||||
}
|
||||
|
||||
// advance tree offset
|
||||
symbol_offset += cv_size_from_symbol(&symbol, align);
|
||||
}
|
||||
next_block:;
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
return symbol_offset - base_offset;
|
||||
}
|
||||
|
||||
// $$FileChksms
|
||||
|
||||
internal void
|
||||
|
||||
@@ -14,10 +14,13 @@ typedef union CV_LeafHeader
|
||||
U32 v;
|
||||
} CV_LeafHeader;
|
||||
|
||||
typedef struct CV_SymbolHeader
|
||||
typedef union CV_SymbolHeader
|
||||
{
|
||||
CV_SymSize size;
|
||||
CV_SymKind kind;
|
||||
struct {
|
||||
CV_SymSize size;
|
||||
CV_SymKind kind;
|
||||
};
|
||||
U32 v;
|
||||
} CV_SymbolHeader;
|
||||
|
||||
////////////////////////////////
|
||||
@@ -337,17 +340,6 @@ typedef struct CV_StringHashTableResult
|
||||
////////////////////////////////
|
||||
//~ Task Contexts
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U64 cap;
|
||||
union {
|
||||
CV_SymbolNode ***buckets;
|
||||
CV_SymbolNode **deref_buckets;
|
||||
} u;
|
||||
Rng1U64 *ranges;
|
||||
CV_SymbolNode **symbols;
|
||||
} CV_SymbolDeduperTask;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CV_SymbolList *list_arr;
|
||||
@@ -398,6 +390,13 @@ internal U64 cv_size_from_symbol(CV_Symbol *symbol, U64 align);
|
||||
internal U64 cv_write_symbol(U8 *buffer, U64 buffer_cursor, U64 buffer_size, CV_Symbol *symbol, U64 align);
|
||||
internal String8 cv_data_from_symbol(Arena *arena, CV_Symbol *symbol, U64 align);
|
||||
|
||||
internal U64 cv_read_symbol(String8 raw_data, U64 off, U64 align, CV_Symbol *symbol_out);
|
||||
internal U8 * cv_ptr_from_symbol(CV_Symbol symbol);
|
||||
internal CV_SymKind * cv_kind_ptr_from_symbol(CV_Symbol symbol);
|
||||
internal CV_Symbol cv_symbol_from_ptr(U8 *ptr);
|
||||
internal String8 cv_raw_from_symbol(void *ptr);
|
||||
internal B32 cv_symbol_match(CV_Symbol a, CV_Symbol b);
|
||||
|
||||
internal String8 cv_make_symbol(Arena *arena, CV_SymKind kind, String8 data);
|
||||
internal String8 cv_make_obj_name(Arena *arena, String8 obj_path, U32 sig);
|
||||
internal String8 cv_make_comp3(Arena *arena, CV_Compile3Flags flags, CV_Language lang, CV_Arch arch, U16 ver_fe_major, U16 ver_fe_minor, U16 ver_fe_build, U16 ver_feqfe, U16 ver_major, U16 ver_minor, U16 ver_build, U16 ver_qfe, String8 version_string);
|
||||
|
||||
+10
-22
@@ -5144,8 +5144,8 @@ lnk_run(TP_Context *tp, TP_Arena *arena, LNK_Config *config)
|
||||
//
|
||||
// CodeView
|
||||
//
|
||||
LNK_CodeViewInput input = lnk_make_code_view_input(tp, arena, config->io_flags, config->lib_dir_list, config->alt_pch_dirs, debug_info_objs_count, debug_info_objs);
|
||||
LNK_MergedTypes merged_types = lnk_merge_types(tp, arena, &input);
|
||||
LNK_CodeViewInput cv = lnk_make_code_view_input(tp, arena, config->io_flags, config->lib_dir_list, config->alt_pch_dirs, debug_info_objs_count, debug_info_objs);
|
||||
LNK_MergedTypes cv_types = lnk_merge_types(tp, arena, &cv);
|
||||
|
||||
//
|
||||
// RDI
|
||||
@@ -5161,11 +5161,11 @@ lnk_run(TP_Context *tp, TP_Arena *arena, LNK_Config *config)
|
||||
image_ctx.image_data,
|
||||
debug_info_objs_count,
|
||||
debug_info_objs,
|
||||
input.debug_s_arr,
|
||||
input.symbol_input_count,
|
||||
input.symbol_inputs,
|
||||
input.parsed_symbols,
|
||||
merged_types);
|
||||
cv.debug_s_arr,
|
||||
cv.symbol_input_count,
|
||||
cv.symbol_inputs,
|
||||
(CV_SymbolListArray[]){0},
|
||||
cv_types);
|
||||
|
||||
lnk_write_data_list_to_file_path(config->rad_debug_name, config->temp_rad_debug_name, rdi_data);
|
||||
|
||||
@@ -5183,26 +5183,14 @@ lnk_run(TP_Context *tp, TP_Arena *arena, LNK_Config *config)
|
||||
if (config->pdb_hash_type_names != LNK_TypeNameHashMode_Null && config->pdb_hash_type_names != LNK_TypeNameHashMode_None) {
|
||||
lnk_replace_type_names_with_hashes(tp,
|
||||
arena,
|
||||
merged_types.count[CV_TypeIndexSource_TPI],
|
||||
merged_types.v [CV_TypeIndexSource_TPI],
|
||||
cv_types.count[CV_TypeIndexSource_TPI],
|
||||
cv_types.v [CV_TypeIndexSource_TPI],
|
||||
config->pdb_hash_type_names,
|
||||
config->pdb_hash_type_name_length,
|
||||
config->pdb_hash_type_name_map);
|
||||
}
|
||||
|
||||
String8List pdb_data = lnk_build_pdb(tp,
|
||||
arena,
|
||||
image_ctx.image_data,
|
||||
config,
|
||||
symtab,
|
||||
debug_info_objs_count,
|
||||
debug_info_objs,
|
||||
input.debug_s_arr,
|
||||
input.symbol_input_count,
|
||||
input.symbol_inputs,
|
||||
input.parsed_symbols,
|
||||
merged_types);
|
||||
|
||||
String8List pdb_data = lnk_build_pdb(tp, arena, image_ctx.image_data, config, symtab, &cv, cv_types);
|
||||
lnk_write_data_list_to_file_path(config->pdb_name, config->temp_pdb_name, pdb_data);
|
||||
lnk_timer_end(LNK_Timer_Pdb);
|
||||
}
|
||||
|
||||
+588
-569
File diff suppressed because it is too large
Load Diff
+113
-212
@@ -3,38 +3,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
// --- Symbol Parsing Tasks ----------------------------------------------------
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_Obj **obj_arr;
|
||||
String8List *sect_list_arr;
|
||||
CV_DebugS *debug_s_arr;
|
||||
} LNK_ParseDebugSTaskData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_Obj **obj_arr;
|
||||
String8Array *data_arr_arr;
|
||||
} LNK_CheckDebugTSigTaskData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_Obj **obj_arr;
|
||||
String8Array *data_arr_arr;
|
||||
CV_DebugT *debug_t_arr;
|
||||
} LNK_ParseDebugTTaskData;
|
||||
|
||||
// --- Code View Input ---------------------------------------------------------
|
||||
|
||||
typedef struct LNK_SymbolInput
|
||||
{
|
||||
U64 obj_idx;
|
||||
CV_DebugS *debug_s;
|
||||
CV_SymbolList *symbol_list;
|
||||
String8 raw_symbols;
|
||||
} LNK_SymbolInput;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CV_TypeServerInfo ts_info;
|
||||
@@ -43,8 +13,71 @@ typedef struct
|
||||
U64List obj_indices;
|
||||
} LNK_TypeServer;
|
||||
typedef struct LNK_TypeServerNode { LNK_TypeServer v; struct LNK_TypeServerNode *next; } LNK_TypeServerNode;
|
||||
typedef struct LNK_TypeServerList { U64 count; LNK_TypeServerNode *first; LNK_TypeServerNode *last; } LNK_TypeServerList;
|
||||
typedef struct LNK_TypeServerArray { U64 count; LNK_TypeServer *v; } LNK_TypeServerArray;
|
||||
typedef struct LNK_TypeServerList { U64 count; LNK_TypeServerNode *first, *last; } LNK_TypeServerList;
|
||||
typedef struct LNK_TypeServerArray { U64 count; LNK_TypeServer *v; } LNK_TypeServerArray;
|
||||
|
||||
typedef struct LNK_SymbolInput
|
||||
{
|
||||
U64 obj_idx;
|
||||
String8 raw_symbols;
|
||||
} LNK_SymbolInput;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_IO_Flags io_flags;
|
||||
U64 obj_count;
|
||||
|
||||
U64 count;
|
||||
LNK_Obj **obj_arr;
|
||||
CV_DebugS *debug_s_arr;
|
||||
CV_DebugT *debug_t_arr;
|
||||
CV_DebugH *debug_h_arr;
|
||||
U64 *obj_to_ts;
|
||||
|
||||
String8List *debug_s_list_arr;
|
||||
String8List *debug_p_list_arr;
|
||||
String8List *debug_t_list_arr;
|
||||
|
||||
U32Array int_obj_indices;
|
||||
U32Array ext_obj_indices;
|
||||
U32Array debug_p_indices;
|
||||
U32Array type_server_indices;
|
||||
|
||||
Rng1U64 ts_obj_range;
|
||||
LNK_TypeServerArray ts_arr;
|
||||
B32 *is_type_server_discarded; // [ts_arr.count]
|
||||
CV_TypeIndex min_type_indices[CV_TypeIndexSource_COUNT];
|
||||
|
||||
U64 symbol_input_count;
|
||||
struct LNK_SymbolInput *symbol_inputs; // [symbol_input_count]
|
||||
Rng1U64 *symbol_input_ranges; // [worker_count]
|
||||
} LNK_CodeViewInput;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_CodeViewInput *input;
|
||||
String8Array *raw_types; // [obj_count]
|
||||
CV_DebugT *out_types; // [obj_count]
|
||||
} LNK_ParseCvTypes;
|
||||
|
||||
// --- Leaf Deduping Tasks -----------------------------------------------------
|
||||
|
||||
typedef struct { U32 obj_idx; U32 leaf_idx; } LNK_LeafRef;
|
||||
typedef struct { U64 count; LNK_LeafRef **v; } LNK_LeafRefArray;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U64 cap;
|
||||
LNK_LeafRef **bucket_arr;
|
||||
} LNK_LeafHashTable;
|
||||
|
||||
typedef struct LNK_LeafRange
|
||||
{
|
||||
struct LNK_LeafRange *next;
|
||||
Rng1U64 range;
|
||||
CV_DebugT *debug_t;
|
||||
} LNK_LeafRange;
|
||||
typedef struct { U64 count; LNK_LeafRange *first, *last; } LNK_LeafRangeList;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -53,71 +86,10 @@ typedef struct
|
||||
U8 **v [CV_TypeIndexSource_COUNT];
|
||||
} LNK_MergedTypes;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_IO_Flags io_flags;
|
||||
U64 count;
|
||||
LNK_Obj **obj_arr;
|
||||
CV_DebugS *debug_s_arr;
|
||||
CV_DebugT *debug_t_arr;
|
||||
CV_DebugH *debug_h_arr;
|
||||
U64 *obj_to_ts;
|
||||
CV_SymbolListArray *parsed_symbols; // [count]
|
||||
|
||||
U32Array int_obj_indices;
|
||||
U32Array ext_obj_indices;
|
||||
U32Array debug_p_indices;
|
||||
U32Array type_server_indices;
|
||||
|
||||
Rng1U64 ts_obj_range;
|
||||
LNK_TypeServerArray ts_arr;
|
||||
B32 *is_type_server_discarded; // [ts_arr.count]
|
||||
|
||||
CV_TypeIndex min_type_indices[CV_TypeIndexSource_COUNT];
|
||||
|
||||
U64 symbol_input_count;
|
||||
LNK_SymbolInput *symbol_inputs; // [symbol_input_count]
|
||||
} LNK_CodeViewInput;
|
||||
|
||||
// --- Leaf Deduping Tasks -----------------------------------------------------
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U32 obj_idx;
|
||||
U32 leaf_idx;
|
||||
} LNK_LeafRef;
|
||||
|
||||
typedef struct LNK_LeafRange
|
||||
{
|
||||
struct LNK_LeafRange *next;
|
||||
Rng1U64 range;
|
||||
CV_DebugT *debug_t;
|
||||
} LNK_LeafRange;
|
||||
|
||||
typedef struct LNK_LeafRangeList
|
||||
{
|
||||
U64 count;
|
||||
LNK_LeafRange *first;
|
||||
LNK_LeafRange *last;
|
||||
} LNK_LeafRangeList;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U64 count;
|
||||
LNK_LeafRef **v;
|
||||
} LNK_LeafRefArray;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U64 cap;
|
||||
LNK_LeafRef **bucket_arr;
|
||||
} LNK_LeafHashTable;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_CodeViewInput *input;
|
||||
CV_DebugS *debug_s_arr;
|
||||
CV_SymbolList *symbol_list_arr;
|
||||
LNK_LeafHashTable leaf_ht_arr[CV_TypeIndexSource_COUNT];
|
||||
Arena **fixed_arenas;
|
||||
CV_TypeIndexSource ti_source;
|
||||
@@ -151,112 +123,63 @@ typedef struct
|
||||
LNK_MergedTypes result;
|
||||
} LNK_MergeTypes;
|
||||
|
||||
// --- Code View Processing Trasks ---------------------------------------------
|
||||
// --- Build PDB ---------------------------------------------
|
||||
|
||||
typedef struct
|
||||
{
|
||||
String8List *data_list_arr;
|
||||
} LNK_ProcessedCodeViewC11Data;
|
||||
String8 image_data;
|
||||
LNK_SymbolTable *symtab;
|
||||
LNK_CodeViewInput *cv;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
String8List *data_list_arr;
|
||||
String8List *source_file_names_list_arr;
|
||||
} LNK_ProcessedCodeViewC13Data;
|
||||
PDB_Context *pdb;
|
||||
PDB_DbiModule **mod_arr; // [obj_count]
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_SymbolInput *inputs;
|
||||
} LNK_ParseCVSymbolsTaskData;
|
||||
U64 total_symbol_count;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U64 symbol_input_count;
|
||||
CV_SymbolListArray *parsed_symbols;
|
||||
U64 *serialized_symbol_data_sizes;
|
||||
// GSI symbol dedup
|
||||
U64 bucket_cap;
|
||||
void **buckets; // [bucket_count]
|
||||
U64 *insert_count; // [worker_count]
|
||||
|
||||
LNK_SymbolInput *symbol_inputs;
|
||||
PDB_DbiModule **mod_arr;
|
||||
String8List *symbol_data_arr;
|
||||
CV_SymbolList *gsi_list_arr;
|
||||
} LNK_ProcessSymDataTaskData;
|
||||
Rng1U64 *symbol_ranges; // [worker_count]
|
||||
U64 symbol_count;
|
||||
void **symbol_arr;
|
||||
U32 *symbol_hashes; // [symbol_count]
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CV_DebugS *debug_s_arr;
|
||||
U64 *proc_ref_counts; // [worker_count]
|
||||
U64 *proc_ref_sizes; // [worker_count]
|
||||
U64 *proc_ref_hashes; // [total_proc_ref_count]
|
||||
U64 *proc_ref_offs; // [worker_count]
|
||||
String8 proc_refs;
|
||||
|
||||
U64 *public_symbol_node_counts; // [worker_count]
|
||||
U64 *public_symbol_node_offsets; // [worker_count]
|
||||
CV_SymbolNode *public_symbol_nodes; // [public_symbol_total_count]
|
||||
CV_SymbolList *public_symbols; // [worker_count]
|
||||
U32 **public_symbol_hashes; // [worker_count][public_symbol.count]
|
||||
|
||||
U64 *symbol_sizes; // [obj_count]
|
||||
|
||||
// process C13 data
|
||||
String8List *source_file_names_list_arr;
|
||||
U64 string_data_base_offset;
|
||||
CV_StringHashTable string_ht;
|
||||
} LNK_ProcessC13DataTask;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MSF_Context *msf;
|
||||
PDB_DbiModule **mod_arr;
|
||||
CV_DebugS *debug_s_arr;
|
||||
U64 *serialized_symbol_data_sizes;
|
||||
CV_SymbolListArray *parsed_symbols;
|
||||
String8List *globrefs_arr;
|
||||
U32 *mod_sizes;
|
||||
} LNK_WriteModuleDataTask;
|
||||
// build DBI modules
|
||||
String8List *globrefs_arr; // [obj_count]
|
||||
U32 *mod_sizes; // [obj_count]
|
||||
U64 *serialized_symbol_data_sizes; // [obj_count]
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_Obj **obj_arr;
|
||||
PDB_DbiModule **mod_arr;
|
||||
PDB_DbiSectionContribList *sc_list;
|
||||
String8 image_data;
|
||||
// push DBI SC Map
|
||||
PE_BinInfo pe;
|
||||
COFF_SectionHeader **image_section_table;
|
||||
U64 image_section_table_count;
|
||||
Rng1U64Array image_section_file_ranges;
|
||||
Rng1U64Array image_section_virt_ranges;
|
||||
} LNK_PushDbiSecContribTaskData;
|
||||
PDB_DbiSectionContribList *sc_list; // [obj_count]
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U32Array *hash_arr_arr;
|
||||
CV_SymbolList *list_arr;
|
||||
} LNK_HashCVSymbolListTask;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U64 *hash_arr;
|
||||
CV_SymbolNode **arr;
|
||||
Rng1U64 *range_arr;
|
||||
} LNK_CvSymbolPtrArrayHasher;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_SymbolHashTrieChunkList *chunk_lists;
|
||||
CV_SymbolList *pub_list_arr;
|
||||
|
||||
Rng1U64 *symbol_ranges;
|
||||
PDB_GsiContext *gsi;
|
||||
CV_SymbolPtrArray symbols;
|
||||
U32 *hashes;
|
||||
} LNK_BuildPublicSymbolsTask;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CV_TypeIndex ipi_min_type_index;
|
||||
CV_DebugT ipi_types;
|
||||
LNK_SymbolInput *symbol_inputs;
|
||||
CV_SymbolListArray *parsed_symbols;
|
||||
} LNK_PostProcessCvSymbolsTask;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Rng1U64 *range_arr;
|
||||
CV_SymbolPtrNode **bucket_arr;
|
||||
CV_SymbolPtrNode **out_arr;
|
||||
U64 *out_count_arr;
|
||||
} LNK_GsiDeduper;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Rng1U64 *range_arr;
|
||||
CV_SymbolPtrNode **bucket_arr;
|
||||
U64 *symbol_base_arr;
|
||||
CV_SymbolNode **symbol_arr;
|
||||
} LNK_GsiUnbucket;
|
||||
// make public symbols
|
||||
CV_SymbolList *pub_list_arr;
|
||||
} LNK_BuildPdb;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -350,8 +273,7 @@ typedef struct
|
||||
CV_DebugS *debug_s_arr;
|
||||
U64 leaf_arr_count_ipi;
|
||||
U8 **leaf_arr_ipi;
|
||||
LNK_SymbolInput *symbol_inputs;
|
||||
CV_SymbolListArray *parsed_symbols;
|
||||
LNK_SymbolInput *symbol_inputs;
|
||||
Rng1U64 ipi_itype_range;
|
||||
Rng1U64 tpi_itype_range;
|
||||
RDIB_Type **tpi_itype_map;
|
||||
@@ -387,11 +309,8 @@ typedef struct
|
||||
|
||||
// --- CodeView ----------------------------------------------------------------
|
||||
|
||||
internal CV_DebugS * lnk_parse_debug_s_sections(TP_Context *tp, TP_Arena *arena, U64 obj_count, LNK_Obj **obj_arr, String8List *sect_list_arr);
|
||||
internal CV_DebugT * lnk_parse_debug_t_sections(TP_Context *tp, TP_Arena *arena, U64 obj_count, LNK_Obj **obj_arr, String8List *debug_t_list_arr);
|
||||
internal LNK_CodeViewInput lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_flags, String8List lib_dir_list, String8List alt_pch_dirs, U64 objs_count, LNK_Obj **objs);
|
||||
|
||||
// type merging
|
||||
internal int lnk_leaf_ref_compare (LNK_LeafRef a, LNK_LeafRef b);
|
||||
internal int lnk_leaf_ref_is_before (void *raw_a, void *raw_b);
|
||||
internal B32 lnk_match_leaf_ref (LNK_CodeViewInput *input, LNK_LeafRef a, LNK_LeafRef b);
|
||||
@@ -402,7 +321,11 @@ internal LNK_LeafRef * lnk_leaf_hash_table_search (LNK_LeafHashTable
|
||||
internal LNK_MergedTypes lnk_merge_types (TP_Context *tp, TP_Arena *tp_temp, LNK_CodeViewInput *input);
|
||||
internal void lnk_replace_type_names_with_hashes (TP_Context *tp, TP_Arena *arena, U64 leaf_count, U8 **leaf_arr, LNK_TypeNameHashMode mode, U64 hash_length, String8 map_name);
|
||||
|
||||
// --- RAD Debug info ----------------------------------------------------------
|
||||
// --- PDB ---------------------------------------------------------------------
|
||||
|
||||
internal String8List lnk_build_pdb(TP_Context *tp, TP_Arena *tp_arena, String8 image_data, LNK_Config *config, LNK_SymbolTable *symtab, LNK_CodeViewInput *cv, LNK_MergedTypes cv_types);
|
||||
|
||||
// --- RDI ---------------------------------------------------------------------
|
||||
|
||||
internal U64 lnk_udt_name_hash_table_hash (String8 string);
|
||||
internal LNK_UDTNameBucket ** lnk_udt_name_hash_table_from_leaf_arr(TP_Context *tp, TP_Arena *arena, U64 leaf_count, U8 **leaf_arr, U64 *buckets_cap_out);
|
||||
@@ -429,28 +352,6 @@ lnk_build_rad_debug_info(TP_Context *tp,
|
||||
CV_SymbolListArray *parsed_symbols,
|
||||
LNK_MergedTypes types);
|
||||
|
||||
// --- PDB ---------------------------------------------------------------------
|
||||
|
||||
internal U64 * lnk_hash_cv_symbol_ptr_arr(TP_Context *tp, Arena *arena, CV_SymbolPtrArray arr);
|
||||
internal CV_SymbolPtrArray lnk_dedup_gsi_symbols (TP_Context *tp, Arena *arena, PDB_GsiContext *gsi, U64 obj_count, CV_SymbolList *symbol_list_arr);
|
||||
|
||||
internal void lnk_build_pdb_public_symbols(TP_Context *tp, TP_Arena *arena, LNK_SymbolTable *symtab, PDB_PsiContext *psi);
|
||||
|
||||
internal String8List lnk_build_pdb(TP_Context *tp,
|
||||
TP_Arena *tp_arena,
|
||||
String8 image_data,
|
||||
LNK_Config *config,
|
||||
LNK_SymbolTable *symtab,
|
||||
U64 obj_count,
|
||||
LNK_Obj **obj_arr,
|
||||
CV_DebugS *debug_s_arr,
|
||||
U64 symbol_input_count,
|
||||
LNK_SymbolInput *symbol_inputs,
|
||||
CV_SymbolListArray *parsed_symbols,
|
||||
LNK_MergedTypes types);
|
||||
|
||||
// --- RAD Debug Info ----------------------------------------------------------
|
||||
|
||||
internal U64 lnk_udt_name_hash_table_hash (String8 string);
|
||||
internal LNK_UDTNameBucket ** lnk_udt_name_hash_table_from_leaf_arr(TP_Context *tp, TP_Arena *arena, U64 leaf_count, U8 **leaf_arr, U64 *buckets_cap_out);
|
||||
internal LNK_UDTNameBucket * lnk_udt_name_hash_table_lookup (LNK_UDTNameBucket **buckets, U64 cap, String8 name);
|
||||
|
||||
@@ -3725,7 +3725,7 @@ pdb_get_guid(PDB_Context *pdb)
|
||||
}
|
||||
|
||||
internal void
|
||||
pdb_build(TP_Context *tp, TP_Arena *pool_temp, PDB_Context *pdb, CV_StringHashTable string_ht)
|
||||
pdb_build(TP_Context *tp, TP_Arena *pool_temp, PDB_Context *pdb, CV_StringHashTable string_ht, B32 build_gsi)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
|
||||
@@ -3735,26 +3735,28 @@ pdb_build(TP_Context *tp, TP_Arena *pool_temp, PDB_Context *pdb, CV_StringHashTa
|
||||
PDB_TypeServer *tpi = pdb->type_servers[CV_TypeIndexSource_TPI];
|
||||
PDB_TypeServer *ipi = pdb->type_servers[CV_TypeIndexSource_IPI];
|
||||
|
||||
if (dbi->globals_sn == MSF_INVALID_STREAM_NUMBER) {
|
||||
dbi->globals_sn = msf_stream_alloc(pdb->msf);
|
||||
}
|
||||
if (dbi->publics_sn == MSF_INVALID_STREAM_NUMBER) {
|
||||
dbi->publics_sn = msf_stream_alloc(pdb->msf);
|
||||
}
|
||||
if (dbi->symbols_sn == MSF_INVALID_STREAM_NUMBER) {
|
||||
dbi->symbols_sn = msf_stream_alloc(pdb->msf);
|
||||
}
|
||||
|
||||
pdb_type_server_build(tp, tpi, strtab, pdb->msf, PDB_FixedStream_Tpi);
|
||||
if (info->flags & PDB_FeatureFlag_HAS_ID_STREAM) {
|
||||
pdb_type_server_build(tp, ipi, strtab, pdb->msf, PDB_FixedStream_Ipi);
|
||||
}
|
||||
|
||||
psi_build(tp, pdb->psi, pdb->msf, dbi->publics_sn, dbi->symbols_sn);
|
||||
gsi_build(tp, pdb->gsi, pdb->msf, dbi->globals_sn, dbi->symbols_sn);
|
||||
dbi_build(tp, pdb->dbi, pdb->msf, PDB_FixedStream_Dbi, string_ht);
|
||||
pdb_info_build(pdb->info, pdb->msf, PDB_FixedStream_Info);
|
||||
|
||||
if (build_gsi) {
|
||||
if (dbi->globals_sn == MSF_INVALID_STREAM_NUMBER) {
|
||||
dbi->globals_sn = msf_stream_alloc(pdb->msf);
|
||||
}
|
||||
if (dbi->publics_sn == MSF_INVALID_STREAM_NUMBER) {
|
||||
dbi->publics_sn = msf_stream_alloc(pdb->msf);
|
||||
}
|
||||
if (dbi->symbols_sn == MSF_INVALID_STREAM_NUMBER) {
|
||||
dbi->symbols_sn = msf_stream_alloc(pdb->msf);
|
||||
}
|
||||
psi_build(tp, pdb->psi, pdb->msf, dbi->publics_sn, dbi->symbols_sn);
|
||||
gsi_build(tp, pdb->gsi, pdb->msf, dbi->globals_sn, dbi->symbols_sn);
|
||||
}
|
||||
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
|
||||
@@ -351,7 +351,7 @@ typedef struct
|
||||
internal PDB_Context * pdb_alloc(U64 page_size, COFF_MachineType machine, COFF_TimeStamp time_stamp, U32 age, Guid guid);
|
||||
internal PDB_Context * pdb_open(String8 data);
|
||||
internal void pdb_release(PDB_Context **pdb_ptr);
|
||||
internal void pdb_build(TP_Context *tp, TP_Arena *pool_temp, PDB_Context *pdb, CV_StringHashTable string_ht);
|
||||
internal void pdb_build(TP_Context *tp, TP_Arena *pool_temp, PDB_Context *pdb, CV_StringHashTable string_ht, B32 build_gsi);
|
||||
internal void pdb_set_machine(PDB_Context *pdb, COFF_MachineType machine);
|
||||
internal void pdb_set_guid(PDB_Context *pdb, Guid guid);
|
||||
internal void pdb_set_time_stamp(PDB_Context *pdb, COFF_TimeStamp time_stamp);
|
||||
|
||||
@@ -15,7 +15,7 @@ tp_run_tasks(TP_Context *pool, TP_Worker *worker)
|
||||
// run task
|
||||
Arena *arena = pool->task_arena ? pool->task_arena->v[worker->id] : 0;
|
||||
U64 task_id = pool->task_count - (task_left+1);
|
||||
pool->task_func(arena, worker->id, task_id, pool->task_data);
|
||||
pool->task_func(arena, worker->id, task_id, pool->task_data, pool);
|
||||
|
||||
// cache task count so we dont touch pool memory after atomic inc
|
||||
U64 task_count = pool->task_count;
|
||||
@@ -85,6 +85,7 @@ tp_alloc(Arena *arena, U32 worker_count, U32 max_worker_count, String8 name)
|
||||
pool->exec_semaphore = exec_semaphore;
|
||||
pool->task_semaphore = task_semaphore;
|
||||
pool->main_semaphore = main_semaphore;
|
||||
pool->barrier = barrier_alloc(worker_count);
|
||||
pool->is_live = 1;
|
||||
pool->worker_count = worker_count;
|
||||
pool->worker_arr = push_array(arena, TP_Worker, worker_count);
|
||||
@@ -113,11 +114,11 @@ tp_release(TP_Context *pool)
|
||||
|
||||
B32 is_shared = pool->exec_semaphore.u64[0] != 0;
|
||||
if (is_shared) {
|
||||
for (U64 i = 0; i < pool->worker_count; ++i) {
|
||||
for EachIndex(i, pool->worker_count) {
|
||||
semaphore_drop(pool->exec_semaphore);
|
||||
}
|
||||
}
|
||||
for (U64 i = 0; i < pool->worker_count; ++i) {
|
||||
for EachIndex(i, pool->worker_count) {
|
||||
semaphore_drop(pool->task_semaphore);
|
||||
}
|
||||
for (U64 i = 1; i < pool->worker_count; i += 1) {
|
||||
@@ -126,6 +127,7 @@ tp_release(TP_Context *pool)
|
||||
if (is_shared) {
|
||||
semaphore_release(pool->exec_semaphore);
|
||||
}
|
||||
barrier_release(pool->barrier);
|
||||
semaphore_release(pool->task_semaphore);
|
||||
semaphore_release(pool->main_semaphore);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define THREAD_POOL_TASK_FUNC(name) void name(Arena *arena, U64 worker_id, U64 task_id, void *raw_task)
|
||||
#define THREAD_POOL_TASK_FUNC(name) void name(Arena *arena, U64 worker_id, U64 task_id, void *raw_task, struct TP_Context *tp)
|
||||
typedef THREAD_POOL_TASK_FUNC(TP_TaskFunc);
|
||||
|
||||
typedef struct TP_Arena
|
||||
@@ -31,6 +31,7 @@ typedef struct TP_Context
|
||||
Semaphore exec_semaphore;
|
||||
Semaphore task_semaphore;
|
||||
Semaphore main_semaphore;
|
||||
Barrier barrier;
|
||||
|
||||
U32 worker_count;
|
||||
TP_Worker *worker_arr;
|
||||
|
||||
Reference in New Issue
Block a user