`fn name` read `while p < fn and ...` as a reference to a function called `and`, which broke
tools/ludic-cli/glgen.ludic and so the dev tool's own build. A reference now needs the name on
the same line and not one of and / or / not / in / is. The threads example checks `fn` as a
local before `and`. Reseeded; bootstrap-cfree reproduces the seed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- `fn name` names a top-level function as a value (E_FNREF, lowers to @fn_<name>); the worker
entry point for Job.parallel_for, which checks it takes (int, pointer-like) and returns void.
- runtime/native/threads.ll (pthreads) and threads_win.ll (Win32 SRWLOCK/CONDITION_VARIABLE): a
pool of one worker per core but one, parked between batches; every thread claims chunks by
compare-and-swap. Linked only into programs that use Job/Promise/Sync, by `ludicc -o`,
`ludic build` and the test suite's build helper.
- Sync.* is real: native mutexes, atomics as cmpxchg retry loops (neither clang takes atomicrw,
the PC's rejects seq_consistent), mutex-guarded channels, Sync.cpu_count from the OS.
- spawn/despawn on a pool thread stop the program with a located panic.
- examples/library/threads.ludic and its test; docs for fn, Job.parallel_for, Job.is_worker.
- Reseeded (bootstrap-cfree: out.ll == seed.ll). 141/141 on macOS; jobs, threads and the guard
pass on Windows from the reseeded Windows seed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>