release file maps before exit in parallel before exit

This commit is contained in:
Nikita Smith
2026-07-27 14:47:20 -07:00
committed by Ryan Fleury
parent 58b5b3d92d
commit cb6443ce4e
2 changed files with 53 additions and 0 deletions
+51
View File
@@ -1211,8 +1211,10 @@ lnk_inputer_flush(Arena *arena, TP_Context *tp, LNK_Inputer *inputer, LNK_IO_Fla
ProfBegin("Load Inputs From Disk"); ProfBegin("Load Inputs From Disk");
String8Array thin_input_datas = lnk_read_data_from_file_path_parallel(tp, inputer->arena, io_flags, thin_input_paths); String8Array thin_input_datas = lnk_read_data_from_file_path_parallel(tp, inputer->arena, io_flags, thin_input_paths);
B32 is_mapped = !!(io_flags & (LNK_IO_Flags_MemoryMapFilesReadWrite|LNK_IO_Flags_MemoryMapFilesReadOnly));
for EachIndex(thin_input_idx, thin_inputs_count) { for EachIndex(thin_input_idx, thin_inputs_count) {
thin_inputs[thin_input_idx]->has_disk_read_failed = thin_input_datas.v[thin_input_idx].size == 0; thin_inputs[thin_input_idx]->has_disk_read_failed = thin_input_datas.v[thin_input_idx].size == 0;
thin_inputs[thin_input_idx]->owns_file_map = is_mapped && !thin_inputs[thin_input_idx]->has_disk_read_failed;
thin_inputs[thin_input_idx]->data = thin_input_datas.v[thin_input_idx]; thin_inputs[thin_input_idx]->data = thin_input_datas.v[thin_input_idx];
} }
ProfEnd(); ProfEnd();
@@ -1234,6 +1236,48 @@ lnk_inputer_flush(Arena *arena, TP_Context *tp, LNK_Inputer *inputer, LNK_IO_Fla
return result; return result;
} }
internal
THREAD_POOL_TASK_FUNC(lnk_release_file_map_task)
{
LNK_Input **mapped_inputs = raw_task;
LNK_Input *input = mapped_inputs[task_id];
file_map_view_close((FileMap){0}, input->data.str, r1u64(0, input->data.size));
input->data = str8_zero();
input->owns_file_map = 0;
}
internal void
lnk_inputer_release_file_maps(TP_Context *tp, LNK_Inputer *inputer)
{
Temp scratch = scratch_begin(0, 0);
U64 mapped_input_count = 0;
for EachNode(input, LNK_Input, inputer->objs.first) {
mapped_input_count += input->owns_file_map;
}
for EachNode(input, LNK_Input, inputer->libs.first) {
mapped_input_count += input->owns_file_map;
}
LNK_Input **mapped_inputs = push_array_no_zero(scratch.arena, LNK_Input *, mapped_input_count);
U64 mapped_input_idx = 0;
for EachNode(input, LNK_Input, inputer->objs.first) {
if (input->owns_file_map) {
mapped_inputs[mapped_input_idx++] = input;
}
}
for EachNode(input, LNK_Input, inputer->libs.first) {
if (input->owns_file_map) {
mapped_inputs[mapped_input_idx++] = input;
}
}
Assert(mapped_input_idx == mapped_input_count);
tp_for_parallel(tp, 0, mapped_input_count, lnk_release_file_map_task, mapped_inputs);
scratch_end(scratch);
}
internal void internal void
lnk_lib_member_ref_list_push_node(LNK_LibMemberRefList *list, LNK_LibMemberRef *node) lnk_lib_member_ref_list_push_node(LNK_LibMemberRefList *list, LNK_LibMemberRef *node)
{ {
@@ -6471,6 +6515,13 @@ lnk_run_linker(TP_Context *tp, TP_Arena *arena, LNK_Config *config)
ProfEnd(); ProfEnd();
} }
#if OS_WINDOWS
// for unexplained reasons, file mappings on Windows cause slow process exit times
ProfBegin("Release Input File Maps");
lnk_inputer_release_file_maps(tp, inputer);
ProfEnd();
#endif
// wait for the thread to finish writing image to disk // wait for the thread to finish writing image to disk
thread_join(image_write_thread, -1); thread_join(image_write_thread, -1);
+2
View File
@@ -34,6 +34,7 @@ typedef struct LNK_Input
String8 data; String8 data;
B32 disallow; B32 disallow;
B32 is_thin; B32 is_thin;
B32 owns_file_map;
B32 has_disk_read_failed; B32 has_disk_read_failed;
B32 exclude_from_debug_info; B32 exclude_from_debug_info;
LNK_LibMemberRef *link_member; LNK_LibMemberRef *link_member;
@@ -381,6 +382,7 @@ internal LNK_Input * lnk_inputer_push_lib_thin(LNK_Inputer *inputer, LNK_Config
internal B32 lnk_inputer_has_items(LNK_Inputer *inputer); internal B32 lnk_inputer_has_items(LNK_Inputer *inputer);
internal LNK_InputPtrArray lnk_inputer_flush(Arena *arena, TP_Context *tp, LNK_Inputer *inputer, LNK_IO_Flags io_flags, LNK_InputList *all_inputs, LNK_InputList *new_inputs); internal LNK_InputPtrArray lnk_inputer_flush(Arena *arena, TP_Context *tp, LNK_Inputer *inputer, LNK_IO_Flags io_flags, LNK_InputList *all_inputs, LNK_InputList *new_inputs);
internal void lnk_inputer_release_file_maps(TP_Context *tp, LNK_Inputer *inputer);
// --- Link Context ------------------------------------------------------------ // --- Link Context ------------------------------------------------------------