Disable Miri weak memory emulation for deque tests #829
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
(Don't merge yet) Once rust-lang/miri#1963 is merged into Miri to support weak memory emulation,
crossbeam-deque/tests/injector.rs::mpmc()
test will hang forever on Miri CI. This PR disables weak memory emulation for deque tests to prevent this. This is why we need to do this:Miri README says
This is because Miri's scheduler is not pre-emptive. It runs the current thread until it terminates or
yield_now()
is called explicitly.The test has a spin loop without yielding. When run natively it relies on the OS to have a pre-emptive scheduler:
crossbeam/crossbeam-deque/tests/injector.rs
Lines 100 to 105 in 6f52bea
This currently passes due to the fact that all the pushing threads run and terminate before any stealing threads gets to run.
.steal()
never returns anything other than success.However, if a pushing thread's
push()
call causes it to yield, then Miri could end up in a stealing thread. If this happens multiple times then Miri could land in a stealing spin loop with nothing in the queue since there aren't enough successful pushes. The test ends up hanging.push()
could yield the thread by a compare exchange failure:crossbeam/crossbeam-deque/src/deque.rs
Lines 1301 to 1330 in 6f52bea
Without weak memory behaviour or thread interleaving, the previously loaded
tail
value is always the most recent one which is what the compare exchange will observe, so the only way it could fail is spuriously. This is why currently we turned off spurious failure, and the thread never yields:crossbeam/ci/miri.sh
Line 27 in 6f52bea
(yes,
-Zmiri-compare-exchange-weak-failure-rate=1.0
implies that the exchange always fails. However it actually means never failing because a comparison in Miri was written backwards. This will be fixed rust-lang/miri#2105)However, once weak memory is added,
tail
doesn't have to be the most recent value, meaning the compare exchange could fail and the pushing thread yields, landing us in a stealing spin loop.crossbeam/crossbeam-deque/src/deque.rs
Line 1276 in 6f52bea
The best way to solve this for Miri to have a pre-emptive scheduler. But to keep the CI green this workaround is fine.