authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-06-11 02:25:55+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-06-12 17:51:30+01:00
logff89a98c50dbf826564657e7f98cc56194add163
tree8ea51fc317975bb3fda9e2d014458e5a7e0a0036
parent1b27369acbb2009935d49c6906363e8fa425313a
signaturelock-open Commit is signed but in an unrecognized format.

link.Queue: release safety lock before releasing mutex after stopping


1 files changed, 4 insertions(+), 2 deletions(-)

src/link/Queue.zig+4-2
...@@ -147,8 +147,7 @@ pub fn enqueueZcu(q: *Queue, comp: *Compilation, task: ZcuTask) Allocator.Error!...@@ -147,8 +147,7 @@ pub fn enqueueZcu(q: *Queue, comp: *Compilation, task: ZcuTask) Allocator.Error!
147}147}
148148
149fn flushTaskQueue(tid: usize, q: *Queue, comp: *Compilation) void {149fn flushTaskQueue(tid: usize, q: *Queue, comp: *Compilation) void {
150 q.flush_safety.lock();150 q.flush_safety.lock(); // every `return` site should unlock this before unlocking `q.mutex`
151 defer q.flush_safety.unlock();
152151
153 if (std.debug.runtime_safety) {152 if (std.debug.runtime_safety) {
154 q.mutex.lock();153 q.mutex.lock();
...@@ -167,6 +166,7 @@ fn flushTaskQueue(tid: usize, q: *Queue, comp: *Compilation) void {...@@ -167,6 +166,7 @@ fn flushTaskQueue(tid: usize, q: *Queue, comp: *Compilation) void {
167 } else {166 } else {
168 // We're expecting more prelink tasks so can't move on to ZCU tasks.167 // We're expecting more prelink tasks so can't move on to ZCU tasks.
169 q.state = .finished;168 q.state = .finished;
169 q.flush_safety.unlock();
170 return;170 return;
171 }171 }
172 }172 }
...@@ -200,6 +200,7 @@ fn flushTaskQueue(tid: usize, q: *Queue, comp: *Compilation) void {...@@ -200,6 +200,7 @@ fn flushTaskQueue(tid: usize, q: *Queue, comp: *Compilation) void {
200 if (q.wip_zcu.items.len == 0) {200 if (q.wip_zcu.items.len == 0) {
201 // We've exhausted all available tasks.201 // We've exhausted all available tasks.
202 q.state = .finished;202 q.state = .finished;
203 q.flush_safety.unlock();
203 return;204 return;
204 }205 }
205 }206 }
...@@ -215,6 +216,7 @@ fn flushTaskQueue(tid: usize, q: *Queue, comp: *Compilation) void {...@@ -215,6 +216,7 @@ fn flushTaskQueue(tid: usize, q: *Queue, comp: *Compilation) void {
215 if (status_ptr.load(.monotonic) != .pending) break :pending;216 if (status_ptr.load(.monotonic) != .pending) break :pending;
216 // We will stop for now, and get restarted once this MIR is ready.217 // We will stop for now, and get restarted once this MIR is ready.
217 q.state = .{ .wait_for_mir = task.link_func.mir };218 q.state = .{ .wait_for_mir = task.link_func.mir };
219 q.flush_safety.unlock();
218 return;220 return;
219 }221 }
220 link.doZcuTask(comp, tid, task);222 link.doZcuTask(comp, tid, task);