authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-23 14:46:46-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-23 16:27:39-07:00
log504ad56815c3deb38319ac7989dd6c50c559b780
tree29e01c26936f36e8f563a295110f5455f7af8f41
parentba71079837a071b53cab289d78e5bacb4925fd25

link.flushTaskQueue: move safety lock

The safety lock needs to happen after check()

2 files changed, 23 insertions(+), 8 deletions(-)

src/ThreadSafeQueue.zig+5-4
...@@ -52,12 +52,13 @@ pub fn ThreadSafeQueue(comptime T: type) type {...@@ -52,12 +52,13 @@ pub fn ThreadSafeQueue(comptime T: type) type {
52 self.mutex.lock();52 self.mutex.lock();
53 defer self.mutex.unlock();53 defer self.mutex.unlock();
54 try self.shared.appendSlice(gpa, items);54 try self.shared.appendSlice(gpa, items);
55 const was_waiting = switch (self.state) {55 return switch (self.state) {
56 .run => false,56 .run => false,
57 .wait => true,57 .wait => {
58 self.state = .run;
59 return true;
60 },
58 };61 };
59 self.state = .run;
60 return was_waiting;
61 }62 }
6263
63 /// Safe only to call exactly once when initially starting the worker.64 /// Safe only to call exactly once when initially starting the worker.
src/link.zig+18-4
...@@ -1365,11 +1365,11 @@ pub const File = struct {...@@ -1365,11 +1365,11 @@ pub const File = struct {
1365/// from the rest of compilation. All tasks performed here are1365/// from the rest of compilation. All tasks performed here are
1366/// single-threaded with respect to one another.1366/// single-threaded with respect to one another.
1367pub fn flushTaskQueue(tid: usize, comp: *Compilation) void {1367pub fn flushTaskQueue(tid: usize, comp: *Compilation) void {
1368 comp.link_task_queue_safety.lock();1368 // As soon as check() is called, another `flushTaskQueue` call could occur,
1369 defer comp.link_task_queue_safety.unlock();1369 // so the safety lock must go after the check.
1370 const prog_node = comp.work_queue_progress_node.start("Parse Linker Inputs", 0);
1371 defer prog_node.end();
1372 while (comp.link_task_queue.check()) |tasks| {1370 while (comp.link_task_queue.check()) |tasks| {
1371 comp.link_task_queue_safety.lock();
1372 defer comp.link_task_queue_safety.unlock();
1373 for (tasks) |task| doTask(comp, tid, task);1373 for (tasks) |task| doTask(comp, tid, task);
1374 }1374 }
1375}1375}
...@@ -1412,6 +1412,8 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {...@@ -1412,6 +1412,8 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {
1412 const diags = &comp.link_diags;1412 const diags = &comp.link_diags;
1413 switch (task) {1413 switch (task) {
1414 .load_explicitly_provided => if (comp.bin_file) |base| {1414 .load_explicitly_provided => if (comp.bin_file) |base| {
1415 const prog_node = comp.work_queue_progress_node.start("Parse Linker Inputs", comp.link_inputs.len);
1416 defer prog_node.end();
1415 for (comp.link_inputs) |input| {1417 for (comp.link_inputs) |input| {
1416 base.loadInput(input) catch |err| switch (err) {1418 base.loadInput(input) catch |err| switch (err) {
1417 error.LinkFailure => return, // error reported via diags1419 error.LinkFailure => return, // error reported via diags
...@@ -1423,9 +1425,13 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {...@@ -1423,9 +1425,13 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {
1423 .dso_exact => diags.addError("failed to handle dso_exact: {s}", .{@errorName(e)}),1425 .dso_exact => diags.addError("failed to handle dso_exact: {s}", .{@errorName(e)}),
1424 },1426 },
1425 };1427 };
1428 prog_node.completeOne();
1426 }1429 }
1427 },1430 },
1428 .load_host_libc => if (comp.bin_file) |base| {1431 .load_host_libc => if (comp.bin_file) |base| {
1432 const prog_node = comp.work_queue_progress_node.start("Linker Parse Host libc", 0);
1433 defer prog_node.end();
1434
1429 const target = comp.root_mod.resolved_target.result;1435 const target = comp.root_mod.resolved_target.result;
1430 const flags = target_util.libcFullLinkFlags(target);1436 const flags = target_util.libcFullLinkFlags(target);
1431 const crt_dir = comp.libc_installation.?.crt_dir.?;1437 const crt_dir = comp.libc_installation.?.crt_dir.?;
...@@ -1482,18 +1488,24 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {...@@ -1482,18 +1488,24 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {
1482 }1488 }
1483 },1489 },
1484 .load_object => |path| if (comp.bin_file) |base| {1490 .load_object => |path| if (comp.bin_file) |base| {
1491 const prog_node = comp.work_queue_progress_node.start("Linker Parse Object", 0);
1492 defer prog_node.end();
1485 base.openLoadObject(path) catch |err| switch (err) {1493 base.openLoadObject(path) catch |err| switch (err) {
1486 error.LinkFailure => return, // error reported via diags1494 error.LinkFailure => return, // error reported via diags
1487 else => |e| diags.addParseError(path, "failed to parse object: {s}", .{@errorName(e)}),1495 else => |e| diags.addParseError(path, "failed to parse object: {s}", .{@errorName(e)}),
1488 };1496 };
1489 },1497 },
1490 .load_archive => |path| if (comp.bin_file) |base| {1498 .load_archive => |path| if (comp.bin_file) |base| {
1499 const prog_node = comp.work_queue_progress_node.start("Linker Parse Archive", 0);
1500 defer prog_node.end();
1491 base.openLoadArchive(path, null) catch |err| switch (err) {1501 base.openLoadArchive(path, null) catch |err| switch (err) {
1492 error.LinkFailure => return, // error reported via link_diags1502 error.LinkFailure => return, // error reported via link_diags
1493 else => |e| diags.addParseError(path, "failed to parse archive: {s}", .{@errorName(e)}),1503 else => |e| diags.addParseError(path, "failed to parse archive: {s}", .{@errorName(e)}),
1494 };1504 };
1495 },1505 },
1496 .load_dso => |path| if (comp.bin_file) |base| {1506 .load_dso => |path| if (comp.bin_file) |base| {
1507 const prog_node = comp.work_queue_progress_node.start("Linker Parse Shared Library", 0);
1508 defer prog_node.end();
1497 base.openLoadDso(path, .{1509 base.openLoadDso(path, .{
1498 .preferred_mode = .dynamic,1510 .preferred_mode = .dynamic,
1499 .search_strategy = .paths_first,1511 .search_strategy = .paths_first,
...@@ -1503,6 +1515,8 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {...@@ -1503,6 +1515,8 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {
1503 };1515 };
1504 },1516 },
1505 .load_input => |input| if (comp.bin_file) |base| {1517 .load_input => |input| if (comp.bin_file) |base| {
1518 const prog_node = comp.work_queue_progress_node.start("Linker Parse Input", 0);
1519 defer prog_node.end();
1506 base.loadInput(input) catch |err| switch (err) {1520 base.loadInput(input) catch |err| switch (err) {
1507 error.LinkFailure => return, // error reported via link_diags1521 error.LinkFailure => return, // error reported via link_diags
1508 else => |e| {1522 else => |e| {