Split non-CAS atomic support off into target_has_atomic_load_store
This commit is contained in:
parent
59a31c8c67
commit
dfe76a1093
7 changed files with 127 additions and 98 deletions
|
@ -154,7 +154,7 @@ mod boxed {
|
|||
#[cfg(test)]
|
||||
mod tests;
|
||||
pub mod collections;
|
||||
#[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))]
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
pub mod sync;
|
||||
pub mod rc;
|
||||
pub mod raw_vec;
|
||||
|
|
|
@ -113,8 +113,8 @@
|
|||
//! ```
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
#![cfg_attr(not(target_has_atomic = "8"), allow(dead_code))]
|
||||
#![cfg_attr(not(target_has_atomic = "8"), allow(unused_imports))]
|
||||
#![cfg_attr(not(target_has_atomic_load_store = "8"), allow(dead_code))]
|
||||
#![cfg_attr(not(target_has_atomic_load_store = "8"), allow(unused_imports))]
|
||||
|
||||
use self::Ordering::*;
|
||||
|
||||
|
@ -160,14 +160,14 @@ pub fn spin_loop_hint() {
|
|||
/// This type has the same in-memory representation as a [`bool`].
|
||||
///
|
||||
/// [`bool`]: ../../../std/primitive.bool.html
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[repr(C, align(1))]
|
||||
pub struct AtomicBool {
|
||||
v: UnsafeCell<u8>,
|
||||
}
|
||||
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Default for AtomicBool {
|
||||
/// Creates an `AtomicBool` initialized to `false`.
|
||||
|
@ -177,14 +177,14 @@ impl Default for AtomicBool {
|
|||
}
|
||||
|
||||
// Send is implicitly implemented for AtomicBool.
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
unsafe impl Sync for AtomicBool {}
|
||||
|
||||
/// A raw pointer type which can be safely shared between threads.
|
||||
///
|
||||
/// This type has the same in-memory representation as a `*mut T`.
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(target_pointer_width = "16", repr(C, align(2)))]
|
||||
#[cfg_attr(target_pointer_width = "32", repr(C, align(4)))]
|
||||
|
@ -193,7 +193,7 @@ pub struct AtomicPtr<T> {
|
|||
p: UnsafeCell<*mut T>,
|
||||
}
|
||||
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T> Default for AtomicPtr<T> {
|
||||
/// Creates a null `AtomicPtr<T>`.
|
||||
|
@ -202,10 +202,10 @@ impl<T> Default for AtomicPtr<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
unsafe impl<T> Send for AtomicPtr<T> {}
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
unsafe impl<T> Sync for AtomicPtr<T> {}
|
||||
|
||||
|
@ -304,7 +304,7 @@ pub enum Ordering {
|
|||
/// An [`AtomicBool`] initialized to `false`.
|
||||
///
|
||||
/// [`AtomicBool`]: struct.AtomicBool.html
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_deprecated(
|
||||
since = "1.34.0",
|
||||
|
@ -313,7 +313,7 @@ pub enum Ordering {
|
|||
)]
|
||||
pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||
impl AtomicBool {
|
||||
/// Creates a new `AtomicBool`.
|
||||
///
|
||||
|
@ -462,7 +462,7 @@ impl AtomicBool {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
pub fn swap(&self, val: bool, order: Ordering) -> bool {
|
||||
unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 }
|
||||
}
|
||||
|
@ -500,7 +500,7 @@ impl AtomicBool {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
pub fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> bool {
|
||||
match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
|
||||
Ok(x) => x,
|
||||
|
@ -551,7 +551,7 @@ impl AtomicBool {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
pub fn compare_exchange(&self,
|
||||
current: bool,
|
||||
new: bool,
|
||||
|
@ -607,7 +607,7 @@ impl AtomicBool {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
pub fn compare_exchange_weak(&self,
|
||||
current: bool,
|
||||
new: bool,
|
||||
|
@ -658,7 +658,7 @@ impl AtomicBool {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
|
||||
unsafe { atomic_and(self.v.get(), val as u8, order) != 0 }
|
||||
}
|
||||
|
@ -700,7 +700,7 @@ impl AtomicBool {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
|
||||
// We can't use atomic_nand here because it can result in a bool with
|
||||
// an invalid value. This happens because the atomic operation is done
|
||||
|
@ -753,7 +753,7 @@ impl AtomicBool {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
|
||||
unsafe { atomic_or(self.v.get(), val as u8, order) != 0 }
|
||||
}
|
||||
|
@ -794,13 +794,13 @@ impl AtomicBool {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
|
||||
unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||
impl<T> AtomicPtr<T> {
|
||||
/// Creates a new `AtomicPtr`.
|
||||
///
|
||||
|
@ -951,7 +951,7 @@ impl<T> AtomicPtr<T> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
|
||||
unsafe { atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T }
|
||||
}
|
||||
|
@ -987,7 +987,7 @@ impl<T> AtomicPtr<T> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) -> *mut T {
|
||||
match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
|
||||
Ok(x) => x,
|
||||
|
@ -1029,7 +1029,7 @@ impl<T> AtomicPtr<T> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
pub fn compare_exchange(&self,
|
||||
current: *mut T,
|
||||
new: *mut T,
|
||||
|
@ -1089,7 +1089,7 @@ impl<T> AtomicPtr<T> {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
pub fn compare_exchange_weak(&self,
|
||||
current: *mut T,
|
||||
new: *mut T,
|
||||
|
@ -1110,7 +1110,7 @@ impl<T> AtomicPtr<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||
#[stable(feature = "atomic_bool_from", since = "1.24.0")]
|
||||
impl From<bool> for AtomicBool {
|
||||
/// Converts a `bool` into an `AtomicBool`.
|
||||
|
@ -1126,16 +1126,17 @@ impl From<bool> for AtomicBool {
|
|||
fn from(b: bool) -> Self { Self::new(b) }
|
||||
}
|
||||
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||
#[stable(feature = "atomic_from", since = "1.23.0")]
|
||||
impl<T> From<*mut T> for AtomicPtr<T> {
|
||||
#[inline]
|
||||
fn from(p: *mut T) -> Self { Self::new(p) }
|
||||
}
|
||||
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||
macro_rules! atomic_int {
|
||||
($stable:meta,
|
||||
($cfg_cas:meta,
|
||||
$stable:meta,
|
||||
$stable_cxchg:meta,
|
||||
$stable_debug:meta,
|
||||
$stable_access:meta,
|
||||
|
@ -1356,7 +1357,7 @@ assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
|
|||
```"),
|
||||
#[inline]
|
||||
#[$stable]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[$cfg_cas]
|
||||
pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
unsafe { atomic_swap(self.v.get(), val, order) }
|
||||
}
|
||||
|
@ -1396,7 +1397,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10);
|
|||
```"),
|
||||
#[inline]
|
||||
#[$stable]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[$cfg_cas]
|
||||
pub fn compare_and_swap(&self,
|
||||
current: $int_type,
|
||||
new: $int_type,
|
||||
|
@ -1454,7 +1455,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10);
|
|||
```"),
|
||||
#[inline]
|
||||
#[$stable_cxchg]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[$cfg_cas]
|
||||
pub fn compare_exchange(&self,
|
||||
current: $int_type,
|
||||
new: $int_type,
|
||||
|
@ -1506,7 +1507,7 @@ loop {
|
|||
```"),
|
||||
#[inline]
|
||||
#[$stable_cxchg]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[$cfg_cas]
|
||||
pub fn compare_exchange_weak(&self,
|
||||
current: $int_type,
|
||||
new: $int_type,
|
||||
|
@ -1544,7 +1545,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 10);
|
|||
```"),
|
||||
#[inline]
|
||||
#[$stable]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[$cfg_cas]
|
||||
pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
unsafe { atomic_add(self.v.get(), val, order) }
|
||||
}
|
||||
|
@ -1576,7 +1577,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 10);
|
|||
```"),
|
||||
#[inline]
|
||||
#[$stable]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[$cfg_cas]
|
||||
pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
unsafe { atomic_sub(self.v.get(), val, order) }
|
||||
}
|
||||
|
@ -1611,7 +1612,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
|
|||
```"),
|
||||
#[inline]
|
||||
#[$stable]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[$cfg_cas]
|
||||
pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
unsafe { atomic_and(self.v.get(), val, order) }
|
||||
}
|
||||
|
@ -1647,7 +1648,7 @@ assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
|
|||
```"),
|
||||
#[inline]
|
||||
#[$stable_nand]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[$cfg_cas]
|
||||
pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
unsafe { atomic_nand(self.v.get(), val, order) }
|
||||
}
|
||||
|
@ -1682,7 +1683,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
|
|||
```"),
|
||||
#[inline]
|
||||
#[$stable]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[$cfg_cas]
|
||||
pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
unsafe { atomic_or(self.v.get(), val, order) }
|
||||
}
|
||||
|
@ -1717,7 +1718,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
|
|||
```"),
|
||||
#[inline]
|
||||
#[$stable]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[$cfg_cas]
|
||||
pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
unsafe { atomic_xor(self.v.get(), val, order) }
|
||||
}
|
||||
|
@ -1767,7 +1768,7 @@ assert_eq!(x.load(Ordering::SeqCst), 9);
|
|||
#[unstable(feature = "no_more_cas",
|
||||
reason = "no more CAS loops in user code",
|
||||
issue = "48655")]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[$cfg_cas]
|
||||
pub fn fetch_update<F>(&self,
|
||||
mut f: F,
|
||||
fetch_order: Ordering,
|
||||
|
@ -1828,7 +1829,7 @@ assert!(max_foo == 42);
|
|||
#[unstable(feature = "atomic_min_max",
|
||||
reason = "easier and faster min/max than writing manual CAS loop",
|
||||
issue = "48655")]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[$cfg_cas]
|
||||
pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
unsafe { $max_fn(self.v.get(), val, order) }
|
||||
}
|
||||
|
@ -1880,7 +1881,7 @@ assert_eq!(min_foo, 12);
|
|||
#[unstable(feature = "atomic_min_max",
|
||||
reason = "easier and faster min/max than writing manual CAS loop",
|
||||
issue = "48655")]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[$cfg_cas]
|
||||
pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
unsafe { $min_fn(self.v.get(), val, order) }
|
||||
}
|
||||
|
@ -1890,8 +1891,9 @@ assert_eq!(min_foo, 12);
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||
atomic_int! {
|
||||
cfg(target_has_atomic = "8"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
|
@ -1906,8 +1908,9 @@ atomic_int! {
|
|||
"AtomicI8::new(0)",
|
||||
i8 AtomicI8 ATOMIC_I8_INIT
|
||||
}
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||
atomic_int! {
|
||||
cfg(target_has_atomic = "8"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
|
@ -1922,8 +1925,9 @@ atomic_int! {
|
|||
"AtomicU8::new(0)",
|
||||
u8 AtomicU8 ATOMIC_U8_INIT
|
||||
}
|
||||
#[cfg(target_has_atomic = "16")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "16"))]
|
||||
atomic_int! {
|
||||
cfg(target_has_atomic = "16"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
|
@ -1938,8 +1942,9 @@ atomic_int! {
|
|||
"AtomicI16::new(0)",
|
||||
i16 AtomicI16 ATOMIC_I16_INIT
|
||||
}
|
||||
#[cfg(target_has_atomic = "16")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "16"))]
|
||||
atomic_int! {
|
||||
cfg(target_has_atomic = "16"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
|
@ -1954,8 +1959,9 @@ atomic_int! {
|
|||
"AtomicU16::new(0)",
|
||||
u16 AtomicU16 ATOMIC_U16_INIT
|
||||
}
|
||||
#[cfg(target_has_atomic = "32")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "32"))]
|
||||
atomic_int! {
|
||||
cfg(target_has_atomic = "32"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
|
@ -1970,8 +1976,9 @@ atomic_int! {
|
|||
"AtomicI32::new(0)",
|
||||
i32 AtomicI32 ATOMIC_I32_INIT
|
||||
}
|
||||
#[cfg(target_has_atomic = "32")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "32"))]
|
||||
atomic_int! {
|
||||
cfg(target_has_atomic = "32"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
|
@ -1986,8 +1993,12 @@ atomic_int! {
|
|||
"AtomicU32::new(0)",
|
||||
u32 AtomicU32 ATOMIC_U32_INIT
|
||||
}
|
||||
#[cfg(target_has_atomic = "64")]
|
||||
#[cfg(any(
|
||||
all(bootstrap, target_has_atomic = "64"),
|
||||
target_has_atomic_load_store = "64"
|
||||
))]
|
||||
atomic_int! {
|
||||
cfg(target_has_atomic = "64"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
|
@ -2002,8 +2013,12 @@ atomic_int! {
|
|||
"AtomicI64::new(0)",
|
||||
i64 AtomicI64 ATOMIC_I64_INIT
|
||||
}
|
||||
#[cfg(target_has_atomic = "64")]
|
||||
#[cfg(any(
|
||||
all(bootstrap, target_has_atomic = "64"),
|
||||
target_has_atomic_load_store = "64"
|
||||
))]
|
||||
atomic_int! {
|
||||
cfg(target_has_atomic = "64"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
stable(feature = "integer_atomics_stable", since = "1.34.0"),
|
||||
|
@ -2018,8 +2033,9 @@ atomic_int! {
|
|||
"AtomicU64::new(0)",
|
||||
u64 AtomicU64 ATOMIC_U64_INIT
|
||||
}
|
||||
#[cfg(target_has_atomic = "128")]
|
||||
#[cfg(target_has_atomic_load_store = "128")]
|
||||
atomic_int! {
|
||||
cfg(target_has_atomic = "128"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
|
@ -2034,8 +2050,9 @@ atomic_int! {
|
|||
"AtomicI128::new(0)",
|
||||
i128 AtomicI128 ATOMIC_I128_INIT
|
||||
}
|
||||
#[cfg(target_has_atomic = "128")]
|
||||
#[cfg(target_has_atomic_load_store = "128")]
|
||||
atomic_int! {
|
||||
cfg(target_has_atomic = "128"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
|
@ -2050,20 +2067,24 @@ atomic_int! {
|
|||
"AtomicU128::new(0)",
|
||||
u128 AtomicU128 ATOMIC_U128_INIT
|
||||
}
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||
#[cfg(target_pointer_width = "16")]
|
||||
macro_rules! ptr_width {
|
||||
() => { 2 }
|
||||
}
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
macro_rules! ptr_width {
|
||||
() => { 4 }
|
||||
}
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
macro_rules! ptr_width {
|
||||
() => { 8 }
|
||||
}
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||
atomic_int!{
|
||||
cfg(target_has_atomic = "ptr"),
|
||||
stable(feature = "rust1", since = "1.0.0"),
|
||||
stable(feature = "extended_compare_and_swap", since = "1.10.0"),
|
||||
stable(feature = "atomic_debug", since = "1.3.0"),
|
||||
|
@ -2078,8 +2099,9 @@ atomic_int!{
|
|||
"AtomicIsize::new(0)",
|
||||
isize AtomicIsize ATOMIC_ISIZE_INIT
|
||||
}
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||
atomic_int!{
|
||||
cfg(target_has_atomic = "ptr"),
|
||||
stable(feature = "rust1", since = "1.0.0"),
|
||||
stable(feature = "extended_compare_and_swap", since = "1.10.0"),
|
||||
stable(feature = "atomic_debug", since = "1.3.0"),
|
||||
|
@ -2096,7 +2118,7 @@ atomic_int!{
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
fn strongest_failure_ordering(order: Ordering) -> Ordering {
|
||||
match order {
|
||||
Release => Relaxed,
|
||||
|
@ -2130,7 +2152,7 @@ unsafe fn atomic_load<T>(dst: *const T, order: Ordering) -> T {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_xchg_acq(dst, val),
|
||||
|
@ -2143,7 +2165,7 @@ unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
|
||||
/// Returns the previous value (like __sync_fetch_and_add).
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_xadd_acq(dst, val),
|
||||
|
@ -2156,7 +2178,7 @@ unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
|
||||
/// Returns the previous value (like __sync_fetch_and_sub).
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_xsub_acq(dst, val),
|
||||
|
@ -2168,7 +2190,7 @@ unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
unsafe fn atomic_compare_exchange<T>(dst: *mut T,
|
||||
old: T,
|
||||
new: T,
|
||||
|
@ -2193,7 +2215,7 @@ unsafe fn atomic_compare_exchange<T>(dst: *mut T,
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
unsafe fn atomic_compare_exchange_weak<T>(dst: *mut T,
|
||||
old: T,
|
||||
new: T,
|
||||
|
@ -2218,7 +2240,7 @@ unsafe fn atomic_compare_exchange_weak<T>(dst: *mut T,
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_and_acq(dst, val),
|
||||
|
@ -2230,7 +2252,7 @@ unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
unsafe fn atomic_nand<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_nand_acq(dst, val),
|
||||
|
@ -2242,7 +2264,7 @@ unsafe fn atomic_nand<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_or_acq(dst, val),
|
||||
|
@ -2254,7 +2276,7 @@ unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_xor_acq(dst, val),
|
||||
|
@ -2267,7 +2289,7 @@ unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
|
||||
/// returns the max value (signed comparison)
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
unsafe fn atomic_max<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_max_acq(dst, val),
|
||||
|
@ -2280,7 +2302,7 @@ unsafe fn atomic_max<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
|
||||
/// returns the min value (signed comparison)
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
unsafe fn atomic_min<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_min_acq(dst, val),
|
||||
|
@ -2293,7 +2315,7 @@ unsafe fn atomic_min<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
|
||||
/// returns the max value (signed comparison)
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
unsafe fn atomic_umax<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_umax_acq(dst, val),
|
||||
|
@ -2306,7 +2328,7 @@ unsafe fn atomic_umax<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
|
||||
/// returns the min value (signed comparison)
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "cas")]
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
unsafe fn atomic_umin<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_umin_acq(dst, val),
|
||||
|
@ -2504,7 +2526,7 @@ pub fn compiler_fence(order: Ordering) {
|
|||
}
|
||||
|
||||
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))]
|
||||
#[stable(feature = "atomic_debug", since = "1.3.0")]
|
||||
impl fmt::Debug for AtomicBool {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
@ -2512,7 +2534,7 @@ impl fmt::Debug for AtomicBool {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||
#[stable(feature = "atomic_debug", since = "1.3.0")]
|
||||
impl<T> fmt::Debug for AtomicPtr<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
@ -2520,7 +2542,7 @@ impl<T> fmt::Debug for AtomicPtr<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))]
|
||||
#[stable(feature = "atomic_pointer", since = "1.24.0")]
|
||||
impl<T> fmt::Pointer for AtomicPtr<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
|
|
@ -1514,22 +1514,25 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
|
|||
}
|
||||
for &i in &[8, 16, 32, 64, 128] {
|
||||
if i >= min_atomic_width && i <= max_atomic_width {
|
||||
let s = i.to_string();
|
||||
ret.insert((
|
||||
sym::target_has_atomic,
|
||||
Some(Symbol::intern(&s)),
|
||||
));
|
||||
if &s == wordsz {
|
||||
let mut insert_atomic = |s| {
|
||||
ret.insert((
|
||||
sym::target_has_atomic,
|
||||
Some(Symbol::intern("ptr")),
|
||||
sym::target_has_atomic_load_store,
|
||||
Some(Symbol::intern(s)),
|
||||
));
|
||||
if atomic_cas {
|
||||
ret.insert((
|
||||
sym::target_has_atomic,
|
||||
Some(Symbol::intern(s))
|
||||
));
|
||||
}
|
||||
};
|
||||
let s = i.to_string();
|
||||
insert_atomic(&s);
|
||||
if &s == wordsz {
|
||||
insert_atomic("ptr");
|
||||
}
|
||||
}
|
||||
}
|
||||
if atomic_cas {
|
||||
ret.insert((sym::target_has_atomic, Some(Symbol::intern("cas"))));
|
||||
}
|
||||
if sess.opts.debug_assertions {
|
||||
ret.insert((Symbol::intern("debug_assertions"), None));
|
||||
}
|
||||
|
|
|
@ -12,7 +12,9 @@ use crate::ops::{Deref, DerefMut};
|
|||
use crate::panicking;
|
||||
use crate::ptr::{Unique, NonNull};
|
||||
use crate::rc::Rc;
|
||||
use crate::sync::{Arc, Mutex, RwLock, atomic};
|
||||
use crate::sync::{Arc, Mutex, RwLock};
|
||||
#[cfg(not(bootstrap))]
|
||||
use crate::sync::atomic;
|
||||
use crate::task::{Context, Poll};
|
||||
use crate::thread::Result;
|
||||
|
||||
|
@ -240,49 +242,49 @@ impl<T: ?Sized> RefUnwindSafe for Mutex<T> {}
|
|||
#[stable(feature = "unwind_safe_lock_refs", since = "1.12.0")]
|
||||
impl<T: ?Sized> RefUnwindSafe for RwLock<T> {}
|
||||
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[cfg(target_has_atomic_load_store = "ptr")]
|
||||
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
|
||||
impl RefUnwindSafe for atomic::AtomicIsize {}
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg(target_has_atomic_load_store = "8")]
|
||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||
impl RefUnwindSafe for atomic::AtomicI8 {}
|
||||
#[cfg(target_has_atomic = "16")]
|
||||
#[cfg(target_has_atomic_load_store = "16")]
|
||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||
impl RefUnwindSafe for atomic::AtomicI16 {}
|
||||
#[cfg(target_has_atomic = "32")]
|
||||
#[cfg(target_has_atomic_load_store = "32")]
|
||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||
impl RefUnwindSafe for atomic::AtomicI32 {}
|
||||
#[cfg(target_has_atomic = "64")]
|
||||
#[cfg(target_has_atomic_load_store = "64")]
|
||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||
impl RefUnwindSafe for atomic::AtomicI64 {}
|
||||
#[cfg(target_has_atomic = "128")]
|
||||
#[cfg(target_has_atomic_load_store = "128")]
|
||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||
impl RefUnwindSafe for atomic::AtomicI128 {}
|
||||
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[cfg(target_has_atomic_load_store = "ptr")]
|
||||
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
|
||||
impl RefUnwindSafe for atomic::AtomicUsize {}
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg(target_hastarget_has_atomic_load_store_atomic = "8")]
|
||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||
impl RefUnwindSafe for atomic::AtomicU8 {}
|
||||
#[cfg(target_has_atomic = "16")]
|
||||
#[cfg(target_has_atomic_load_store = "16")]
|
||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||
impl RefUnwindSafe for atomic::AtomicU16 {}
|
||||
#[cfg(target_has_atomic = "32")]
|
||||
#[cfg(target_has_atomic_load_store = "32")]
|
||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||
impl RefUnwindSafe for atomic::AtomicU32 {}
|
||||
#[cfg(target_has_atomic = "64")]
|
||||
#[cfg(target_has_atomic_load_store = "64")]
|
||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||
impl RefUnwindSafe for atomic::AtomicU64 {}
|
||||
#[cfg(target_has_atomic = "128")]
|
||||
#[cfg(target_has_atomic_load_store = "128")]
|
||||
#[unstable(feature = "integer_atomics", issue = "32976")]
|
||||
impl RefUnwindSafe for atomic::AtomicU128 {}
|
||||
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
#[cfg(target_has_atomic_load_store = "8")]
|
||||
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
|
||||
impl RefUnwindSafe for atomic::AtomicBool {}
|
||||
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[cfg(target_has_atomic_load_store = "ptr")]
|
||||
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
|
||||
impl<T> RefUnwindSafe for atomic::AtomicPtr<T> {}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ const GATED_CFGS: &[(Symbol, Symbol, GateFn)] = &[
|
|||
// (name in cfg, feature, function to check if the feature is enabled)
|
||||
(sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
|
||||
(sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
|
||||
(sym::target_has_atomic_load_store, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
|
||||
(sym::rustdoc, sym::doc_cfg, cfg_fn!(doc_cfg)),
|
||||
(sym::doctest, sym::cfg_doctest, cfg_fn!(cfg_doctest)),
|
||||
];
|
||||
|
|
|
@ -658,6 +658,7 @@ symbols! {
|
|||
suggestion,
|
||||
target_feature,
|
||||
target_has_atomic,
|
||||
target_has_atomic_load_store,
|
||||
target_thread_local,
|
||||
task,
|
||||
tbm_target_feature,
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
|
||||
# The target used below doesn't support atomic CAS operations. Verify that's the case
|
||||
all:
|
||||
$(RUSTC) --print cfg --target thumbv6m-none-eabi | $(CGREP) -v 'target_has_atomic="cas"'
|
||||
$(RUSTC) --print cfg --target thumbv6m-none-eabi | $(CGREP) -v 'target_has_atomic="ptr"'
|
||||
|
|
Loading…
Add table
Reference in a new issue