From bbf688a84de7001d033764b848a50cbad42f3d5a Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 30 Jun 2018 14:56:08 -0500 Subject: [PATCH 1/3] enable Atomic*.{load,store} for ARMv6-M / MSP430 closes #45085 this commit adds an `atomic_cas` target option and an unstable `#[cfg(target_has_atomic_cas)]` attribute to enable a subset of the `Atomic*` API on architectures that don't support atomic CAS natively, like MSP430 and ARMv6-M. --- src/liballoc/lib.rs | 4 +++- src/liballoc/task.rs | 9 ++++++--- src/libcore/lib.rs | 1 + src/libcore/sync/atomic.rs | 16 ++++++++++++++++ src/librustc/session/config.rs | 4 ++++ src/librustc_target/spec/mod.rs | 6 ++++++ src/librustc_target/spec/msp430_none_elf.rs | 6 ++++-- src/librustc_target/spec/thumbv6m_none_eabi.rs | 2 +- src/libsyntax/feature_gate.rs | 4 ++++ 9 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 493448eaf88fa..66bf8de1993a3 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -86,6 +86,7 @@ #![feature(box_patterns)] #![feature(box_syntax)] #![feature(cfg_target_has_atomic)] +#![cfg_attr(not(stage0), feature(cfg_target_has_atomic_cas))] #![feature(coerce_unsized)] #![feature(collections_range)] #![feature(const_fn)] @@ -162,7 +163,8 @@ mod boxed { #[cfg(test)] mod boxed_test; pub mod collections; -#[cfg(target_has_atomic = "ptr")] +#[cfg_attr(stage0, cfg(target_has_atomic = "ptr"))] +#[cfg_attr(not(stage0), cfg(all(target_has_atomic = "ptr", target_has_atomic_cas)))] pub mod sync; pub mod rc; pub mod raw_vec; diff --git a/src/liballoc/task.rs b/src/liballoc/task.rs index f14fe3a20da93..c8e3e770ed2de 100644 --- a/src/liballoc/task.rs +++ b/src/liballoc/task.rs @@ -12,10 +12,12 @@ pub use core::task::*; -#[cfg(target_has_atomic = "ptr")] +#[cfg_attr(stage0, cfg(target_has_atomic = "ptr"))] +#[cfg_attr(not(stage0), cfg(all(target_has_atomic = "ptr", target_has_atomic_cas)))] pub use self::if_arc::*; -#[cfg(target_has_atomic = "ptr")] +#[cfg_attr(stage0, cfg(target_has_atomic = "ptr"))] +#[cfg_attr(not(stage0), cfg(all(target_has_atomic = "ptr", target_has_atomic_cas)))] mod if_arc { use super::*; use core::marker::PhantomData; @@ -47,7 +49,8 @@ mod if_arc { } } - #[cfg(target_has_atomic = "ptr")] + #[cfg_attr(stage0, cfg(target_has_atomic = "ptr"))] + #[cfg_attr(not(stage0), cfg(all(target_has_atomic = "ptr", target_has_atomic_cas)))] struct ArcWrapped(PhantomData); unsafe impl UnsafeWake for ArcWrapped { diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index b2b38820a89cc..fe328bdd10707 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -79,6 +79,7 @@ #![feature(associated_type_defaults)] #![feature(attr_literals)] #![feature(cfg_target_has_atomic)] +#![cfg_attr(not(stage0), feature(cfg_target_has_atomic_cas))] #![feature(concat_idents)] #![feature(const_fn)] #![feature(const_int_ops)] diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 7aba8b51cff51..647bf4fb40a38 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -371,6 +371,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] pub fn swap(&self, val: bool, order: Ordering) -> bool { unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 } } @@ -401,6 +402,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] 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, @@ -446,6 +448,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "extended_compare_and_swap", since = "1.10.0")] + #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] pub fn compare_exchange(&self, current: bool, new: bool, @@ -537,6 +540,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] pub fn fetch_and(&self, val: bool, order: Ordering) -> bool { unsafe { atomic_and(self.v.get(), val as u8, order) != 0 } } @@ -568,6 +572,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] 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 @@ -610,6 +615,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] pub fn fetch_or(&self, val: bool, order: Ordering) -> bool { unsafe { atomic_or(self.v.get(), val as u8, order) != 0 } } @@ -640,6 +646,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool { unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 } } @@ -786,6 +793,7 @@ impl AtomicPtr { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] 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 } } @@ -815,6 +823,7 @@ impl AtomicPtr { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] 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, @@ -853,6 +862,7 @@ impl AtomicPtr { /// ``` #[inline] #[stable(feature = "extended_compare_and_swap", since = "1.10.0")] + #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] pub fn compare_exchange(&self, current: *mut T, new: *mut T, @@ -1138,6 +1148,7 @@ assert_eq!(some_var.swap(10, Ordering::Relaxed), 5); ```"), #[inline] #[$stable] + #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type { unsafe { atomic_swap(self.v.get(), val, order) } } @@ -1170,6 +1181,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10); ```"), #[inline] #[$stable] + #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] pub fn compare_and_swap(&self, current: $int_type, new: $int_type, @@ -1223,6 +1235,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10); ```"), #[inline] #[$stable_cxchg] + #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] pub fn compare_exchange(&self, current: $int_type, new: $int_type, @@ -1677,6 +1690,7 @@ atomic_int!{ } #[inline] +#[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] fn strongest_failure_ordering(order: Ordering) -> Ordering { match order { Release => Relaxed, @@ -1713,6 +1727,7 @@ unsafe fn atomic_load(dst: *const T, order: Ordering) -> T { } #[inline] +#[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] unsafe fn atomic_swap(dst: *mut T, val: T, order: Ordering) -> T { match order { Acquire => intrinsics::atomic_xchg_acq(dst, val), @@ -1751,6 +1766,7 @@ unsafe fn atomic_sub(dst: *mut T, val: T, order: Ordering) -> T { } #[inline] +#[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] unsafe fn atomic_compare_exchange(dst: *mut T, old: T, new: T, diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index f97e11ef72f49..93bfe1fc63851 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1367,6 +1367,7 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig { let vendor = &sess.target.target.target_vendor; let min_atomic_width = sess.target.target.min_atomic_width(); let max_atomic_width = sess.target.target.max_atomic_width(); + let atomic_cas = sess.target.target.options.atomic_cas; let mut ret = HashSet::new(); // Target bindings. @@ -1406,6 +1407,9 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig { } } } + if atomic_cas { + ret.insert((Symbol::intern("target_has_atomic_cas"), None)); + } if sess.opts.debug_assertions { ret.insert((Symbol::intern("debug_assertions"), None)); } diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index e54cd773123c8..8ebf5f7c64deb 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -572,6 +572,9 @@ pub struct TargetOptions { /// Don't use this field; instead use the `.max_atomic_width()` method. pub max_atomic_width: Option, + /// Whether the target supports atomic CAS operations natively + pub atomic_cas: bool, + /// Panic strategy: "unwind" or "abort" pub panic_strategy: PanicStrategy, @@ -690,6 +693,7 @@ impl Default for TargetOptions { no_integrated_as: false, min_atomic_width: None, max_atomic_width: None, + atomic_cas: true, panic_strategy: PanicStrategy::Unwind, abi_blacklist: vec![], crt_static_allows_dylibs: false, @@ -946,6 +950,7 @@ impl Target { key!(no_integrated_as, bool); key!(max_atomic_width, Option); key!(min_atomic_width, Option); + key!(atomic_cas, bool); try!(key!(panic_strategy, PanicStrategy)); key!(crt_static_allows_dylibs, bool); key!(crt_static_default, bool); @@ -1154,6 +1159,7 @@ impl ToJson for Target { target_option_val!(no_integrated_as); target_option_val!(min_atomic_width); target_option_val!(max_atomic_width); + target_option_val!(atomic_cas); target_option_val!(panic_strategy); target_option_val!(crt_static_allows_dylibs); target_option_val!(crt_static_default); diff --git a/src/librustc_target/spec/msp430_none_elf.rs b/src/librustc_target/spec/msp430_none_elf.rs index ce42a908b0e43..291511dd42913 100644 --- a/src/librustc_target/spec/msp430_none_elf.rs +++ b/src/librustc_target/spec/msp430_none_elf.rs @@ -34,9 +34,11 @@ pub fn target() -> TargetResult { linker: Some("msp430-elf-gcc".to_string()), no_integrated_as: true, - // There are no atomic instructions available in the MSP430 + // There are no atomic CAS instructions available in the MSP430 // instruction set - max_atomic_width: Some(0), + max_atomic_width: Some(16), + + atomic_cas: false, // Because these devices have very little resources having an // unwinder is too onerous so we default to "abort" because the diff --git a/src/librustc_target/spec/thumbv6m_none_eabi.rs b/src/librustc_target/spec/thumbv6m_none_eabi.rs index 9fea07c36f4ef..0c45178b47a5b 100644 --- a/src/librustc_target/spec/thumbv6m_none_eabi.rs +++ b/src/librustc_target/spec/thumbv6m_none_eabi.rs @@ -31,7 +31,7 @@ pub fn target() -> TargetResult { features: "+strict-align".to_string(), // There are no atomic instructions available in the instruction set of the ARMv6-M // architecture - max_atomic_width: Some(0), + atomic_cas: false, .. super::thumb_base::opts() } }) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 2ae0e669fd031..59418f8bf2abb 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -479,6 +479,9 @@ declare_features! ( // Allows async and await syntax (active, async_await, "1.28.0", Some(50547), None), + + // Allows async and await syntax + (active, cfg_target_has_atomic_cas, "1.28.0", Some(0), None), ); declare_features! ( @@ -1099,6 +1102,7 @@ const GATED_CFGS: &[(&str, &str, fn(&Features) -> bool)] = &[ ("target_vendor", "cfg_target_vendor", cfg_fn!(cfg_target_vendor)), ("target_thread_local", "cfg_target_thread_local", cfg_fn!(cfg_target_thread_local)), ("target_has_atomic", "cfg_target_has_atomic", cfg_fn!(cfg_target_has_atomic)), + ("target_has_atomic_cas", "cfg_target_has_atomic_cas", cfg_fn!(cfg_target_has_atomic_cas)), ]; #[derive(Debug, Eq, PartialEq)] From 0ed32313a223dbe1a1d5f61cd66d533992e26f6d Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 5 Jul 2018 16:44:13 -0500 Subject: [PATCH 2/3] #[cfg(target_has_atomic_cas)] -> #[cfg(target_has_atomic = "cas")] --- src/liballoc/lib.rs | 7 ++-- src/liballoc/task.rs | 18 +++++++---- src/libcore/lib.rs | 1 - src/libcore/sync/atomic.rs | 32 +++++++++---------- src/librustc/session/config.rs | 2 +- src/librustc_target/spec/msp430_none_elf.rs | 1 - .../spec/thumbv6m_none_eabi.rs | 2 +- src/libsyntax/feature_gate.rs | 4 --- 8 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 66bf8de1993a3..35bf8d1b792f9 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -86,7 +86,6 @@ #![feature(box_patterns)] #![feature(box_syntax)] #![feature(cfg_target_has_atomic)] -#![cfg_attr(not(stage0), feature(cfg_target_has_atomic_cas))] #![feature(coerce_unsized)] #![feature(collections_range)] #![feature(const_fn)] @@ -163,8 +162,10 @@ mod boxed { #[cfg(test)] mod boxed_test; pub mod collections; -#[cfg_attr(stage0, cfg(target_has_atomic = "ptr"))] -#[cfg_attr(not(stage0), cfg(all(target_has_atomic = "ptr", target_has_atomic_cas)))] +#[cfg(any( + all(stage0, target_has_atomic = "ptr"), + all(not(stage0), target_has_atomic = "ptr", target_has_atomic = "cas") +))] pub mod sync; pub mod rc; pub mod raw_vec; diff --git a/src/liballoc/task.rs b/src/liballoc/task.rs index c8e3e770ed2de..9792d52dd66d2 100644 --- a/src/liballoc/task.rs +++ b/src/liballoc/task.rs @@ -12,12 +12,16 @@ pub use core::task::*; -#[cfg_attr(stage0, cfg(target_has_atomic = "ptr"))] -#[cfg_attr(not(stage0), cfg(all(target_has_atomic = "ptr", target_has_atomic_cas)))] +#[cfg(any( + all(stage0, target_has_atomic = "ptr"), + all(not(stage0), target_has_atomic = "ptr", target_has_atomic = "cas") +))] pub use self::if_arc::*; -#[cfg_attr(stage0, cfg(target_has_atomic = "ptr"))] -#[cfg_attr(not(stage0), cfg(all(target_has_atomic = "ptr", target_has_atomic_cas)))] +#[cfg(any( + all(stage0, target_has_atomic = "ptr"), + all(not(stage0), target_has_atomic = "ptr", target_has_atomic = "cas") +))] mod if_arc { use super::*; use core::marker::PhantomData; @@ -49,8 +53,10 @@ mod if_arc { } } - #[cfg_attr(stage0, cfg(target_has_atomic = "ptr"))] - #[cfg_attr(not(stage0), cfg(all(target_has_atomic = "ptr", target_has_atomic_cas)))] + #[cfg(any( + all(stage0, target_has_atomic = "ptr"), + all(not(stage0), target_has_atomic = "ptr", target_has_atomic = "cas") + ))] struct ArcWrapped(PhantomData); unsafe impl UnsafeWake for ArcWrapped { diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index fe328bdd10707..b2b38820a89cc 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -79,7 +79,6 @@ #![feature(associated_type_defaults)] #![feature(attr_literals)] #![feature(cfg_target_has_atomic)] -#![cfg_attr(not(stage0), feature(cfg_target_has_atomic_cas))] #![feature(concat_idents)] #![feature(const_fn)] #![feature(const_int_ops)] diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 647bf4fb40a38..e9d1fb8911504 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -371,7 +371,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] + #[cfg(any(stage0, target_has_atomic = "cas"))] pub fn swap(&self, val: bool, order: Ordering) -> bool { unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 } } @@ -402,7 +402,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] + #[cfg(any(stage0, target_has_atomic = "cas"))] 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, @@ -448,7 +448,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "extended_compare_and_swap", since = "1.10.0")] - #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] + #[cfg(any(stage0, target_has_atomic = "cas"))] pub fn compare_exchange(&self, current: bool, new: bool, @@ -540,7 +540,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] + #[cfg(any(stage0, target_has_atomic = "cas"))] pub fn fetch_and(&self, val: bool, order: Ordering) -> bool { unsafe { atomic_and(self.v.get(), val as u8, order) != 0 } } @@ -572,7 +572,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] + #[cfg(any(stage0, target_has_atomic = "cas"))] 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 @@ -615,7 +615,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] + #[cfg(any(stage0, target_has_atomic = "cas"))] pub fn fetch_or(&self, val: bool, order: Ordering) -> bool { unsafe { atomic_or(self.v.get(), val as u8, order) != 0 } } @@ -646,7 +646,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] + #[cfg(any(stage0, target_has_atomic = "cas"))] pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool { unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 } } @@ -793,7 +793,7 @@ impl AtomicPtr { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] + #[cfg(any(stage0, target_has_atomic = "cas"))] 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 } } @@ -823,7 +823,7 @@ impl AtomicPtr { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] + #[cfg(any(stage0, target_has_atomic = "cas"))] 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, @@ -862,7 +862,7 @@ impl AtomicPtr { /// ``` #[inline] #[stable(feature = "extended_compare_and_swap", since = "1.10.0")] - #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] + #[cfg(any(stage0, target_has_atomic = "cas"))] pub fn compare_exchange(&self, current: *mut T, new: *mut T, @@ -1148,7 +1148,7 @@ assert_eq!(some_var.swap(10, Ordering::Relaxed), 5); ```"), #[inline] #[$stable] - #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] + #[cfg(any(stage0, target_has_atomic = "cas"))] pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type { unsafe { atomic_swap(self.v.get(), val, order) } } @@ -1181,7 +1181,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10); ```"), #[inline] #[$stable] - #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] + #[cfg(any(stage0, target_has_atomic = "cas"))] pub fn compare_and_swap(&self, current: $int_type, new: $int_type, @@ -1235,7 +1235,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10); ```"), #[inline] #[$stable_cxchg] - #[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] + #[cfg(any(stage0, target_has_atomic = "cas"))] pub fn compare_exchange(&self, current: $int_type, new: $int_type, @@ -1690,7 +1690,7 @@ atomic_int!{ } #[inline] -#[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] +#[cfg(any(stage0, target_has_atomic = "cas"))] fn strongest_failure_ordering(order: Ordering) -> Ordering { match order { Release => Relaxed, @@ -1727,7 +1727,7 @@ unsafe fn atomic_load(dst: *const T, order: Ordering) -> T { } #[inline] -#[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] +#[cfg(any(stage0, target_has_atomic = "cas"))] unsafe fn atomic_swap(dst: *mut T, val: T, order: Ordering) -> T { match order { Acquire => intrinsics::atomic_xchg_acq(dst, val), @@ -1766,7 +1766,7 @@ unsafe fn atomic_sub(dst: *mut T, val: T, order: Ordering) -> T { } #[inline] -#[cfg_attr(not(stage0), cfg(target_has_atomic_cas))] +#[cfg(any(stage0, target_has_atomic = "cas"))] unsafe fn atomic_compare_exchange(dst: *mut T, old: T, new: T, diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 93bfe1fc63851..342799d41bb56 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1408,7 +1408,7 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig { } } if atomic_cas { - ret.insert((Symbol::intern("target_has_atomic_cas"), None)); + ret.insert((Symbol::intern("target_has_atomic"), Some(Symbol::intern("cas")))); } if sess.opts.debug_assertions { ret.insert((Symbol::intern("debug_assertions"), None)); diff --git a/src/librustc_target/spec/msp430_none_elf.rs b/src/librustc_target/spec/msp430_none_elf.rs index 291511dd42913..3ac4c459c6384 100644 --- a/src/librustc_target/spec/msp430_none_elf.rs +++ b/src/librustc_target/spec/msp430_none_elf.rs @@ -37,7 +37,6 @@ pub fn target() -> TargetResult { // There are no atomic CAS instructions available in the MSP430 // instruction set max_atomic_width: Some(16), - atomic_cas: false, // Because these devices have very little resources having an diff --git a/src/librustc_target/spec/thumbv6m_none_eabi.rs b/src/librustc_target/spec/thumbv6m_none_eabi.rs index 0c45178b47a5b..26812501814f5 100644 --- a/src/librustc_target/spec/thumbv6m_none_eabi.rs +++ b/src/librustc_target/spec/thumbv6m_none_eabi.rs @@ -29,7 +29,7 @@ pub fn target() -> TargetResult { // The ARMv6-M architecture doesn't support unaligned loads/stores so we disable them // with +strict-align. features: "+strict-align".to_string(), - // There are no atomic instructions available in the instruction set of the ARMv6-M + // There are no atomic CAS instructions available in the instruction set of the ARMv6-M // architecture atomic_cas: false, .. super::thumb_base::opts() diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 59418f8bf2abb..2ae0e669fd031 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -479,9 +479,6 @@ declare_features! ( // Allows async and await syntax (active, async_await, "1.28.0", Some(50547), None), - - // Allows async and await syntax - (active, cfg_target_has_atomic_cas, "1.28.0", Some(0), None), ); declare_features! ( @@ -1102,7 +1099,6 @@ const GATED_CFGS: &[(&str, &str, fn(&Features) -> bool)] = &[ ("target_vendor", "cfg_target_vendor", cfg_fn!(cfg_target_vendor)), ("target_thread_local", "cfg_target_thread_local", cfg_fn!(cfg_target_thread_local)), ("target_has_atomic", "cfg_target_has_atomic", cfg_fn!(cfg_target_has_atomic)), - ("target_has_atomic_cas", "cfg_target_has_atomic_cas", cfg_fn!(cfg_target_has_atomic_cas)), ]; #[derive(Debug, Eq, PartialEq)] From f9145d01e16d98b7dc969b66ffb6068df9cdd01d Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 5 Jul 2018 20:18:19 -0500 Subject: [PATCH 3/3] update run-pass test --- .../run-make-fulldeps/target-without-atomic-cas/Makefile | 5 +++++ src/test/run-make-fulldeps/target-without-atomics/Makefile | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 src/test/run-make-fulldeps/target-without-atomic-cas/Makefile delete mode 100644 src/test/run-make-fulldeps/target-without-atomics/Makefile diff --git a/src/test/run-make-fulldeps/target-without-atomic-cas/Makefile b/src/test/run-make-fulldeps/target-without-atomic-cas/Makefile new file mode 100644 index 0000000000000..c2eb4caea2635 --- /dev/null +++ b/src/test/run-make-fulldeps/target-without-atomic-cas/Makefile @@ -0,0 +1,5 @@ +-include ../tools.mk + +# 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"' diff --git a/src/test/run-make-fulldeps/target-without-atomics/Makefile b/src/test/run-make-fulldeps/target-without-atomics/Makefile deleted file mode 100644 index c5f575ddf84c6..0000000000000 --- a/src/test/run-make-fulldeps/target-without-atomics/Makefile +++ /dev/null @@ -1,5 +0,0 @@ --include ../tools.mk - -# The target used below doesn't support atomic operations. Verify that's the case -all: - $(RUSTC) --print cfg --target thumbv6m-none-eabi | $(CGREP) -v target_has_atomic