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

core: Support variety of atomic widths in width-agnostic functions #106856

Merged
merged 2 commits into from
Jan 27, 2023
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
8 changes: 8 additions & 0 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
if sess.target.has_thread_local {
ret.insert((sym::target_thread_local, None));
}
let mut has_atomic = false;
for (i, align) in [
(8, layout.i8_align.abi),
(16, layout.i16_align.abi),
Expand All @@ -965,6 +966,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
(128, layout.i128_align.abi),
] {
if i >= min_atomic_width && i <= max_atomic_width {
has_atomic = true;
let mut insert_atomic = |s, align: Align| {
ret.insert((sym::target_has_atomic_load_store, Some(Symbol::intern(s))));
if atomic_cas {
Expand All @@ -981,6 +983,12 @@ fn default_configuration(sess: &Session) -> CrateConfig {
}
}
}
if sess.is_nightly_build() && has_atomic {
ret.insert((sym::target_has_atomic_load_store, None));
if atomic_cas {
ret.insert((sym::target_has_atomic, None));
vadorovsky marked this conversation as resolved.
Show resolved Hide resolved
}
}

let panic_strategy = sess.panic_strategy();
ret.insert((sym::panic, Some(panic_strategy.desc_symbol())));
Expand Down
45 changes: 30 additions & 15 deletions library/core/src/sync/atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1861,7 +1861,8 @@ macro_rules! if_not_8_bit {
($_:ident, $($tt:tt)*) => { $($tt)* };
}

#[cfg(target_has_atomic_load_store = "8")]
#[cfg_attr(not(bootstrap), cfg(target_has_atomic_load_store))]
#[cfg_attr(bootstrap, cfg(target_has_atomic_load_store = "8"))]
macro_rules! atomic_int {
($cfg_cas:meta,
$cfg_align:meta,
Expand Down Expand Up @@ -2988,7 +2989,8 @@ atomic_int_ptr_sized! {
}

#[inline]
#[cfg(target_has_atomic = "8")]
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
fn strongest_failure_ordering(order: Ordering) -> Ordering {
match order {
Release => Relaxed,
Expand Down Expand Up @@ -3030,7 +3032,8 @@ unsafe fn atomic_load<T: Copy>(dst: *const T, order: Ordering) -> T {
}

#[inline]
#[cfg(target_has_atomic = "8")]
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
unsafe fn atomic_swap<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
// SAFETY: the caller must uphold the safety contract for `atomic_swap`.
Expand All @@ -3047,7 +3050,8 @@ unsafe fn atomic_swap<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {

/// Returns the previous value (like __sync_fetch_and_add).
#[inline]
#[cfg(target_has_atomic = "8")]
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
unsafe fn atomic_add<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
// SAFETY: the caller must uphold the safety contract for `atomic_add`.
Expand All @@ -3064,7 +3068,8 @@ unsafe fn atomic_add<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {

/// Returns the previous value (like __sync_fetch_and_sub).
#[inline]
#[cfg(target_has_atomic = "8")]
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
unsafe fn atomic_sub<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
// SAFETY: the caller must uphold the safety contract for `atomic_sub`.
Expand All @@ -3080,7 +3085,8 @@ unsafe fn atomic_sub<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
}

#[inline]
#[cfg(target_has_atomic = "8")]
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
unsafe fn atomic_compare_exchange<T: Copy>(
dst: *mut T,
Expand Down Expand Up @@ -3115,7 +3121,8 @@ unsafe fn atomic_compare_exchange<T: Copy>(
}

#[inline]
#[cfg(target_has_atomic = "8")]
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
unsafe fn atomic_compare_exchange_weak<T: Copy>(
dst: *mut T,
Expand Down Expand Up @@ -3150,7 +3157,8 @@ unsafe fn atomic_compare_exchange_weak<T: Copy>(
}

#[inline]
#[cfg(target_has_atomic = "8")]
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
unsafe fn atomic_and<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
// SAFETY: the caller must uphold the safety contract for `atomic_and`
Expand All @@ -3166,7 +3174,8 @@ unsafe fn atomic_and<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
}

#[inline]
#[cfg(target_has_atomic = "8")]
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
unsafe fn atomic_nand<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
// SAFETY: the caller must uphold the safety contract for `atomic_nand`
Expand All @@ -3182,7 +3191,8 @@ unsafe fn atomic_nand<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
}

#[inline]
#[cfg(target_has_atomic = "8")]
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
unsafe fn atomic_or<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
// SAFETY: the caller must uphold the safety contract for `atomic_or`
Expand All @@ -3198,7 +3208,8 @@ unsafe fn atomic_or<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
}

#[inline]
#[cfg(target_has_atomic = "8")]
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
unsafe fn atomic_xor<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
// SAFETY: the caller must uphold the safety contract for `atomic_xor`
Expand All @@ -3215,7 +3226,8 @@ unsafe fn atomic_xor<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {

/// returns the max value (signed comparison)
#[inline]
#[cfg(target_has_atomic = "8")]
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
unsafe fn atomic_max<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
// SAFETY: the caller must uphold the safety contract for `atomic_max`
Expand All @@ -3232,7 +3244,8 @@ unsafe fn atomic_max<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {

/// returns the min value (signed comparison)
#[inline]
#[cfg(target_has_atomic = "8")]
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
unsafe fn atomic_min<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
// SAFETY: the caller must uphold the safety contract for `atomic_min`
Expand All @@ -3249,7 +3262,8 @@ unsafe fn atomic_min<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {

/// returns the max value (unsigned comparison)
#[inline]
#[cfg(target_has_atomic = "8")]
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
unsafe fn atomic_umax<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
// SAFETY: the caller must uphold the safety contract for `atomic_umax`
Expand All @@ -3266,7 +3280,8 @@ unsafe fn atomic_umax<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {

/// returns the min value (unsigned comparison)
#[inline]
#[cfg(target_has_atomic = "8")]
#[cfg_attr(not(bootstrap), cfg(target_has_atomic))]
#[cfg_attr(bootstrap, cfg(target_has_atomic = "8"))]
bjorn3 marked this conversation as resolved.
Show resolved Hide resolved
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
unsafe fn atomic_umin<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
// SAFETY: the caller must uphold the safety contract for `atomic_umin`
Expand Down