mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-14 08:02:23 -07:00
impl shared thread pool mode
This commit is contained in:
+7
-2
@@ -3189,8 +3189,13 @@ lnk_run(int argc, char **argv)
|
||||
|
||||
LNK_Config *config = lnk_build_config(scratch.arena, argc, argv);
|
||||
|
||||
TP_Context *tp = tp_alloc(scratch.arena, config->worker_count);
|
||||
TP_Arena *tp_arena = tp_arena_alloc(tp);
|
||||
TP_Context *tp;
|
||||
if (config->shared_thread_pool == LNK_SwitchState_Yes) {
|
||||
tp = tp_alloc_shared(scratch.arena, config->worker_count, config->shared_thread_pool_mutex_name);
|
||||
} else {
|
||||
tp = tp_alloc(scratch.arena, config->worker_count);
|
||||
}
|
||||
TP_Arena *tp_arena = tp_arena_alloc(tp);
|
||||
|
||||
#if PROFILE_TELEMETRY
|
||||
{
|
||||
|
||||
+75
-62
@@ -127,41 +127,43 @@ global read_only struct
|
||||
{ LNK_CmdSwitch_NotImplemented, "WX", "", "" },
|
||||
|
||||
//- internal switches
|
||||
{ LNK_CmdSwitch_Rad_Age, "RAD_AGE", ":#", "Age embeded in EXE and PDB, used to validate incremental build. Default is 1." },
|
||||
{ LNK_CmdSwitch_Rad_BuildInfo, "RAD_BUILD_INFO", "", "Print build info and exit." },
|
||||
{ LNK_CmdSwitch_Rad_CheckUnusedDelayLoadDll, "RAD_CHECK_UNUSED_DELAY_LOAD_DLL", "[:NO]", "" },
|
||||
{ LNK_CmdSwitch_Rad_Debug, "RAD_DEBUG", "[:NO]", "Emit RAD debug info file." },
|
||||
{ LNK_CmdSwitch_Rad_DebugAltPath, "RAD_DEBUGALTPATH", "", "" },
|
||||
{ LNK_CmdSwitch_Rad_DebugName, "RAD_DEBUG_NAME", ":FILENAME", "Sets file name for RAD debug info file." },
|
||||
{ LNK_CmdSwitch_Rad_DelayBind, "RAD_DELAY_BIND", "[:NO]", "" },
|
||||
{ LNK_CmdSwitch_Rad_DoMerge, "RAD_DO_MERGE", "[:NO]", "" },
|
||||
{ LNK_CmdSwitch_Rad_EnvLib, "RAD_ENV_LIB", "[:NO]", "" },
|
||||
{ LNK_CmdSwitch_Rad_Exe, "RAD_EXE", "[:NO]", "" },
|
||||
{ LNK_CmdSwitch_Rad_Guid, "RAD_GUID", ":{IMAGEBLAKE3|XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXXXXX}", "" },
|
||||
{ LNK_CmdSwitch_Rad_IdleWorkers, "RAD_IDLE_WORKERS", ":#", "Number of workers to leave idle." },
|
||||
{ LNK_CmdSwitch_Rad_LargePages, "RAD_LARGE_PAGES", "[:NO]", "Disabled by default on Windows." },
|
||||
{ LNK_CmdSwitch_Rad_LinkVer, "RAD_LINK_VER", ":##,##", "" },
|
||||
{ LNK_CmdSwitch_Rad_Log, "RAD_LOG", ":{ALL,INPUT_OBJ,INPUT_LIB,IO,LINK_STATS,TIMERS}", "" },
|
||||
{ LNK_CmdSwitch_Rad_MtPath, "RAD_MT_PATH", ":EXEPATH", "Exe path to manifest tool, default: " LNK_MANIFEST_MERGE_TOOL_NAME },
|
||||
{ LNK_CmdSwitch_Rad_OsVer, "RAD_OS_VER", ":##,##", "" },
|
||||
{ LNK_CmdSwitch_Rad_PageSize, "RAD_PAGE_SIZE", ":#", "Must be power of two." },
|
||||
{ LNK_CmdSwitch_Rad_PathStyle, "RAD_PATH_STYLE", ":{WindowsAbsolute|UnixAbsolute}", "" },
|
||||
{ LNK_CmdSwitch_Rad_PdbHashTypeNameLength, "RAD_PDB_HASH_TYPE_NAME_LENGTH", ":#", "Number of hash bytes to use to replace type name. Default 8 bytes (Max 16)." },
|
||||
{ LNK_CmdSwitch_Rad_PdbHashTypeNameMap, "RAD_PDB_HASH_TYPE_NAME_MAP", ":FILENAME", "Produce map file with hash -> type name mappings." },
|
||||
{ LNK_CmdSwitch_Rad_PdbHashTypeNames, "RAD_PDB_HASH_TYPE_NAMES", ":{NONE|LENIENT|FULL}", "Replace type names in LF_STRUCTURE and LF_CLASS with hashes." },
|
||||
{ LNK_CmdSwitch_Rad_SectVirtOff, "RAD_SECT_VIRT_OFF", ":#", "Set RVA where section data is placed in memory. For internal use only." },
|
||||
{ LNK_CmdSwitch_Rad_SuppressError, "RAD_SUPPRESS_ERROR", ":#", "" },
|
||||
{ LNK_CmdSwitch_Rad_SymbolTableCapDefined, "RAD_SYMBOL_TABLE_CAP_DEFINED", ":#", "Number of buckets allocated in the symbol table for defined symbols." },
|
||||
{ LNK_CmdSwitch_Rad_SymbolTableCapInternal, "RAD_SYMBOL_TABLE_CAP_INTERNAL", ":#", "Number of buckets allocated in the symbol table for internal symbols." },
|
||||
{ LNK_CmdSwitch_Rad_SymbolTableCapLib, "RAD_SYMBOL_TABLE_CAP_LIB", ":#", "Number of buckets allocated in the symbol table for library symbols." },
|
||||
{ LNK_CmdSwitch_Rad_SymbolTableCapWeak, "RAD_SYMBOL_TABLE_CAP_WEAK", ":#", "Number of buckets allocated in the symbol table for weak symbols." },
|
||||
{ LNK_CmdSwitch_Rad_TargetOs, "RAD_TARGET_OS", ":{WINDOWS,LINUX,MAC}" },
|
||||
{ LNK_CmdSwitch_Rad_TimeStamp, "RAD_TIME_STAMP", ":#", "Time stamp embeded in EXE and PDB." },
|
||||
{ LNK_CmdSwitch_Rad_Version, "RAD_VERSION", "", "Print version and exit." },
|
||||
{ LNK_CmdSwitch_Rad_Workers, "RAD_WORKERS", ":#", "Sets number of workers created in the pool. Number is capped at 1024." },
|
||||
{ LNK_CmdSwitch_Rad_Age, "RAD_AGE", ":#", "Age embeded in EXE and PDB, used to validate incremental build. Default is 1." },
|
||||
{ LNK_CmdSwitch_Rad_BuildInfo, "RAD_BUILD_INFO", "", "Print build info and exit." },
|
||||
{ LNK_CmdSwitch_Rad_CheckUnusedDelayLoadDll, "RAD_CHECK_UNUSED_DELAY_LOAD_DLL", "[:NO]", "" },
|
||||
{ LNK_CmdSwitch_Rad_Debug, "RAD_DEBUG", "[:NO]", "Emit RAD debug info file." },
|
||||
{ LNK_CmdSwitch_Rad_DebugAltPath, "RAD_DEBUGALTPATH", "", "" },
|
||||
{ LNK_CmdSwitch_Rad_DebugName, "RAD_DEBUG_NAME", ":FILENAME", "Sets file name for RAD debug info file." },
|
||||
{ LNK_CmdSwitch_Rad_DelayBind, "RAD_DELAY_BIND", "[:NO]", "" },
|
||||
{ LNK_CmdSwitch_Rad_DoMerge, "RAD_DO_MERGE", "[:NO]", "" },
|
||||
{ LNK_CmdSwitch_Rad_EnvLib, "RAD_ENV_LIB", "[:NO]", "" },
|
||||
{ LNK_CmdSwitch_Rad_Exe, "RAD_EXE", "[:NO]", "" },
|
||||
{ LNK_CmdSwitch_Rad_Guid, "RAD_GUID", ":{IMAGEBLAKE3|XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXXXXX}", "" },
|
||||
{ LNK_CmdSwitch_Rad_IdleWorkers, "RAD_IDLE_WORKERS", ":#", "Number of workers to leave idle." },
|
||||
{ LNK_CmdSwitch_Rad_LargePages, "RAD_LARGE_PAGES", "[:NO]", "Disabled by default on Windows." },
|
||||
{ LNK_CmdSwitch_Rad_LinkVer, "RAD_LINK_VER", ":##,##", "" },
|
||||
{ LNK_CmdSwitch_Rad_Log, "RAD_LOG", ":{ALL,INPUT_OBJ,INPUT_LIB,IO,LINK_STATS,TIMERS}", "" },
|
||||
{ LNK_CmdSwitch_Rad_MtPath, "RAD_MT_PATH", ":EXEPATH", "Exe path to manifest tool, default: " LNK_MANIFEST_MERGE_TOOL_NAME },
|
||||
{ LNK_CmdSwitch_Rad_OsVer, "RAD_OS_VER", ":##,##", "" },
|
||||
{ LNK_CmdSwitch_Rad_PageSize, "RAD_PAGE_SIZE", ":#", "Must be power of two." },
|
||||
{ LNK_CmdSwitch_Rad_PathStyle, "RAD_PATH_STYLE", ":{WindowsAbsolute|UnixAbsolute}", "" },
|
||||
{ LNK_CmdSwitch_Rad_PdbHashTypeNameLength, "RAD_PDB_HASH_TYPE_NAME_LENGTH", ":#", "Number of hash bytes to use to replace type name. Default 8 bytes (Max 16)." },
|
||||
{ LNK_CmdSwitch_Rad_PdbHashTypeNameMap, "RAD_PDB_HASH_TYPE_NAME_MAP", ":FILENAME", "Produce map file with hash -> type name mappings." },
|
||||
{ LNK_CmdSwitch_Rad_PdbHashTypeNames, "RAD_PDB_HASH_TYPE_NAMES", ":{NONE|LENIENT|FULL}", "Replace type names in LF_STRUCTURE and LF_CLASS with hashes." },
|
||||
{ LNK_CmdSwitch_Rad_SectVirtOff, "RAD_SECT_VIRT_OFF", ":#", "Set RVA where section data is placed in memory. For internal use only." },
|
||||
{ LNK_CmdSwitch_Rad_SharedThreadPool, "RAD_SHARED_THREAD_POOL", "[:NO]", "" },
|
||||
{ LNK_CmdSwitch_Rad_SharedThreadPoolMutexName, "RAD_SHARED_THREAD_POOL_MUTEX_NAME", ":STRING", "" },
|
||||
{ LNK_CmdSwitch_Rad_SuppressError, "RAD_SUPPRESS_ERROR", ":#", "" },
|
||||
{ LNK_CmdSwitch_Rad_SymbolTableCapDefined, "RAD_SYMBOL_TABLE_CAP_DEFINED", ":#", "Number of buckets allocated in the symbol table for defined symbols." },
|
||||
{ LNK_CmdSwitch_Rad_SymbolTableCapInternal, "RAD_SYMBOL_TABLE_CAP_INTERNAL", ":#", "Number of buckets allocated in the symbol table for internal symbols." },
|
||||
{ LNK_CmdSwitch_Rad_SymbolTableCapLib, "RAD_SYMBOL_TABLE_CAP_LIB", ":#", "Number of buckets allocated in the symbol table for library symbols." },
|
||||
{ LNK_CmdSwitch_Rad_SymbolTableCapWeak, "RAD_SYMBOL_TABLE_CAP_WEAK", ":#", "Number of buckets allocated in the symbol table for weak symbols." },
|
||||
{ LNK_CmdSwitch_Rad_TargetOs, "RAD_TARGET_OS", ":{WINDOWS,LINUX,MAC}" },
|
||||
{ LNK_CmdSwitch_Rad_TimeStamp, "RAD_TIME_STAMP", ":#", "Time stamp embeded in EXE and PDB." },
|
||||
{ LNK_CmdSwitch_Rad_Version, "RAD_VERSION", "", "Print version and exit." },
|
||||
{ LNK_CmdSwitch_Rad_Workers, "RAD_WORKERS", ":#", "Sets number of workers created in the pool. Number is capped at 1024." },
|
||||
|
||||
{ LNK_CmdSwitch_Help, "HELP", "", "" },
|
||||
{ LNK_CmdSwitch_Help, "?", "", "" },
|
||||
{ LNK_CmdSwitch_Help, "HELP", "", "" },
|
||||
{ LNK_CmdSwitch_Help, "?", "", "" },
|
||||
};
|
||||
|
||||
global read_only struct
|
||||
@@ -944,6 +946,8 @@ lnk_expand_env_vars_windows(Arena *arena, HashTable *env_vars, String8 string)
|
||||
internal void
|
||||
lnk_apply_cmd_option_to_config(Arena *arena, LNK_Config *config, String8 cmd_name, String8List value_strings, String8 obj_path, String8 lib_path)
|
||||
{
|
||||
Assert(cmd_name.size); // switch must have a defined name in the table
|
||||
|
||||
Temp scratch = scratch_begin(&arena,1);
|
||||
|
||||
LNK_CmdSwitchType cmd_switch = lnk_cmd_switch_type_from_string(cmd_name);
|
||||
@@ -1672,6 +1676,14 @@ lnk_apply_cmd_option_to_config(Arena *arena, LNK_Config *config, String8 cmd_nam
|
||||
}
|
||||
} break;
|
||||
|
||||
case LNK_CmdSwitch_Rad_SharedThreadPool: {
|
||||
lnk_cmd_switch_parse_flag(obj_path, lib_path, cmd_switch, value_strings, &config->shared_thread_pool);
|
||||
} break;
|
||||
|
||||
case LNK_CmdSwitch_Rad_SharedThreadPoolMutexName: {
|
||||
lnk_cmd_switch_parse_string(obj_path, lib_path, cmd_switch, value_strings, &config->shared_thread_pool_mutex_name);
|
||||
} break;
|
||||
|
||||
case LNK_CmdSwitch_Rad_SuppressError: {
|
||||
U64List error_code_list = {0};
|
||||
if (lnk_cmd_switch_parse_u64_list(scratch.arena, obj_path, lib_path, cmd_switch, value_strings, &error_code_list, 0)) {
|
||||
@@ -1754,34 +1766,35 @@ lnk_config_from_cmd_line(Arena *arena, String8List raw_cmd_line)
|
||||
if (lnk_cmd_line_has_switch(cmd_line, LNK_CmdSwitch_Dll)) {
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_SubSystem, "%S", pe_string_from_subsystem(PE_WindowsSubsystem_WINDOWS_GUI));
|
||||
}
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_HighEntropyVa, "");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_ManifestUac, "\"level='asInvoker' uiAccess='false'\"");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_NxCompat, "");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_FunctionPadMin, "0");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_LargeAddressAware, "");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_PdbAltPath, "%%_RAD_PDB_PATH%%");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_PdbPageSize, "%u", KB(4));
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_TimeStamp, "%u", os_get_process_start_time_unix());
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Age, "%u", 1);
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_CheckUnusedDelayLoadDll, "");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_DelayBind, "");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_DoMerge, "");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_EnvLib, "");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Exe, "");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Guid, "imageblake3");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_LargePages, "no");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_LinkVer, "14.0");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_OsVer, "6.0");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_PageSize, "%u", KB(4));
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_PathStyle, "system");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SectVirtOff, "0x1000");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Workers, "%u", os_get_system_info()->logical_processor_count);
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_TargetOs, "windows");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SymbolTableCapDefined, "0x3ffff");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SymbolTableCapInternal, "0x1000");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SymbolTableCapWeak, "0x3ffff");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SymbolTableCapLib, "0x3ffff");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_DebugAltPath, "%%_RAD_RDI_PATH%%");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_HighEntropyVa, "");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_ManifestUac, "\"level='asInvoker' uiAccess='false'\"");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_NxCompat, "");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_FunctionPadMin, "0");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_LargeAddressAware, "");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_PdbAltPath, "%%_RAD_PDB_PATH%%");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_PdbPageSize, "%u", KB(4));
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_TimeStamp, "%u", os_get_process_start_time_unix());
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Age, "%u", 1);
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_CheckUnusedDelayLoadDll, "");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_DelayBind, "");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_DoMerge, "");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_EnvLib, "");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Exe, "");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Guid, "imageblake3");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_LargePages, "no");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_LinkVer, "14.0");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_OsVer, "6.0");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_PageSize, "%u", KB(4));
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_PathStyle, "system");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SectVirtOff, "0x1000");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Workers, "%u", os_get_system_info()->logical_processor_count);
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_TargetOs, "windows");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SymbolTableCapDefined, "0x3ffff");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SymbolTableCapInternal, "0x1000");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SymbolTableCapWeak, "0x3ffff");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SymbolTableCapLib, "0x3ffff");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_DebugAltPath, "%%_RAD_RDI_PATH%%");
|
||||
lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SharedThreadPoolMutexName, "RADLINK_THREAD_POOL_MUTEX");
|
||||
#if BUILD_DEBUG
|
||||
lnk_cmd_line_push_optionf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Log, "debug");
|
||||
lnk_cmd_line_push_optionf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Log, "io_write");
|
||||
|
||||
@@ -147,6 +147,8 @@ typedef enum
|
||||
LNK_CmdSwitch_Rad_PdbHashTypeNameMap,
|
||||
LNK_CmdSwitch_Rad_PdbHashTypeNameLength,
|
||||
LNK_CmdSwitch_Rad_SectVirtOff,
|
||||
LNK_CmdSwitch_Rad_SharedThreadPool,
|
||||
LNK_CmdSwitch_Rad_SharedThreadPoolMutexName,
|
||||
LNK_CmdSwitch_Rad_SuppressError,
|
||||
LNK_CmdSwitch_Rad_SymbolTableCapDefined,
|
||||
LNK_CmdSwitch_Rad_SymbolTableCapInternal,
|
||||
@@ -310,6 +312,8 @@ typedef struct LNK_Config
|
||||
U64 pdb_page_size;
|
||||
U64 worker_count;
|
||||
U64 idle_worker_count;
|
||||
LNK_SwitchState shared_thread_pool;
|
||||
String8 shared_thread_pool_mutex_name;
|
||||
U64 *function_pad_min;
|
||||
U64 *manifest_resource_id;
|
||||
B32 no_default_libs;
|
||||
|
||||
@@ -81,12 +81,25 @@ tp_alloc(Arena *arena, U32 worker_count)
|
||||
return pool;
|
||||
}
|
||||
|
||||
internal TP_Context *
|
||||
tp_alloc_shared(Arena *arena, U32 worker_count, String8 name)
|
||||
{
|
||||
TP_Context *tp = tp_alloc(arena, worker_count);
|
||||
tp->shared_mutex_name = name;
|
||||
tp->shared_mutex_handle = os_shared_mutex_alloc(name);
|
||||
AssertAlways(!os_handle_match(tp->shared_mutex_handle, os_handle_zero()));
|
||||
return tp;
|
||||
}
|
||||
|
||||
internal void
|
||||
tp_release(TP_Context *pool)
|
||||
{
|
||||
pool->is_live = 0;
|
||||
os_semaphore_release(pool->task_semaphore);
|
||||
os_semaphore_release(pool->main_semaphore);
|
||||
if (!os_handle_match(pool->shared_mutex_handle, os_handle_zero())) {
|
||||
os_mutex_release(pool->shared_mutex_handle);
|
||||
}
|
||||
for (U64 i = 1; i < pool->worker_count; i += 1) {
|
||||
os_thread_detach(pool->worker_arr[i].handle);
|
||||
}
|
||||
@@ -160,13 +173,20 @@ tp_for_parallel(TP_Context *pool, TP_Arena *arena, U64 task_count, TP_TaskFunc *
|
||||
{
|
||||
Assert(!arena || arena->count == pool->worker_count);
|
||||
|
||||
// in shared mode take mutex
|
||||
if (!os_handle_match(pool->shared_mutex_handle, os_handle_zero())) {
|
||||
if (!os_shared_mutex_take(pool->shared_mutex_handle, max_U64)) {
|
||||
AssertAlways(!"failed to take shared mutex");
|
||||
}
|
||||
}
|
||||
|
||||
// setup pool state
|
||||
pool->worker_arena = arena;
|
||||
pool->task_count = task_count;
|
||||
pool->task_func = task_func;
|
||||
pool->task_data = task_data;
|
||||
pool->task_count = task_count;
|
||||
pool->task_func = task_func;
|
||||
pool->task_data = task_data;
|
||||
pool->next_task_id = 0;
|
||||
pool->take_count = 0;
|
||||
pool->take_count = 0;
|
||||
|
||||
// do we have enough work for other workers?
|
||||
pool->take_count = Min(pool->task_count, pool->worker_count);
|
||||
@@ -183,6 +203,11 @@ tp_for_parallel(TP_Context *pool, TP_Arena *arena, U64 task_count, TP_TaskFunc *
|
||||
// wait for workers to finish assigned tasks
|
||||
os_semaphore_take(pool->main_semaphore, max_U64);
|
||||
}
|
||||
|
||||
// signal other thread pools that we have done our round of tasks
|
||||
if (!os_handle_match(pool->shared_mutex_handle, os_handle_zero())) {
|
||||
os_shared_mutex_drop(pool->shared_mutex_handle);
|
||||
}
|
||||
}
|
||||
|
||||
internal Rng1U64 *
|
||||
|
||||
@@ -29,6 +29,8 @@ typedef struct TP_Context
|
||||
{
|
||||
OS_Handle task_semaphore;
|
||||
OS_Handle main_semaphore;
|
||||
OS_Handle shared_mutex_handle;
|
||||
String8 shared_mutex_name;
|
||||
B32 is_live;
|
||||
U32 worker_count;
|
||||
TP_Worker *worker_arr;
|
||||
@@ -41,6 +43,7 @@ typedef struct TP_Context
|
||||
} TP_Context;
|
||||
|
||||
internal TP_Context * tp_alloc(Arena *arena, U32 worker_count);
|
||||
internal TP_Context * tp_alloc_shared(Arena *arena, U32 worker_count, String8 name);
|
||||
internal void tp_release(TP_Context *pool);
|
||||
internal TP_Arena * tp_arena_alloc(TP_Context *pool);
|
||||
internal void tp_arena_release(TP_Arena **arena_ptr);
|
||||
|
||||
Reference in New Issue
Block a user