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
@@ -365,6 +365,45 @@ fn test_cpp20_rwc_syncs() {
365
365
assert ! ( ( b, c) != ( 0 , 0 ) ) ;
366
366
}
367
367
368
+ /// This checks that the *last* thing the SC fence does is act like a release fence.
369
+ /// See <https://github.com/rust-lang/miri/pull/4057#issuecomment-2522296601>.
370
+ fn test_sc_fence_release ( ) {
371
+ let x = static_atomic ( 0 ) ;
372
+ let y = static_atomic ( 0 ) ;
373
+ let z = static_atomic ( 0 ) ;
374
+ let k = static_atomic ( 0 ) ;
375
+
376
+ let j1 = spawn ( move || {
377
+ x. store ( 1 , Relaxed ) ;
378
+ fence ( SeqCst ) ;
379
+ k. store ( 1 , Relaxed ) ;
380
+ } ) ;
381
+ let j2 = spawn ( move || {
382
+ y. store ( 1 , Relaxed ) ;
383
+ fence ( SeqCst ) ;
384
+ z. store ( 1 , Relaxed ) ;
385
+ } ) ;
386
+
387
+ let j3 = spawn ( move || {
388
+ let kval = k. load ( Acquire ) ;
389
+ let yval = y. load ( Relaxed ) ;
390
+ ( kval, yval)
391
+ } ) ;
392
+ let j4 = spawn ( move || {
393
+ let zval = z. load ( Acquire ) ;
394
+ let xval = x. load ( Relaxed ) ;
395
+ ( zval, xval)
396
+ } ) ;
397
+
398
+ j1. join ( ) . unwrap ( ) ;
399
+ j2. join ( ) . unwrap ( ) ;
400
+ let ( kval, yval) = j3. join ( ) . unwrap ( ) ;
401
+ let ( zval, xval) = j4. join ( ) . unwrap ( ) ;
402
+
403
+ let bad = kval == 1 && yval == 0 && zval == 1 && xval == 0 ;
404
+ assert ! ( !bad) ;
405
+ }
406
+
368
407
pub fn main ( ) {
369
408
for _ in 0 ..50 {
370
409
test_single_thread ( ) ;
@@ -378,5 +417,6 @@ pub fn main() {
378
417
test_iriw_sc_rlx ( ) ;
379
418
test_cpp20_sc_fence_fix ( ) ;
380
419
test_cpp20_rwc_syncs ( ) ;
420
+ test_sc_fence_release ( ) ;
381
421
}
382
422
}
0 commit comments