Skip to content

Commit 2ce0384

Browse files
committed
Move cpp20_rwc_syncs into compile-fail
1 parent 20db949 commit 2ce0384

File tree

2 files changed

+86
-57
lines changed

2 files changed

+86
-57
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// ignore-windows: Concurrency on Windows is not supported yet.
2+
// compile-flags: -Zmiri-ignore-leaks
3+
4+
// https://plv.mpi-sws.org/scfix/paper.pdf
5+
// 2.2 Second Problem: SC Fences are Too Weak
6+
// This test should pass under the C++20 model Rust is using.
7+
// Unfortunately, Miri's weak memory emulation only follows C++11 model
8+
// as we don't know how to correctly emulate C++20's revised SC semantics,
9+
// so we have to stick to C++11 emulation from exiting research.
10+
11+
use std::sync::atomic::Ordering::*;
12+
use std::thread::{spawn, yield_now};
13+
use std::sync::atomic::{fence, AtomicUsize};
14+
15+
// Spins and yields until until it reads value
16+
fn reads_value(loc: &AtomicUsize, val: usize) -> usize {
17+
while loc.load(Relaxed) != val {
18+
yield_now();
19+
}
20+
val
21+
}
22+
23+
// We can't create static items because we need to run each test
24+
// multiple tests
25+
fn static_atomic(val: usize) -> &'static AtomicUsize {
26+
let ret = Box::leak(Box::new(AtomicUsize::new(val)));
27+
// A workaround to put the initialisation value in the store buffer
28+
ret.store(val, Relaxed);
29+
ret
30+
}
31+
32+
fn test_cpp20_rwc_syncs() {
33+
/*
34+
int main() {
35+
atomic_int x = 0;
36+
atomic_int y = 0;
37+
38+
{{{ x.store(1,mo_relaxed);
39+
||| { r1=x.load(mo_relaxed).readsvalue(1);
40+
fence(mo_seq_cst);
41+
r2=y.load(mo_relaxed); }
42+
||| { y.store(1,mo_relaxed);
43+
fence(mo_seq_cst);
44+
r3=x.load(mo_relaxed); }
45+
}}}
46+
return 0;
47+
}
48+
*/
49+
let x = static_atomic(0);
50+
let y = static_atomic(0);
51+
52+
let j1 = spawn(move || {
53+
x.store(1, Relaxed);
54+
});
55+
56+
let j2 = spawn(move || {
57+
reads_value(&x, 1);
58+
fence(SeqCst);
59+
y.load(Relaxed)
60+
});
61+
62+
let j3 = spawn(move || {
63+
y.store(1, Relaxed);
64+
fence(SeqCst);
65+
x.load(Relaxed)
66+
});
67+
68+
j1.join().unwrap();
69+
let b = j2.join().unwrap();
70+
let c = j3.join().unwrap();
71+
72+
if (b, c) == (0, 0) {
73+
// FIXME: the standalone compiletest-rs needs to support
74+
// failure-status header to allow us to write assert_ne!((b, c), (0, 0))
75+
// https://rustc-dev-guide.rust-lang.org/tests/headers.html#miscellaneous-headers
76+
// because panic exits with 101 but compile-rs expects 1
77+
let _ = unsafe { std::mem::MaybeUninit::<*const u32>::uninit().assume_init() }; //~ ERROR uninitialized
78+
}
79+
}
80+
81+
pub fn main() {
82+
for _ in 0..500 {
83+
test_cpp20_rwc_syncs();
84+
}
85+
}

tests/run-pass/concurrency/weak_memory.rs

+1-57
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#![feature(atomic_from_mut)]
3232

3333
use std::sync::atomic::Ordering::*;
34-
use std::sync::atomic::{fence, AtomicU16, AtomicU32, AtomicUsize};
34+
use std::sync::atomic::{AtomicU16, AtomicU32, AtomicUsize};
3535
use std::thread::{spawn, yield_now};
3636

3737
#[derive(Copy, Clone)]
@@ -57,13 +57,6 @@ fn acquires_value(loc: &AtomicUsize, val: usize) -> usize {
5757
val
5858
}
5959

60-
fn reads_value(loc: &AtomicUsize, val: usize) -> usize {
61-
while loc.load(Relaxed) != val {
62-
yield_now();
63-
}
64-
val
65-
}
66-
6760
fn test_corr() {
6861
let x = static_atomic(0);
6962
let y = static_atomic(0);
@@ -242,54 +235,6 @@ fn test_sc_store_buffering() {
242235
assert_ne!((a, b), (0, 0));
243236
}
244237

245-
// 2.2 Second Problem: SC Fences are Too Weak
246-
// This test should pass under the C++20 model Rust is using.
247-
// Unfortunately, Miri's weak memory emulation only follows C++11 model
248-
// as we don't know how to correctly emulate C++20's revised SC semantics
249-
#[allow(dead_code)]
250-
fn test_cpp20_rwc_syncs() {
251-
/*
252-
int main() {
253-
atomic_int x = 0;
254-
atomic_int y = 0;
255-
256-
{{{ x.store(1,mo_relaxed);
257-
||| { r1=x.load(mo_relaxed).readsvalue(1);
258-
fence(mo_seq_cst);
259-
r2=y.load(mo_relaxed); }
260-
||| { y.store(1,mo_relaxed);
261-
fence(mo_seq_cst);
262-
r3=x.load(mo_relaxed); }
263-
}}}
264-
return 0;
265-
}
266-
*/
267-
let x = static_atomic(0);
268-
let y = static_atomic(0);
269-
270-
let j1 = spawn(move || {
271-
x.store(1, Relaxed);
272-
});
273-
274-
let j2 = spawn(move || {
275-
reads_value(&x, 1);
276-
fence(SeqCst);
277-
y.load(Relaxed)
278-
});
279-
280-
let j3 = spawn(move || {
281-
y.store(1, Relaxed);
282-
fence(SeqCst);
283-
x.load(Relaxed)
284-
});
285-
286-
j1.join().unwrap();
287-
let b = j2.join().unwrap();
288-
let c = j3.join().unwrap();
289-
290-
assert_ne!((b, c), (0, 0));
291-
}
292-
293238
pub fn main() {
294239
test_imperfectly_overlapping_access();
295240
// TODO: does this make chances of spurious success
@@ -303,6 +248,5 @@ pub fn main() {
303248
test_wrc();
304249
test_corr();
305250
test_sc_store_buffering();
306-
// test_cpp20_rwc_syncs();
307251
}
308252
}

0 commit comments

Comments
 (0)