Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enable Atomic*.{load,store} for ARMv6-M / MSP430 #51953

Merged
merged 3 commits into from
Jul 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/liballoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,10 @@ mod boxed {
#[cfg(test)]
mod boxed_test;
pub mod collections;
#[cfg(target_has_atomic = "ptr")]
#[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;
Expand Down
15 changes: 12 additions & 3 deletions src/liballoc/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,16 @@

pub use core::task::*;

#[cfg(target_has_atomic = "ptr")]
#[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(target_has_atomic = "ptr")]
#[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;
Expand Down Expand Up @@ -47,7 +53,10 @@ mod if_arc {
}
}

#[cfg(target_has_atomic = "ptr")]
#[cfg(any(
all(stage0, target_has_atomic = "ptr"),
all(not(stage0), target_has_atomic = "ptr", target_has_atomic = "cas")
))]
struct ArcWrapped<T>(PhantomData<T>);

unsafe impl<T: Wake + 'static> UnsafeWake for ArcWrapped<T> {
Expand Down
16 changes: 16 additions & 0 deletions src/libcore/sync/atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ impl AtomicBool {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[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 }
}
Expand Down Expand Up @@ -401,6 +402,7 @@ impl AtomicBool {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[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,
Expand Down Expand Up @@ -446,6 +448,7 @@ impl AtomicBool {
/// ```
#[inline]
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
#[cfg(any(stage0, target_has_atomic = "cas"))]
pub fn compare_exchange(&self,
current: bool,
new: bool,
Expand Down Expand Up @@ -537,6 +540,7 @@ impl AtomicBool {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[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 }
}
Expand Down Expand Up @@ -568,6 +572,7 @@ impl AtomicBool {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[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
Expand Down Expand Up @@ -610,6 +615,7 @@ impl AtomicBool {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[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 }
}
Expand Down Expand Up @@ -640,6 +646,7 @@ impl AtomicBool {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[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 }
}
Expand Down Expand Up @@ -786,6 +793,7 @@ impl<T> AtomicPtr<T> {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[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 }
}
Expand Down Expand Up @@ -815,6 +823,7 @@ impl<T> AtomicPtr<T> {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[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,
Expand Down Expand Up @@ -853,6 +862,7 @@ impl<T> AtomicPtr<T> {
/// ```
#[inline]
#[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
#[cfg(any(stage0, target_has_atomic = "cas"))]
pub fn compare_exchange(&self,
current: *mut T,
new: *mut T,
Expand Down Expand Up @@ -1138,6 +1148,7 @@ assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
```"),
#[inline]
#[$stable]
#[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) }
}
Expand Down Expand Up @@ -1170,6 +1181,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10);
```"),
#[inline]
#[$stable]
#[cfg(any(stage0, target_has_atomic = "cas"))]
pub fn compare_and_swap(&self,
current: $int_type,
new: $int_type,
Expand Down Expand Up @@ -1223,6 +1235,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10);
```"),
#[inline]
#[$stable_cxchg]
#[cfg(any(stage0, target_has_atomic = "cas"))]
pub fn compare_exchange(&self,
current: $int_type,
new: $int_type,
Expand Down Expand Up @@ -1677,6 +1690,7 @@ atomic_int!{
}

#[inline]
#[cfg(any(stage0, target_has_atomic = "cas"))]
fn strongest_failure_ordering(order: Ordering) -> Ordering {
match order {
Release => Relaxed,
Expand Down Expand Up @@ -1713,6 +1727,7 @@ unsafe fn atomic_load<T>(dst: *const T, order: Ordering) -> T {
}

#[inline]
#[cfg(any(stage0, target_has_atomic = "cas"))]
unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T {
match order {
Acquire => intrinsics::atomic_xchg_acq(dst, val),
Expand Down Expand Up @@ -1751,6 +1766,7 @@ unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T {
}

#[inline]
#[cfg(any(stage0, target_has_atomic = "cas"))]
unsafe fn atomic_compare_exchange<T>(dst: *mut T,
old: T,
new: T,
Expand Down
4 changes: 4 additions & 0 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -1406,6 +1407,9 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
}
}
}
if atomic_cas {
ret.insert((Symbol::intern("target_has_atomic"), Some(Symbol::intern("cas"))));
}
if sess.opts.debug_assertions {
ret.insert((Symbol::intern("debug_assertions"), None));
}
Expand Down
6 changes: 6 additions & 0 deletions src/librustc_target/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,9 @@ pub struct TargetOptions {
/// Don't use this field; instead use the `.max_atomic_width()` method.
pub max_atomic_width: Option<u64>,

/// Whether the target supports atomic CAS operations natively
pub atomic_cas: bool,

/// Panic strategy: "unwind" or "abort"
pub panic_strategy: PanicStrategy,

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -946,6 +950,7 @@ impl Target {
key!(no_integrated_as, bool);
key!(max_atomic_width, Option<u64>);
key!(min_atomic_width, Option<u64>);
key!(atomic_cas, bool);
try!(key!(panic_strategy, PanicStrategy));
key!(crt_static_allows_dylibs, bool);
key!(crt_static_default, bool);
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 3 additions & 2 deletions src/librustc_target/spec/msp430_none_elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ 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
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_target/spec/thumbv6m_none_eabi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ 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
max_atomic_width: Some(0),
atomic_cas: false,
.. super::thumb_base::opts()
}
})
Expand Down
5 changes: 5 additions & 0 deletions src/test/run-make-fulldeps/target-without-atomic-cas/Makefile
Original file line number Diff line number Diff line change
@@ -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"'
5 changes: 0 additions & 5 deletions src/test/run-make-fulldeps/target-without-atomics/Makefile

This file was deleted.