1
- //@compile-flags: -Zmiri-ignore-leaks -Zmiri-disable-stacked-borrows -Zmiri-provenance-gc=10000
1
+ //@compile-flags: -Zmiri-ignore-leaks -Zmiri-disable-stacked-borrows -Zmiri-disable-validation -Zmiri- provenance-gc=10000
2
2
// This test's runtime explodes if the GC interval is set to 1 (which we do in CI), so we
3
3
// override it internally back to the default frequency.
4
4
@@ -34,14 +34,10 @@ unsafe impl<T> Sync for EvilSend<T> {}
34
34
// We can't create static items because we need to run each test
35
35
// multiple times
36
36
fn static_atomic ( val : i32 ) -> & ' static AtomicI32 {
37
- let ret = Box :: leak ( Box :: new ( AtomicI32 :: new ( val) ) ) ;
38
- ret. store ( val, Relaxed ) ; // work around https://github.com/rust-lang/miri/issues/2164
39
- ret
37
+ Box :: leak ( Box :: new ( AtomicI32 :: new ( val) ) )
40
38
}
41
39
fn static_atomic_bool ( val : bool ) -> & ' static AtomicBool {
42
- let ret = Box :: leak ( Box :: new ( AtomicBool :: new ( val) ) ) ;
43
- ret. store ( val, Relaxed ) ; // work around https://github.com/rust-lang/miri/issues/2164
44
- ret
40
+ Box :: leak ( Box :: new ( AtomicBool :: new ( val) ) )
45
41
}
46
42
47
43
// Spins until it acquires a pre-determined value.
@@ -365,6 +361,45 @@ fn test_cpp20_rwc_syncs() {
365
361
assert ! ( ( b, c) != ( 0 , 0 ) ) ;
366
362
}
367
363
364
+ /// This checks that the *last* thing the SC fence does is act like a release fence.
365
+ /// See <https://github.com/rust-lang/miri/pull/4057#issuecomment-2522296601>.
366
+ fn test_sc_fence_release ( ) {
367
+ let x = static_atomic ( 0 ) ;
368
+ let y = static_atomic ( 0 ) ;
369
+ let z = static_atomic ( 0 ) ;
370
+ let k = static_atomic ( 0 ) ;
371
+
372
+ let j1 = spawn ( move || {
373
+ x. store ( 1 , Relaxed ) ;
374
+ fence ( SeqCst ) ;
375
+ k. store ( 1 , Relaxed ) ;
376
+ } ) ;
377
+ let j2 = spawn ( move || {
378
+ y. store ( 1 , Relaxed ) ;
379
+ fence ( SeqCst ) ;
380
+ z. store ( 1 , Relaxed ) ;
381
+ } ) ;
382
+
383
+ let j3 = spawn ( move || {
384
+ let kval = k. load ( Acquire ) ;
385
+ let yval = y. load ( Relaxed ) ;
386
+ ( kval, yval)
387
+ } ) ;
388
+ let j4 = spawn ( move || {
389
+ let zval = z. load ( Acquire ) ;
390
+ let xval = x. load ( Relaxed ) ;
391
+ ( zval, xval)
392
+ } ) ;
393
+
394
+ j1. join ( ) . unwrap ( ) ;
395
+ j2. join ( ) . unwrap ( ) ;
396
+ let ( kval, yval) = j3. join ( ) . unwrap ( ) ;
397
+ let ( zval, xval) = j4. join ( ) . unwrap ( ) ;
398
+
399
+ let bad = kval == 1 && yval == 0 && zval == 1 && xval == 0 ;
400
+ assert ! ( !bad) ;
401
+ }
402
+
368
403
pub fn main ( ) {
369
404
for _ in 0 ..50 {
370
405
test_single_thread ( ) ;
@@ -378,5 +413,6 @@ pub fn main() {
378
413
test_iriw_sc_rlx ( ) ;
379
414
test_cpp20_sc_fence_fix ( ) ;
380
415
test_cpp20_rwc_syncs ( ) ;
416
+ test_sc_fence_release ( ) ;
381
417
}
382
418
}
0 commit comments