Filed during the landing sweep after #673 merged. This is a question about a control, not a reported failure — I have not measured it either way, and saying so is the point.
The situation
Two changes landed hours apart and interact:
Both are now on master:
$ grep -c PendingQueue include/morph/core/strand.hpp
2
$ grep -n TEST_CASE tests/test_strand_race.cpp
44: … never runs two tasks for one key concurrently under contention
167: … keeps one strand per key when a post races the drain
The gap
#673's evidence that its new case detects the race is a mutation result:
0 pass / 10 fail against the two-step-drain mutant under clang-tsan, 0/15 without a sanitizer, unchanged at 4 and 2 CPUs — against 10/10 passes for the old case on the same mutant binary.
That was measured against the old strand, whose queue was a std::deque reconstructed on every dispatch. PendingQueue changes the allocation and drain shape of exactly the code path the test provokes.
What has been verified since: #673 was rebased onto post-#671 master and its CI passed. That establishes the test still passes. It does not establish that it still fails when it should — and those are different properties. A green run cannot distinguish "the test works" from "the test no longer provokes the window".
This is #668's own defect one turn later: #668 existed because the original case passed 10/10 against the mutant while looking like a regression test.
Verification status: not measured, in either direction
I have run nothing. What I have is the structural fact that the mutation predates the implementation it now guards, plus the reasoning above. I am not claiming the test is broken — I am claiming nobody knows.
What would resolve it
Restore the two-step drain in the current scheduleNext, i.e. mutate PendingQueue's drain rather than the old deque's, and run [race] under the clang-tsan preset. Expected: the new case fails, the old one passes. Either outcome is worth recording:
Confirm instrumentation before believing a green run — #675 is open about check_sanitizer_instrumentation.sh refusing single-target trees, so a symbol count may be the practical route.
What would change the verdict
Close as invalid if #673's lane did re-run the mutation against PendingQueue and simply did not say so — its hand-back reports the mutation table without naming which strand it ran against, and the branch was rebased mid-flight, so this is possible. A comment from that work, or a rerun, settles it.
Related
🤖 Generated with Claude Code
https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW
Filed during the landing sweep after #673 merged. This is a question about a control, not a reported failure — I have not measured it either way, and saying so is the point.
The situation
Two changes landed hours apart and interact:
735cc2e9) replacedStrand'sstd::dequewithPendingQueue, which holds the head task inline and builds a deque only on overflow.95aa5686) addedtests/test_strand_race.cpp's second case, "StrandExecutor keeps one strand per key when a post races the drain", whose whole purpose is to detect the two-step drain-and-erase race that the pre-existing case could not.Both are now on master:
The gap
#673's evidence that its new case detects the race is a mutation result:
That was measured against the old strand, whose queue was a
std::dequereconstructed on every dispatch.PendingQueuechanges the allocation and drain shape of exactly the code path the test provokes.What has been verified since: #673 was rebased onto post-#671 master and its CI passed. That establishes the test still passes. It does not establish that it still fails when it should — and those are different properties. A green run cannot distinguish "the test works" from "the test no longer provokes the window".
This is #668's own defect one turn later: #668 existed because the original case passed 10/10 against the mutant while looking like a regression test.
Verification status: not measured, in either direction
I have run nothing. What I have is the structural fact that the mutation predates the implementation it now guards, plus the reasoning above. I am not claiming the test is broken — I am claiming nobody knows.
What would resolve it
Restore the two-step drain in the current
scheduleNext, i.e. mutatePendingQueue's drain rather than the old deque's, and run[race]under theclang-tsanpreset. Expected: the new case fails, the old one passes. Either outcome is worth recording:Confirm instrumentation before believing a green run — #675 is open about
check_sanitizer_instrumentation.shrefusing single-target trees, so a symbol count may be the practical route.What would change the verdict
Close as
invalidif #673's lane did re-run the mutation againstPendingQueueand simply did not say so — its hand-back reports the mutation table without naming which strand it ran against, and the branch was rebased mid-flight, so this is possible. A comment from that work, or a rerun, settles it.Related
PendingQueue.PendingQueue.🤖 Generated with Claude Code
https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW