22#![ feature( macro_metavar_expr_concat) ]
33#![ cfg( target_arch = "aarch64" ) ]
44
5+ use std:: sync:: Mutex ;
6+
7+ use compiler_builtins:: aarch64_outline_atomics:: { get_have_lse_atomics, set_have_lse_atomics} ;
8+ use compiler_builtins:: int:: { Int , MinInt } ;
9+ use compiler_builtins:: { foreach_bytes, foreach_ordering} ;
10+
11+ #[ track_caller]
12+ fn with_maybe_lse_atomics ( use_lse : bool , f : impl FnOnce ( ) ) {
13+ // Ensure tests run in parallel don't interleave global settings
14+ static LOCK : Mutex < ( ) > = Mutex :: new ( ( ) ) ;
15+ let _g = LOCK . lock ( ) . unwrap ( ) ;
16+ let old = get_have_lse_atomics ( ) ;
17+ // safety: as the caller of the unsafe fn `set_have_lse_atomics`, we
18+ // have to ensure the CPU supports LSE. This is why we make this assertion.
19+ if use_lse || old {
20+ assert ! ( std:: arch:: is_aarch64_feature_detected!( "lse" ) ) ;
21+ }
22+ unsafe { set_have_lse_atomics ( use_lse) } ;
23+ f ( ) ;
24+ unsafe { set_have_lse_atomics ( old) } ;
25+ }
26+
27+ pub fn run_fuzz_tests_with_lse_variants < I : Int , F : Fn ( I , I ) + Copy > ( n : u32 , f : F )
28+ where
29+ <I as MinInt >:: Unsigned : Int ,
30+ {
31+ // We use `fuzz_2` because our subject function `f` requires two inputs
32+ let test_fn = || {
33+ builtins_test:: fuzz_2 ( n, f) ;
34+ } ;
35+ // Always run without LSE
36+ with_maybe_lse_atomics ( false , test_fn) ;
37+
38+ // Conditionally run with LSE
39+ if std:: arch:: is_aarch64_feature_detected!( "lse" ) {
40+ with_maybe_lse_atomics ( true , test_fn) ;
41+ }
42+ }
43+
544/// Translate a byte size to a Rust type.
645macro int_ty {
746 ( 1 ) => { u8 } ,
@@ -15,7 +54,7 @@ mod cas {
1554 pub ( super ) macro test( $_ordering: ident, $bytes: tt, $name: ident) {
1655 #[ test]
1756 fn $name( ) {
18- builtins_test :: fuzz_2 ( 10000 , |expected : super :: int_ty!( $bytes) , new| {
57+ crate :: run_fuzz_tests_with_lse_variants ( 10000 , |expected : super :: int_ty!( $bytes) , new| {
1958 let mut target = expected. wrapping_add ( 10 ) ;
2059 let ret: super :: int_ty!( $bytes) = unsafe {
2160 compiler_builtins:: aarch64_outline_atomics :: $name:: $name(
@@ -62,16 +101,21 @@ mod swap {
62101 pub ( super ) macro test( $_ordering: ident, $bytes: tt, $name: ident) {
63102 #[ test]
64103 fn $name( ) {
65- builtins_test:: fuzz_2 ( 10000 , |left : super :: int_ty!( $bytes) , mut right| {
66- let orig_right = right;
67- assert_eq ! (
68- unsafe {
69- compiler_builtins:: aarch64_outline_atomics:: $name:: $name( left, & mut right)
70- } ,
71- orig_right
72- ) ;
73- assert_eq ! ( left, right) ;
74- } ) ;
104+ crate :: run_fuzz_tests_with_lse_variants (
105+ 10000 ,
106+ |left : super :: int_ty!( $bytes) , mut right| {
107+ let orig_right = right;
108+ assert_eq ! (
109+ unsafe {
110+ compiler_builtins:: aarch64_outline_atomics:: $name:: $name(
111+ left, & mut right,
112+ )
113+ } ,
114+ orig_right
115+ ) ;
116+ assert_eq ! ( left, right) ;
117+ } ,
118+ ) ;
75119 }
76120 }
77121}
@@ -83,7 +127,7 @@ macro_rules! test_op {
83127 ( $_ordering: ident, $bytes: tt, $name: ident) => {
84128 #[ test]
85129 fn $name( ) {
86- builtins_test :: fuzz_2 ( 10000 , |old, val| {
130+ crate :: run_fuzz_tests_with_lse_variants ( 10000 , |old, val| {
87131 let mut target = old;
88132 let op: fn ( super :: int_ty!( $bytes) , super :: int_ty!( $bytes) ) -> _ = $( $op) * ;
89133 let expected = op( old, val) ;
@@ -101,7 +145,6 @@ test_op!(add, |left, right| left.wrapping_add(right));
101145test_op ! ( clr, |left, right| left & !right) ;
102146test_op ! ( xor, std:: ops:: BitXor :: bitxor) ;
103147test_op ! ( or, std:: ops:: BitOr :: bitor) ;
104- use compiler_builtins:: { foreach_bytes, foreach_ordering} ;
105148compiler_builtins:: foreach_cas!( cas:: test) ;
106149compiler_builtins:: foreach_cas16!( test_cas16) ;
107150compiler_builtins:: foreach_swp!( swap:: test) ;
0 commit comments