1 //@compile-flags: -Zmiri-ignore-leaks
3 // https://plv.mpi-sws.org/scfix/paper.pdf
4 // 2.2 Second Problem: SC Fences are Too Weak
5 // This test should pass under the C++20 model Rust is using.
6 // Unfortunately, Miri's weak memory emulation only follows the C++11 model
7 // as we don't know how to correctly emulate C++20's revised SC semantics,
8 // so we have to stick to C++11 emulation from existing research.
10 use std::sync::atomic::Ordering::*;
11 use std::sync::atomic::{fence, AtomicUsize};
12 use std::thread::spawn;
14 // Spins until it reads the given value
15 fn reads_value(loc: &AtomicUsize, val: usize) -> usize {
16 while loc.load(Relaxed) != val {
17 std::hint::spin_loop();
22 // We can't create static items because we need to run each test
24 fn static_atomic(val: usize) -> &'static AtomicUsize {
25 let ret = Box::leak(Box::new(AtomicUsize::new(val)));
26 // A workaround to put the initialization value in the store buffer.
27 // See https://github.com/rust-lang/miri/issues/2164
32 fn test_cpp20_rwc_syncs() {
38 {{{ x.store(1,mo_relaxed);
39 ||| { r1=x.load(mo_relaxed).readsvalue(1);
41 r2=y.load(mo_relaxed); }
42 ||| { y.store(1,mo_relaxed);
44 r3=x.load(mo_relaxed); }
49 let x = static_atomic(0);
50 let y = static_atomic(0);
52 let j1 = spawn(move || {
56 let j2 = spawn(move || {
62 let j3 = spawn(move || {
69 let b = j2.join().unwrap();
70 let c = j3.join().unwrap();
72 // We cannot write assert_ne!() since ui_test's fail
73 // tests expect exit status 1, whereas panics produce 101.
74 // Our ui_test does not yet support overriding failure status codes.
76 // This *should* be unreachable, but Miri will reach it.
78 std::hint::unreachable_unchecked(); //~ERROR: unreachable
85 test_cpp20_rwc_syncs();