diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 9cc4296c0fa48..d4150352edb7b 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -2337,10 +2337,7 @@ fn strongest_failure_ordering(order: Ordering) -> Ordering { } #[inline] -#[cfg_attr(target_arch = "bpf", allow(unused_variables))] -#[cfg_attr(target_arch = "sbf", allow(unused_variables))] unsafe fn atomic_store(dst: *mut T, val: T, order: Ordering) { - #[cfg(all(not(target_arch = "bpf"), not(target_arch = "sbf")))] // SAFETY: the caller must uphold the safety contract for `atomic_store`. unsafe { match order { @@ -2351,18 +2348,10 @@ unsafe fn atomic_store(dst: *mut T, val: T, order: Ordering) { AcqRel => panic!("there is no such thing as an acquire/release store"), } } - #[cfg(any(target_arch = "bpf", target_arch = "sbf"))] - // SAFETY: the caller must uphold the safety contract for `atomic_store`. - unsafe { - *dst = val; - } } #[inline] -#[cfg_attr(target_arch = "bpf", allow(unused_variables))] -#[cfg_attr(target_arch = "sbf", allow(unused_variables))] unsafe fn atomic_load(dst: *const T, order: Ordering) -> T { - #[cfg(all(not(target_arch = "bpf"), not(target_arch = "sbf")))] // SAFETY: the caller must uphold the safety contract for `atomic_load`. unsafe { match order { @@ -2373,19 +2362,11 @@ unsafe fn atomic_load(dst: *const T, order: Ordering) -> T { AcqRel => panic!("there is no such thing as an acquire/release load"), } } - #[cfg(any(target_arch = "bpf", target_arch = "sbf"))] - // SAFETY: the caller must uphold the safety contract for `atomic_load`. - unsafe { - *dst - } } #[inline] #[cfg(target_has_atomic = "8")] -#[cfg_attr(target_arch = "bpf", allow(unused_variables))] -#[cfg_attr(target_arch = "sbf", allow(unused_variables))] unsafe fn atomic_swap(dst: *mut T, val: T, order: Ordering) -> T { - #[cfg(all(not(target_arch = "bpf"), not(target_arch = "sbf")))] // SAFETY: the caller must uphold the safety contract for `atomic_swap`. unsafe { match order { @@ -2396,22 +2377,12 @@ unsafe fn atomic_swap(dst: *mut T, val: T, order: Ordering) -> T { SeqCst => intrinsics::atomic_xchg(dst, val), } } - #[cfg(any(target_arch = "bpf" ,target_arch = "sbf"))] - // SAFETY: the caller must uphold the safety contract for `atomic_swap`. - unsafe { - let old = *dst; - *dst = val; - old - } } /// Returns the previous value (like __sync_fetch_and_add). #[inline] #[cfg(target_has_atomic = "8")] -#[cfg_attr(target_arch = "bpf", allow(unused_variables))] -#[cfg_attr(target_arch = "sbf", allow(unused_variables))] unsafe fn atomic_add>(dst: *mut T, val: T, order: Ordering) -> T { - #[cfg(all(not(target_arch = "bpf"), not(target_arch = "sbf")))] // SAFETY: the caller must uphold the safety contract for `atomic_add`. unsafe { match order { @@ -2422,22 +2393,12 @@ unsafe fn atomic_add>(dst: *mut T, val: T, SeqCst => intrinsics::atomic_xadd(dst, val), } } - #[cfg(any(target_arch = "bpf", target_arch = "sbf"))] - // SAFETY: the caller must uphold the safety contract for `atomic_add`. - unsafe { - let old = *dst; - *dst = old + val; - old - } } /// Returns the previous value (like __sync_fetch_and_sub). #[inline] #[cfg(target_has_atomic = "8")] -#[cfg_attr(target_arch = "bpf", allow(unused_variables))] -#[cfg_attr(target_arch = "sbf", allow(unused_variables))] unsafe fn atomic_sub>(dst: *mut T, val: T, order: Ordering) -> T { - #[cfg(all(not(target_arch = "bpf"), not(target_arch = "sbf")))] // SAFETY: the caller must uphold the safety contract for `atomic_sub`. unsafe { match order { @@ -2448,19 +2409,10 @@ unsafe fn atomic_sub>(dst: *mut T, val: T, SeqCst => intrinsics::atomic_xsub(dst, val), } } - #[cfg(any(target_arch = "bpf", target_arch = "sbf"))] - // SAFETY: the caller must uphold the safety contract for `atomic_sub`. - unsafe { - let old = *dst; - *dst = old - val; - old - } } #[inline] #[cfg(target_has_atomic = "8")] -#[cfg_attr(target_arch = "bpf", allow(unused_variables))] -#[cfg_attr(target_arch = "sbf", allow(unused_variables))] unsafe fn atomic_compare_exchange( dst: *mut T, old: T, @@ -2468,38 +2420,24 @@ unsafe fn atomic_compare_exchange( success: Ordering, failure: Ordering, ) -> Result { - #[cfg(all(not(target_arch = "bpf"), not(target_arch = "sbf")))] - { - // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange`. - let (val, ok) = unsafe { - match (success, failure) { - (Acquire, Acquire) => intrinsics::atomic_cxchg_acq(dst, old, new), - (Release, Relaxed) => intrinsics::atomic_cxchg_rel(dst, old, new), - (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel(dst, old, new), - (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed(dst, old, new), - (SeqCst, SeqCst) => intrinsics::atomic_cxchg(dst, old, new), - (Acquire, Relaxed) => intrinsics::atomic_cxchg_acq_failrelaxed(dst, old, new), - (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_failrelaxed(dst, old, new), - (SeqCst, Relaxed) => intrinsics::atomic_cxchg_failrelaxed(dst, old, new), - (SeqCst, Acquire) => intrinsics::atomic_cxchg_failacq(dst, old, new), - (_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"), - (_, Release) => panic!("there is no such thing as a release failure ordering"), - _ => panic!("a failure ordering can't be stronger than a success ordering"), - } - }; - if ok { Ok(val) } else { Err(val) } - } - #[cfg(any(target_arch = "bpf", target_arch = "sbf"))] // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange`. - unsafe { - let current = *dst; - if current == old { - *dst = new; - Ok(current) - } else { - Err(current) + let (val, ok) = unsafe { + match (success, failure) { + (Acquire, Acquire) => intrinsics::atomic_cxchg_acq(dst, old, new), + (Release, Relaxed) => intrinsics::atomic_cxchg_rel(dst, old, new), + (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel(dst, old, new), + (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed(dst, old, new), + (SeqCst, SeqCst) => intrinsics::atomic_cxchg(dst, old, new), + (Acquire, Relaxed) => intrinsics::atomic_cxchg_acq_failrelaxed(dst, old, new), + (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_failrelaxed(dst, old, new), + (SeqCst, Relaxed) => intrinsics::atomic_cxchg_failrelaxed(dst, old, new), + (SeqCst, Acquire) => intrinsics::atomic_cxchg_failacq(dst, old, new), + (_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"), + (_, Release) => panic!("there is no such thing as a release failure ordering"), + _ => panic!("a failure ordering can't be stronger than a success ordering"), } - } + }; + if ok { Ok(val) } else { Err(val) } } #[inline] @@ -2511,38 +2449,24 @@ unsafe fn atomic_compare_exchange_weak( _success: Ordering, _failure: Ordering, ) -> Result { - #[cfg(all(not(target_arch = "bpf"), not(target_arch = "sbf")))] - { - // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange_weak`. - let (val, ok) = unsafe { - match (_success, _failure) { - (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acq(dst, old, new), - (Release, Relaxed) => intrinsics::atomic_cxchgweak_rel(dst, old, new), - (AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel(dst, old, new), - (Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed(dst, old, new), - (SeqCst, SeqCst) => intrinsics::atomic_cxchgweak(dst, old, new), - (Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acq_failrelaxed(dst, old, new), - (AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_failrelaxed(dst, old, new), - (SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_failrelaxed(dst, old, new), - (SeqCst, Acquire) => intrinsics::atomic_cxchgweak_failacq(dst, old, new), - (_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"), - (_, Release) => panic!("there is no such thing as a release failure ordering"), - _ => panic!("a failure ordering can't be stronger than a success ordering"), - } - }; - if ok { Ok(val) } else { Err(val) } - } - #[cfg(any(target_arch = "sbf", target_arch = "bpf"))] // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange_weak`. - unsafe { - let current = *dst; - if current == old { - *dst = new; - Ok(current) - } else { - Err(current) + let (val, ok) = unsafe { + match (_success, _failure) { + (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acq(dst, old, new), + (Release, Relaxed) => intrinsics::atomic_cxchgweak_rel(dst, old, new), + (AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel(dst, old, new), + (Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed(dst, old, new), + (SeqCst, SeqCst) => intrinsics::atomic_cxchgweak(dst, old, new), + (Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acq_failrelaxed(dst, old, new), + (AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_failrelaxed(dst, old, new), + (SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_failrelaxed(dst, old, new), + (SeqCst, Acquire) => intrinsics::atomic_cxchgweak_failacq(dst, old, new), + (_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"), + (_, Release) => panic!("there is no such thing as a release failure ordering"), + _ => panic!("a failure ordering can't be stronger than a success ordering"), } - } + }; + if ok { Ok(val) } else { Err(val) } } #[inline] @@ -2609,7 +2533,6 @@ unsafe fn atomic_xor(dst: *mut T, val: T, order: Ordering) -> T { #[inline] #[cfg(target_has_atomic = "8")] unsafe fn atomic_max(dst: *mut T, val: T, _order: Ordering) -> T { - #[cfg(all(not(target_arch = "bpf"), not(target_arch = "sbf")))] // SAFETY: the caller must uphold the safety contract for `atomic_max` unsafe { match _order { @@ -2620,18 +2543,12 @@ unsafe fn atomic_max(dst: *mut T, val: T, _order: Ord SeqCst => intrinsics::atomic_max(dst, val), } } - #[cfg(any(target_arch = "bpf", target_arch = "sbf"))] - // SAFETY: the caller must uphold the safety contract for `atomic_max` - unsafe { - crate::cmp::max(*dst, val) - } } /// returns the min value (signed comparison) #[inline] #[cfg(target_has_atomic = "8")] unsafe fn atomic_min(dst: *mut T, val: T, _order: Ordering) -> T { - #[cfg(all(not(target_arch = "bpf"), not(target_arch = "sbf")))] // SAFETY: the caller must uphold the safety contract for `atomic_min` unsafe { match _order { @@ -2642,18 +2559,12 @@ unsafe fn atomic_min(dst: *mut T, val: T, _order: Ord SeqCst => intrinsics::atomic_min(dst, val), } } - #[cfg(any(target_arch = "bpf", target_arch = "sbf"))] - // SAFETY: the caller must uphold the safety contract for `atomic_min` - unsafe { - crate::cmp::min(*dst, val) - } } /// returns the max value (unsigned comparison) #[inline] #[cfg(target_has_atomic = "8")] unsafe fn atomic_umax(dst: *mut T, val: T, _order: Ordering) -> T { - #[cfg(all(not(target_arch = "bpf"), not(target_arch = "sbf")))] // SAFETY: the caller must uphold the safety contract for `atomic_umax` unsafe { match _order { @@ -2664,18 +2575,12 @@ unsafe fn atomic_umax(dst: *mut T, val: T, _order: Or SeqCst => intrinsics::atomic_umax(dst, val), } } - #[cfg(any(target_arch = "bpf", target_arch = "sbf"))] - // SAFETY: the caller must uphold the safety contract for `atomic_umax` - unsafe { - crate::cmp::max(*dst, val) - } } /// returns the min value (unsigned comparison) #[inline] #[cfg(target_has_atomic = "8")] unsafe fn atomic_umin(dst: *mut T, val: T, _order: Ordering) -> T { - #[cfg(all(not(target_arch = "bpf"), not(target_arch = "sbf")))] // SAFETY: the caller must uphold the safety contract for `atomic_umin` unsafe { match _order { @@ -2686,11 +2591,6 @@ unsafe fn atomic_umin(dst: *mut T, val: T, _order: Or SeqCst => intrinsics::atomic_umin(dst, val), } } - #[cfg(any(target_arch = "bpf", target_arch = "sbf"))] - // SAFETY: the caller must uphold the safety contract for `atomic_umin` - unsafe { - crate::cmp::min(*dst, val) - } } /// An atomic fence. @@ -2770,16 +2670,8 @@ unsafe fn atomic_umin(dst: *mut T, val: T, _order: Or #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "fence"] -#[cfg_attr(any(target_arch = "bpf", target_arch = "sbf", target_arch = "wasm32"), allow(unused_variables))] pub fn fence(order: Ordering) { - #[cfg(not(any(target_arch = "wasm32", target_arch = "bpf", target_arch = "sbf")))] // SAFETY: using an atomic fence is safe. - // On wasm32 and SBF it looks like fences aren't implemented in LLVM yet in that - // they will cause LLVM to abort. The wasm instruction set doesn't have - // fences right now. There's discussion online about the best way for tools - // to conventionally implement fences at - // https://github.com/WebAssembly/tool-conventions/issues/59. We should - // follow that discussion and implement a solution when one comes about! unsafe { match order { Acquire => intrinsics::atomic_fence_acq(), @@ -2860,10 +2752,7 @@ pub fn fence(order: Ordering) { #[inline] #[stable(feature = "compiler_fences", since = "1.21.0")] #[rustc_diagnostic_item = "compiler_fence"] -#[cfg_attr(target_arch = "bpf", allow(unused_variables))] -#[cfg_attr(target_arch = "sbf", allow(unused_variables))] pub fn compiler_fence(order: Ordering) { - #[cfg(all(not(target_arch = "bpf"), not(target_arch = "sbf")))] // SAFETY: using an atomic fence is safe. unsafe { match order { diff --git a/library/core/tests/atomic.rs b/library/core/tests/atomic.rs index b735957666fc5..b001da590a975 100644 --- a/library/core/tests/atomic.rs +++ b/library/core/tests/atomic.rs @@ -127,38 +127,42 @@ fn int_max() { assert_eq!(x.load(SeqCst), 0xf731); } -static S_FALSE: AtomicBool = AtomicBool::new(false); -static S_TRUE: AtomicBool = AtomicBool::new(true); -static S_INT: AtomicIsize = AtomicIsize::new(0); -static S_UINT: AtomicUsize = AtomicUsize::new(0); - -#[test] -fn static_init() { - // Note that we're not really testing the mutability here but it's important - // on Android at the moment (#49775) - assert!(!S_FALSE.swap(true, SeqCst)); - assert!(S_TRUE.swap(false, SeqCst)); - assert!(S_INT.fetch_add(1, SeqCst) == 0); - assert!(S_UINT.fetch_add(1, SeqCst) == 0); +// SBF does not support mustable static data +#[cfg(not(any(target_arch = "bpf", target_arch = "sbf")))] +mod statik { + use super::*; + + static S_FALSE: AtomicBool = AtomicBool::new(false); + static S_TRUE: AtomicBool = AtomicBool::new(true); + static S_INT: AtomicIsize = AtomicIsize::new(0); + static S_UINT: AtomicUsize = AtomicUsize::new(0); + + #[test] + fn static_init() { + // Note that we're not really testing the mutability here but it's important + // on Android at the moment (#49775) + assert!(!S_FALSE.swap(true, SeqCst)); + assert!(S_TRUE.swap(false, SeqCst)); + assert!(S_INT.fetch_add(1, SeqCst) == 0); + assert!(S_UINT.fetch_add(1, SeqCst) == 0); + } } #[test] fn atomic_access_bool() { - static mut ATOMIC: AtomicBool = AtomicBool::new(false); - - unsafe { - assert_eq!(*ATOMIC.get_mut(), false); - ATOMIC.store(true, SeqCst); - assert_eq!(*ATOMIC.get_mut(), true); - ATOMIC.fetch_or(false, SeqCst); - assert_eq!(*ATOMIC.get_mut(), true); - ATOMIC.fetch_and(false, SeqCst); - assert_eq!(*ATOMIC.get_mut(), false); - ATOMIC.fetch_nand(true, SeqCst); - assert_eq!(*ATOMIC.get_mut(), true); - ATOMIC.fetch_xor(true, SeqCst); - assert_eq!(*ATOMIC.get_mut(), false); - } + let mut atomic: AtomicBool = AtomicBool::new(false); + + assert_eq!(*atomic.get_mut(), false); + atomic.store(true, SeqCst); + assert_eq!(*atomic.get_mut(), true); + atomic.fetch_or(false, SeqCst); + assert_eq!(*atomic.get_mut(), true); + atomic.fetch_and(false, SeqCst); + assert_eq!(*atomic.get_mut(), false); + atomic.fetch_nand(true, SeqCst); + assert_eq!(*atomic.get_mut(), true); + atomic.fetch_xor(true, SeqCst); + assert_eq!(*atomic.get_mut(), false); } #[test] @@ -199,24 +203,24 @@ fn atomic_alignment() { fn atomic_compare_exchange() { use Ordering::*; - static ATOMIC: AtomicIsize = AtomicIsize::new(0); - - ATOMIC.compare_exchange(0, 1, Relaxed, Relaxed).ok(); - ATOMIC.compare_exchange(0, 1, Acquire, Relaxed).ok(); - ATOMIC.compare_exchange(0, 1, Release, Relaxed).ok(); - ATOMIC.compare_exchange(0, 1, AcqRel, Relaxed).ok(); - ATOMIC.compare_exchange(0, 1, SeqCst, Relaxed).ok(); - ATOMIC.compare_exchange(0, 1, Acquire, Acquire).ok(); - ATOMIC.compare_exchange(0, 1, AcqRel, Acquire).ok(); - ATOMIC.compare_exchange(0, 1, SeqCst, Acquire).ok(); - ATOMIC.compare_exchange(0, 1, SeqCst, SeqCst).ok(); - ATOMIC.compare_exchange_weak(0, 1, Relaxed, Relaxed).ok(); - ATOMIC.compare_exchange_weak(0, 1, Acquire, Relaxed).ok(); - ATOMIC.compare_exchange_weak(0, 1, Release, Relaxed).ok(); - ATOMIC.compare_exchange_weak(0, 1, AcqRel, Relaxed).ok(); - ATOMIC.compare_exchange_weak(0, 1, SeqCst, Relaxed).ok(); - ATOMIC.compare_exchange_weak(0, 1, Acquire, Acquire).ok(); - ATOMIC.compare_exchange_weak(0, 1, AcqRel, Acquire).ok(); - ATOMIC.compare_exchange_weak(0, 1, SeqCst, Acquire).ok(); - ATOMIC.compare_exchange_weak(0, 1, SeqCst, SeqCst).ok(); + let atomic: AtomicIsize = AtomicIsize::new(0); + + atomic.compare_exchange(0, 1, Relaxed, Relaxed).ok(); + atomic.compare_exchange(0, 1, Acquire, Relaxed).ok(); + atomic.compare_exchange(0, 1, Release, Relaxed).ok(); + atomic.compare_exchange(0, 1, AcqRel, Relaxed).ok(); + atomic.compare_exchange(0, 1, SeqCst, Relaxed).ok(); + atomic.compare_exchange(0, 1, Acquire, Acquire).ok(); + atomic.compare_exchange(0, 1, AcqRel, Acquire).ok(); + atomic.compare_exchange(0, 1, SeqCst, Acquire).ok(); + atomic.compare_exchange(0, 1, SeqCst, SeqCst).ok(); + atomic.compare_exchange_weak(0, 1, Relaxed, Relaxed).ok(); + atomic.compare_exchange_weak(0, 1, Acquire, Relaxed).ok(); + atomic.compare_exchange_weak(0, 1, Release, Relaxed).ok(); + atomic.compare_exchange_weak(0, 1, AcqRel, Relaxed).ok(); + atomic.compare_exchange_weak(0, 1, SeqCst, Relaxed).ok(); + atomic.compare_exchange_weak(0, 1, Acquire, Acquire).ok(); + atomic.compare_exchange_weak(0, 1, AcqRel, Acquire).ok(); + atomic.compare_exchange_weak(0, 1, SeqCst, Acquire).ok(); + atomic.compare_exchange_weak(0, 1, SeqCst, SeqCst).ok(); } diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index b77c9c6e57cd7..cd1eeac445035 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -79,7 +79,6 @@ mod alloc; mod any; mod array; mod ascii; -#[cfg(not(any(target_arch = "bpf", target_arch = "sbf")))] mod atomic; mod bool; mod cell; diff --git a/src/llvm-project b/src/llvm-project index 9f7a8c20a4870..421b949f53f69 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 9f7a8c20a487058b72d85c37060fc793a87db2ed +Subproject commit 421b949f53f69b9790a1e8ff8a092bfc7bc56f28