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
22// This test's runtime explodes if the GC interval is set to 1 (which we do in CI), so we
33// override it internally back to the default frequency.
44
@@ -365,6 +365,45 @@ fn test_cpp20_rwc_syncs() {
365365 assert ! ( ( b, c) != ( 0 , 0 ) ) ;
366366}
367367
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+
368407pub fn main ( ) {
369408 for _ in 0 ..50 {
370409 test_single_thread ( ) ;
@@ -378,5 +417,6 @@ pub fn main() {
378417 test_iriw_sc_rlx ( ) ;
379418 test_cpp20_sc_fence_fix ( ) ;
380419 test_cpp20_rwc_syncs ( ) ;
420+ test_sc_fence_release ( ) ;
381421 }
382422}
0 commit comments