diff options
| author | Ralf Jung <post@ralfj.de> | 2025-05-24 16:35:20 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2025-05-28 22:57:55 +0200 |
| commit | 4794ea176be0d61f3ac08c367971c032e7abe7af (patch) | |
| tree | 41f4d9eeb2185a14f67ef01baf65b804f463028d /library | |
| parent | 6f69710780d579b180ab38da4c1384d630f7bd31 (diff) | |
| download | rust-4794ea176be0d61f3ac08c367971c032e7abe7af.tar.gz rust-4794ea176be0d61f3ac08c367971c032e7abe7af.zip | |
atomic_load intrinsic: use const generic parameter for ordering
Diffstat (limited to 'library')
| -rw-r--r-- | library/core/src/intrinsics/mod.rs | 30 | ||||
| -rw-r--r-- | library/core/src/sync/atomic.rs | 18 |
2 files changed, 46 insertions, 2 deletions
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 32642a13b42..8a0f80f8ce7 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -30,7 +30,7 @@ //! //! The atomic intrinsics provide common atomic operations on machine //! words, with multiple possible memory orderings. See the -//! [atomic types][crate::sync::atomic] docs for details. +//! [atomic types][atomic] docs for details. //! //! # Unwinding //! @@ -50,7 +50,7 @@ )] #![allow(missing_docs)] -use crate::marker::{DiscriminantKind, Tuple}; +use crate::marker::{ConstParamTy, DiscriminantKind, Tuple}; use crate::ptr; pub mod fallback; @@ -62,6 +62,20 @@ pub mod simd; #[cfg(all(target_has_atomic = "8", target_has_atomic = "32", target_has_atomic = "ptr"))] use crate::sync::atomic::{self, AtomicBool, AtomicI32, AtomicIsize, AtomicU32, Ordering}; +/// A type for atomic ordering parameters for intrinsics. This is a separate type from +/// `atomic::Ordering` so that we can make it `ConstParamTy` and fix the values used here without a +/// risk of leaking that to stable code. +#[derive(Debug, ConstParamTy, PartialEq, Eq)] +pub enum AtomicOrdering { + // These values must match the compiler's `AtomicOrdering` defined in + // `rustc_middle/src/ty/consts/int.rs`! + Relaxed = 0, + Release = 1, + Acquire = 2, + AcqRel = 3, + SeqCst = 4, +} + // N.B., these intrinsics take raw pointers because they mutate aliased // memory, which is not valid for either `&` or `&mut`. @@ -395,10 +409,20 @@ pub unsafe fn atomic_cxchgweak_seqcst_seqcst<T: Copy>(dst: *mut T, old: T, src: /// `T` must be an integer or pointer type. /// /// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `load` method. For example, [`AtomicBool::load`]. +#[rustc_intrinsic] +#[rustc_nounwind] +#[cfg(not(bootstrap))] +pub unsafe fn atomic_load<T: Copy, const ORD: AtomicOrdering>(src: *const T) -> T; +/// Loads the current value of the pointer. +/// `T` must be an integer or pointer type. +/// +/// The stabilized version of this intrinsic is available on the /// [`atomic`] types via the `load` method by passing /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::load`]. #[rustc_intrinsic] #[rustc_nounwind] +#[cfg(bootstrap)] pub unsafe fn atomic_load_seqcst<T: Copy>(src: *const T) -> T; /// Loads the current value of the pointer. /// `T` must be an integer or pointer type. @@ -408,6 +432,7 @@ pub unsafe fn atomic_load_seqcst<T: Copy>(src: *const T) -> T; /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::load`]. #[rustc_intrinsic] #[rustc_nounwind] +#[cfg(bootstrap)] pub unsafe fn atomic_load_acquire<T: Copy>(src: *const T) -> T; /// Loads the current value of the pointer. /// `T` must be an integer or pointer type. @@ -417,6 +442,7 @@ pub unsafe fn atomic_load_acquire<T: Copy>(src: *const T) -> T; /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::load`]. #[rustc_intrinsic] #[rustc_nounwind] +#[cfg(bootstrap)] pub unsafe fn atomic_load_relaxed<T: Copy>(src: *const T) -> T; /// Stores the value at the specified memory location. diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index bd5a58d74ba..a3fbc71162b 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -3822,6 +3822,7 @@ unsafe fn atomic_store<T: Copy>(dst: *mut T, val: T, order: Ordering) { #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +#[cfg(bootstrap)] unsafe fn atomic_load<T: Copy>(dst: *const T, order: Ordering) -> T { // SAFETY: the caller must uphold the safety contract for `atomic_load`. unsafe { @@ -3836,6 +3837,23 @@ unsafe fn atomic_load<T: Copy>(dst: *const T, order: Ordering) -> T { } #[inline] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +#[cfg(not(bootstrap))] +unsafe fn atomic_load<T: Copy>(dst: *const T, order: Ordering) -> T { + use intrinsics::AtomicOrdering; + // SAFETY: the caller must uphold the safety contract for `atomic_load`. + unsafe { + match order { + Relaxed => intrinsics::atomic_load::<T, { AtomicOrdering::Relaxed }>(dst), + Acquire => intrinsics::atomic_load::<T, { AtomicOrdering::Acquire }>(dst), + SeqCst => intrinsics::atomic_load::<T, { AtomicOrdering::SeqCst }>(dst), + Release => panic!("there is no such thing as a release load"), + AcqRel => panic!("there is no such thing as an acquire-release load"), + } + } +} + +#[inline] #[cfg(target_has_atomic)] #[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 { |
