authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-23 14:04:34-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-23 14:08:03-07:00
log322d71139d2e28f9332b5397ae8b14d04e27b5df
treef211f676366dd0dcdc7ac403b15776f09cd34f4d
parentd210f733f80731487f8f83caf621e04506f50bb4

link.MachO: remove buggy multi-threading

thread-sanitizer reports data races here when running test-link. I tried only removing the ones that triggered races, but after 10 back and forths with the compiler and tsan, I got impatient and removed all of them. next time, let's be sure the test suite runs tsan-clean before merging any changes that add parallelism. after this commit, `zig build test-link` completes without any tsan warnings. closes #21778

2 files changed, 48 insertions(+), 92 deletions(-)

src/link/MachO.zig+35-68
......@@ -875,18 +875,13 @@ pub fn parseInputFiles(self: *MachO) !void {
875875 defer tracy.end();
876876
877877 const diags = &self.base.comp.link_diags;
878 const tp = self.base.comp.thread_pool;
879 var wg: WaitGroup = .{};
880878
881879 {
882 wg.reset();
883 defer wg.wait();
884
885880 for (self.objects.items) |index| {
886 tp.spawnWg(&wg, parseInputFileWorker, .{ self, self.getFile(index).? });
881 parseInputFileWorker(self, self.getFile(index).?);
887882 }
888883 for (self.dylibs.items) |index| {
889 tp.spawnWg(&wg, parseInputFileWorker, .{ self, self.getFile(index).? });
884 parseInputFileWorker(self, self.getFile(index).?);
890885 }
891886 }
892887
......@@ -1269,17 +1264,13 @@ fn markLive(self: *MachO) void {
12691264}
12701265
12711266fn convertTentativeDefsAndResolveSpecialSymbols(self: *MachO) !void {
1272 const tp = self.base.comp.thread_pool;
12731267 const diags = &self.base.comp.link_diags;
1274 var wg: WaitGroup = .{};
12751268 {
1276 wg.reset();
1277 defer wg.wait();
12781269 for (self.objects.items) |index| {
1279 tp.spawnWg(&wg, convertTentativeDefinitionsWorker, .{ self, self.getFile(index).?.object });
1270 convertTentativeDefinitionsWorker(self, self.getFile(index).?.object);
12801271 }
12811272 if (self.getInternalObject()) |obj| {
1282 tp.spawnWg(&wg, resolveSpecialSymbolsWorker, .{ self, obj });
1273 resolveSpecialSymbolsWorker(self, obj);
12831274 }
12841275 }
12851276 if (diags.hasErrors()) return error.LinkFailure;
......@@ -1327,19 +1318,15 @@ pub fn dedupLiterals(self: *MachO) !void {
13271318 try object.resolveLiterals(&lp, self);
13281319 }
13291320
1330 const tp = self.base.comp.thread_pool;
1331 var wg: WaitGroup = .{};
13321321 {
1333 wg.reset();
1334 defer wg.wait();
13351322 if (self.getZigObject()) |zo| {
1336 tp.spawnWg(&wg, File.dedupLiterals, .{ zo.asFile(), lp, self });
1323 File.dedupLiterals(zo.asFile(), lp, self);
13371324 }
13381325 for (self.objects.items) |index| {
1339 tp.spawnWg(&wg, File.dedupLiterals, .{ self.getFile(index).?, lp, self });
1326 File.dedupLiterals(self.getFile(index).?, lp, self);
13401327 }
13411328 if (self.getInternalObject()) |object| {
1342 tp.spawnWg(&wg, File.dedupLiterals, .{ object.asFile(), lp, self });
1329 File.dedupLiterals(object.asFile(), lp, self);
13431330 }
13441331 }
13451332}
......@@ -1357,21 +1344,17 @@ fn checkDuplicates(self: *MachO) !void {
13571344 const tracy = trace(@src());
13581345 defer tracy.end();
13591346
1360 const tp = self.base.comp.thread_pool;
13611347 const diags = &self.base.comp.link_diags;
13621348
1363 var wg: WaitGroup = .{};
13641349 {
1365 wg.reset();
1366 defer wg.wait();
13671350 if (self.getZigObject()) |zo| {
1368 tp.spawnWg(&wg, checkDuplicatesWorker, .{ self, zo.asFile() });
1351 checkDuplicatesWorker(self, zo.asFile());
13691352 }
13701353 for (self.objects.items) |index| {
1371 tp.spawnWg(&wg, checkDuplicatesWorker, .{ self, self.getFile(index).? });
1354 checkDuplicatesWorker(self, self.getFile(index).?);
13721355 }
13731356 if (self.getInternalObject()) |obj| {
1374 tp.spawnWg(&wg, checkDuplicatesWorker, .{ self, obj.asFile() });
1357 checkDuplicatesWorker(self, obj.asFile());
13751358 }
13761359 }
13771360
......@@ -1428,23 +1411,17 @@ fn scanRelocs(self: *MachO) !void {
14281411 const tracy = trace(@src());
14291412 defer tracy.end();
14301413
1431 const tp = self.base.comp.thread_pool;
14321414 const diags = &self.base.comp.link_diags;
14331415
1434 var wg: WaitGroup = .{};
1435
14361416 {
1437 wg.reset();
1438 defer wg.wait();
1439
14401417 if (self.getZigObject()) |zo| {
1441 tp.spawnWg(&wg, scanRelocsWorker, .{ self, zo.asFile() });
1418 scanRelocsWorker(self, zo.asFile());
14421419 }
14431420 for (self.objects.items) |index| {
1444 tp.spawnWg(&wg, scanRelocsWorker, .{ self, self.getFile(index).? });
1421 scanRelocsWorker(self, self.getFile(index).?);
14451422 }
14461423 if (self.getInternalObject()) |obj| {
1447 tp.spawnWg(&wg, scanRelocsWorker, .{ self, obj.asFile() });
1424 scanRelocsWorker(self, obj.asFile());
14481425 }
14491426 }
14501427
......@@ -1888,38 +1865,34 @@ fn calcSectionSizes(self: *MachO) !void {
18881865 header.@"align" = 3;
18891866 }
18901867
1891 const tp = self.base.comp.thread_pool;
1892 var wg: WaitGroup = .{};
18931868 {
1894 wg.reset();
1895 defer wg.wait();
18961869 const slice = self.sections.slice();
18971870 for (slice.items(.header), slice.items(.atoms), 0..) |header, atoms, i| {
18981871 if (atoms.items.len == 0) continue;
18991872 if (self.requiresThunks() and header.isCode()) continue;
1900 tp.spawnWg(&wg, calcSectionSizeWorker, .{ self, @as(u8, @intCast(i)) });
1873 calcSectionSizeWorker(self, @as(u8, @intCast(i)));
19011874 }
19021875
19031876 if (self.requiresThunks()) {
19041877 for (slice.items(.header), slice.items(.atoms), 0..) |header, atoms, i| {
19051878 if (!header.isCode()) continue;
19061879 if (atoms.items.len == 0) continue;
1907 tp.spawnWg(&wg, createThunksWorker, .{ self, @as(u8, @intCast(i)) });
1880 createThunksWorker(self, @as(u8, @intCast(i)));
19081881 }
19091882 }
19101883
19111884 // At this point, we can also calculate most of the symtab and data-in-code linkedit section sizes
19121885 if (self.getZigObject()) |zo| {
1913 tp.spawnWg(&wg, File.calcSymtabSize, .{ zo.asFile(), self });
1886 File.calcSymtabSize(zo.asFile(), self);
19141887 }
19151888 for (self.objects.items) |index| {
1916 tp.spawnWg(&wg, File.calcSymtabSize, .{ self.getFile(index).?, self });
1889 File.calcSymtabSize(self.getFile(index).?, self);
19171890 }
19181891 for (self.dylibs.items) |index| {
1919 tp.spawnWg(&wg, File.calcSymtabSize, .{ self.getFile(index).?, self });
1892 File.calcSymtabSize(self.getFile(index).?, self);
19201893 }
19211894 if (self.getInternalObject()) |obj| {
1922 tp.spawnWg(&wg, File.calcSymtabSize, .{ obj.asFile(), self });
1895 File.calcSymtabSize(obj.asFile(), self);
19231896 }
19241897 }
19251898
......@@ -2403,23 +2376,18 @@ fn writeSectionsAndUpdateLinkeditSizes(self: *MachO) !void {
24032376 try self.strtab.resize(gpa, cmd.strsize);
24042377 self.strtab.items[0] = 0;
24052378
2406 const tp = self.base.comp.thread_pool;
2407 var wg: WaitGroup = .{};
24082379 {
2409 wg.reset();
2410 defer wg.wait();
2411
24122380 for (self.objects.items) |index| {
2413 tp.spawnWg(&wg, writeAtomsWorker, .{ self, self.getFile(index).? });
2381 writeAtomsWorker(self, self.getFile(index).?);
24142382 }
24152383 if (self.getZigObject()) |zo| {
2416 tp.spawnWg(&wg, writeAtomsWorker, .{ self, zo.asFile() });
2384 writeAtomsWorker(self, zo.asFile());
24172385 }
24182386 if (self.getInternalObject()) |obj| {
2419 tp.spawnWg(&wg, writeAtomsWorker, .{ self, obj.asFile() });
2387 writeAtomsWorker(self, obj.asFile());
24202388 }
24212389 for (self.thunks.items) |thunk| {
2422 tp.spawnWg(&wg, writeThunkWorker, .{ self, thunk });
2390 writeThunkWorker(self, thunk);
24232391 }
24242392
24252393 const slice = self.sections.slice();
......@@ -2434,34 +2402,34 @@ fn writeSectionsAndUpdateLinkeditSizes(self: *MachO) !void {
24342402 }) |maybe_sect_id| {
24352403 if (maybe_sect_id) |sect_id| {
24362404 const out = slice.items(.out)[sect_id].items;
2437 tp.spawnWg(&wg, writeSyntheticSectionWorker, .{ self, sect_id, out });
2405 writeSyntheticSectionWorker(self, sect_id, out);
24382406 }
24392407 }
24402408
24412409 if (self.la_symbol_ptr_sect_index) |_| {
2442 tp.spawnWg(&wg, updateLazyBindSizeWorker, .{self});
2410 updateLazyBindSizeWorker(self);
24432411 }
24442412
2445 tp.spawnWg(&wg, updateLinkeditSizeWorker, .{ self, .rebase });
2446 tp.spawnWg(&wg, updateLinkeditSizeWorker, .{ self, .bind });
2447 tp.spawnWg(&wg, updateLinkeditSizeWorker, .{ self, .weak_bind });
2448 tp.spawnWg(&wg, updateLinkeditSizeWorker, .{ self, .export_trie });
2449 tp.spawnWg(&wg, updateLinkeditSizeWorker, .{ self, .data_in_code });
2413 updateLinkeditSizeWorker(self, .rebase);
2414 updateLinkeditSizeWorker(self, .bind);
2415 updateLinkeditSizeWorker(self, .weak_bind);
2416 updateLinkeditSizeWorker(self, .export_trie);
2417 updateLinkeditSizeWorker(self, .data_in_code);
24502418
24512419 if (self.getZigObject()) |zo| {
2452 tp.spawnWg(&wg, File.writeSymtab, .{ zo.asFile(), self, self });
2420 File.writeSymtab(zo.asFile(), self, self);
24532421 }
24542422 for (self.objects.items) |index| {
2455 tp.spawnWg(&wg, File.writeSymtab, .{ self.getFile(index).?, self, self });
2423 File.writeSymtab(self.getFile(index).?, self, self);
24562424 }
24572425 for (self.dylibs.items) |index| {
2458 tp.spawnWg(&wg, File.writeSymtab, .{ self.getFile(index).?, self, self });
2426 File.writeSymtab(self.getFile(index).?, self, self);
24592427 }
24602428 if (self.getInternalObject()) |obj| {
2461 tp.spawnWg(&wg, File.writeSymtab, .{ obj.asFile(), self, self });
2429 File.writeSymtab(obj.asFile(), self, self);
24622430 }
24632431 if (self.requiresThunks()) for (self.thunks.items) |th| {
2464 tp.spawnWg(&wg, Thunk.writeSymtab, .{ th, self, self });
2432 Thunk.writeSymtab(th, self, self);
24652433 };
24662434 }
24672435
......@@ -5370,7 +5338,6 @@ const Thunk = @import("MachO/Thunk.zig");
53705338const TlvPtrSection = synthetic.TlvPtrSection;
53715339const Value = @import("../Value.zig");
53725340const UnwindInfo = @import("MachO/UnwindInfo.zig");
5373const WaitGroup = std.Thread.WaitGroup;
53745341const WeakBind = bind.WeakBind;
53755342const ZigObject = @import("MachO/ZigObject.zig");
53765343const dev = @import("../dev.zig");
src/link/MachO/relocatable.zig+13-24
......@@ -290,38 +290,33 @@ fn calcSectionSizes(macho_file: *MachO) !void {
290290 zo.calcNumRelocs(macho_file);
291291 }
292292
293 const tp = macho_file.base.comp.thread_pool;
294 var wg: WaitGroup = .{};
295293 {
296 wg.reset();
297 defer wg.wait();
298
299294 for (macho_file.sections.items(.atoms), 0..) |atoms, i| {
300295 if (atoms.items.len == 0) continue;
301 tp.spawnWg(&wg, calcSectionSizeWorker, .{ macho_file, @as(u8, @intCast(i)) });
296 calcSectionSizeWorker(macho_file, @as(u8, @intCast(i)));
302297 }
303298
304299 if (macho_file.eh_frame_sect_index) |_| {
305 tp.spawnWg(&wg, calcEhFrameSizeWorker, .{macho_file});
300 calcEhFrameSizeWorker(macho_file);
306301 }
307302
308303 if (macho_file.unwind_info_sect_index) |_| {
309304 for (macho_file.objects.items) |index| {
310 tp.spawnWg(&wg, Object.calcCompactUnwindSizeRelocatable, .{
305 Object.calcCompactUnwindSizeRelocatable(
311306 macho_file.getFile(index).?.object,
312307 macho_file,
313 });
308 );
314309 }
315310 }
316311
317312 for (macho_file.objects.items) |index| {
318 tp.spawnWg(&wg, File.calcSymtabSize, .{ macho_file.getFile(index).?, macho_file });
313 File.calcSymtabSize(macho_file.getFile(index).?, macho_file);
319314 }
320315 if (macho_file.getZigObject()) |zo| {
321 tp.spawnWg(&wg, File.calcSymtabSize, .{ zo.asFile(), macho_file });
316 File.calcSymtabSize(zo.asFile(), macho_file);
322317 }
323318
324 tp.spawnWg(&wg, MachO.updateLinkeditSizeWorker, .{ macho_file, .data_in_code });
319 MachO.updateLinkeditSizeWorker(macho_file, .data_in_code);
325320 }
326321
327322 if (macho_file.unwind_info_sect_index) |_| {
......@@ -601,29 +596,24 @@ fn writeSections(macho_file: *MachO) !void {
601596 try macho_file.strtab.resize(gpa, cmd.strsize);
602597 macho_file.strtab.items[0] = 0;
603598
604 const tp = macho_file.base.comp.thread_pool;
605 var wg: WaitGroup = .{};
606599 {
607 wg.reset();
608 defer wg.wait();
609
610600 for (macho_file.objects.items) |index| {
611 tp.spawnWg(&wg, writeAtomsWorker, .{ macho_file, macho_file.getFile(index).? });
612 tp.spawnWg(&wg, File.writeSymtab, .{ macho_file.getFile(index).?, macho_file, macho_file });
601 writeAtomsWorker(macho_file, macho_file.getFile(index).?);
602 File.writeSymtab(macho_file.getFile(index).?, macho_file, macho_file);
613603 }
614604
615605 if (macho_file.getZigObject()) |zo| {
616 tp.spawnWg(&wg, writeAtomsWorker, .{ macho_file, zo.asFile() });
617 tp.spawnWg(&wg, File.writeSymtab, .{ zo.asFile(), macho_file, macho_file });
606 writeAtomsWorker(macho_file, zo.asFile());
607 File.writeSymtab(zo.asFile(), macho_file, macho_file);
618608 }
619609
620610 if (macho_file.eh_frame_sect_index) |_| {
621 tp.spawnWg(&wg, writeEhFrameWorker, .{macho_file});
611 writeEhFrameWorker(macho_file);
622612 }
623613
624614 if (macho_file.unwind_info_sect_index) |_| {
625615 for (macho_file.objects.items) |index| {
626 tp.spawnWg(&wg, writeCompactUnwindWorker, .{ macho_file, macho_file.getFile(index).?.object });
616 writeCompactUnwindWorker(macho_file, macho_file.getFile(index).?.object);
627617 }
628618 }
629619 }
......@@ -777,4 +767,3 @@ const File = @import("file.zig").File;
777767const MachO = @import("../MachO.zig");
778768const Object = @import("Object.zig");
779769const Symbol = @import("Symbol.zig");
780const WaitGroup = std.Thread.WaitGroup;