| ... | @@ -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 | } |
| 148 | | 148 | |
| 149 | fn flushTaskQueue(tid: usize, q: *Queue, comp: *Compilation) void { | 149 | fn 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(); | | |
| 152 | | 151 | |
| 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); |