summaryrefslogtreecommitdiff
path: root/src/save/._main.c
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2026-10-14 11:44:16 -0700
committerScott Gasch <[email protected]>2026-10-14 11:44:16 -0700
commit91f01c607338eabb10ae1f8c144be55071d174a5 (patch)
tree89d14a9f6f6533152cad409095487f556ba3087f /src/save/._main.c
parentb3d4d0781faa189c74b05fec96814e3f30e449f9 (diff)
Fix WouldGiveCheck race in StartParallelSearch's move snapshot
StartParallelSearch's snapshot loop (split.c, the move list handed to helper threads at a split) skipped recomputing WouldGiveCheck for v == uMoveNum on the assumption that Search()'s own loop had already computed it moments earlier when it originally selected that move. That assumption only holds if re-running SelectBestWithHistory(ctx, uMoveNum) is a no-op. It isn't: the loop calls SelectBestWithHistory for every v including uMoveNum, which rescans [v, uEnd) using g_HistoryCounters/g_ContinuationHistory -- process-global state written by every other searcher thread with no lock. Between Search()'s original selection and this second one a few lines later, another thread can mutate those tables enough to change which move wins the scan, swapping a *different* move into slot uMoveNum than the one originally selected -- one whose check bit was never computed, inheriting a stale/garbage value instead. That move, with its wrong check bit, got handed to a helper thread via g_SplitInfo[u].mvf[], tripping HelpSearch's own IS_CHECKING_MOVE/InCheck invariant (visible as "Assertion failure in split.c, line 1143" under DEBUG) or, in a release build, corrupting move generation further down the line (observed as "Typhoon PANIC 0x4 ... Location: generate.c" via InvalidGenerator, when a move wrongly believed non-checking reached a dispatch table expecting the opposite invariant). Confirmed via a DEBUG=1 build at --cpus 4: reliably reproduced within the first ~15 positions of ecm_confident_quick at sd10 before this fix (same assert, different positions across repeated runs -- consistent with a real race, not a deterministic bug), and ran 43 consecutive positions with zero assertion failures after. Also confirmed pre-existing at HEAD~2 (3d54c2c, before this session's prior two commits), so unrelated to the search-unification work in progress. Fix: always recompute WouldGiveCheck for every move in this loop, including uMoveNum. This loop runs once per split (not once per move tried), so the extra call is split overhead, not a per-node cost. Co-Authored-By: Claude Sonnet 5 <[email protected]>
Diffstat (limited to 'src/save/._main.c')
0 files changed, 0 insertions, 0 deletions