feat(compiler): a Job.parallel_for worker may read a state but not change one

Every pool thread runs the worker at once with the same states, so a mut state in a worker was a
race nothing reported. check_worker_ref refuses a worker whose leading states include a mut one;
threads.ludic's total moves into the words the worker is handed, under the mutex. The seeds are
regenerated (ludic-dev reseed). ludic-dev test 305 passed, selfhost-test 33 passed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-27 22:04:59 +03:00
parent 7ceefa8c50
commit 7834b26ef8
6 changed files with 13354 additions and 13188 deletions

View file

@ -185,4 +185,11 @@ function check_worker_ref(e: Node) -> void {
var ok = len(d.kids) == s + 2 and llty(d.ty) == "void"
if ok { ok = llty(d.kids[s].ty) == "i32" and llty(d.kids[s + 1].ty) == "ptr" }
if not ok { perr(`fn {e.s}: a worker function takes (i: int, ctx: pointer) and returns nothing`) }
# every thread runs it at once: a state it is handed is read by all of them, so none may change one
var k = 0
while k < s {
let p = d.kids[k]
if p.uns == 1 { perr(`fn {e.s}: a worker runs on every core at once, so it may read {p.ty} but not change it ({p.s}: mut {p.ty}); write results into ctx, shared counts through Sync.add`) }
k += 1
}
}