Skip to content

Commit

Permalink
Rollup merge of rust-lang#106856 - vadorovsky:fix-atomic-annotations,…
Browse files Browse the repository at this point in the history
… r=joshtriplett

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

Before this change, the following functions and macros were annotated with `#[cfg(target_has_atomic = "8")]` or
`#[cfg(target_has_atomic_load_store = "8")]`:

* `atomic_int`
* `strongest_failure_ordering`
* `atomic_swap`
* `atomic_add`
* `atomic_sub`
* `atomic_compare_exchange`
* `atomic_compare_exchange_weak`
* `atomic_and`
* `atomic_nand`
* `atomic_or`
* `atomic_xor`
* `atomic_max`
* `atomic_min`
* `atomic_umax`
* `atomic_umin`

However, none of those functions and macros actually depend on 8-bit width and they are needed for all atomic widths (16-bit, 32-bit, 64-bit etc.). Some targets might not support 8-bit atomics (i.e. BPF, if we would enable atomic CAS for it).

This change fixes that by removing the `"8"` argument from annotations, which results in accepting the whole variety of widths.

Fixes rust-lang#106845
Fixes rust-lang#106795

Signed-off-by: Michal Rostecki <vadorovsky@gmail.com>
  • Loading branch information
JohnTitor committed Jan 27, 2023
2 parents a5a8b48 + 474ea87 commit a4e6bb0
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 15 deletions.
8 changes: 8 additions & 0 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,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 @@ -953,6 +954,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 @@ -969,6 +971,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));
}
}

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"))]
#[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

0 comments on commit a4e6bb0

Please sign in to comment.