Skip to main content

core/sync/
atomic.rs

1//! Atomic types
2//!
3//! Atomic types provide primitive shared-memory communication between
4//! threads, and are the building blocks of other concurrent
5//! types.
6//!
7//! This module defines atomic versions of a select number of primitive
8//! types, including [`AtomicBool`], [`AtomicIsize`], [`AtomicUsize`],
9//! [`AtomicI8`], [`AtomicU16`], etc.
10//! Atomic types present operations that, when used correctly, synchronize
11//! updates between threads.
12//!
13//! Atomic variables are safe to share between threads (they implement [`Sync`])
14//! but they do not themselves provide the mechanism for sharing and follow the
15//! [threading model](../../../std/thread/index.html#the-threading-model) of Rust.
16//! The most common way to share an atomic variable is to put it into an [`Arc`][arc] (an
17//! atomically-reference-counted shared pointer).
18//!
19//! [arc]: ../../../std/sync/struct.Arc.html
20//!
21//! Atomic types may be stored in static variables, initialized using
22//! the constant initializers like [`AtomicBool::new`]. Atomic statics
23//! are often used for lazy global initialization.
24//!
25//! ## Memory model for atomic accesses
26//!
27//! Rust atomics currently follow the same rules as [C++20 atomics][cpp], specifically the rules
28//! from the [`intro.races`][cpp-intro.races] section, without the "consume" memory ordering. Since
29//! C++ uses an object-based memory model whereas Rust is access-based, a bit of translation work
30//! has to be done to apply the C++ rules to Rust: whenever C++ talks about "the value of an
31//! object", we understand that to mean the resulting bytes obtained when doing a read. When the C++
32//! standard talks about "the value of an atomic object", this refers to the result of doing an
33//! atomic load (via the operations provided in this module). A "modification of an atomic object"
34//! refers to an atomic store.
35//!
36//! The end result is *almost* equivalent to saying that creating a *shared reference* to one of the
37//! Rust atomic types corresponds to creating an `atomic_ref` in C++, with the `atomic_ref` being
38//! destroyed when the lifetime of the shared reference ends. The main difference is that Rust
39//! permits concurrent atomic and non-atomic reads to the same memory as those cause no issue in the
40//! C++ memory model, they are just forbidden in C++ because memory is partitioned into "atomic
41//! objects" and "non-atomic objects" (with `atomic_ref` temporarily converting a non-atomic object
42//! into an atomic object).
43//!
44//! The most important aspect of this model is that *data races* are undefined behavior. A data race
45//! is defined as conflicting non-synchronized accesses where at least one of the accesses is
46//! non-atomic. Here, accesses are *conflicting* if they affect overlapping regions of memory and at
47//! least one of them is a write. (A `compare_exchange` or `compare_exchange_weak` that does not
48//! succeed is not considered a write.) They are *non-synchronized* if neither of them
49//! *happens-before* the other, according to the happens-before order of the memory model.
50//!
51//! The other possible cause of undefined behavior in the memory model are mixed-size accesses: Rust
52//! inherits the C++ limitation that non-synchronized conflicting atomic accesses may not partially
53//! overlap. In other words, every pair of non-synchronized atomic accesses must be either disjoint,
54//! access the exact same memory (including using the same access size), or both be reads.
55//!
56//! Each atomic access takes an [`Ordering`] which defines how the operation interacts with the
57//! happens-before order. These orderings behave the same as the corresponding [C++20 atomic
58//! orderings][cpp_memory_order]. For more information, see the [nomicon].
59//!
60//! [cpp]: https://en.cppreference.com/w/cpp/atomic
61//! [cpp-intro.races]: https://timsong-cpp.github.io/cppwp/n4868/intro.multithread#intro.races
62//! [cpp_memory_order]: https://en.cppreference.com/w/cpp/atomic/memory_order
63//! [nomicon]: ../../../nomicon/atomics.html
64//!
65//! ```rust,no_run undefined_behavior
66//! use std::sync::atomic::{AtomicU16, AtomicU8, Ordering};
67//! use std::mem::transmute;
68//! use std::thread;
69//!
70//! let atomic = AtomicU16::new(0);
71//!
72//! thread::scope(|s| {
73//!     // This is UB: conflicting non-synchronized accesses, at least one of which is non-atomic.
74//!     s.spawn(|| atomic.store(1, Ordering::Relaxed)); // atomic store
75//!     s.spawn(|| unsafe { atomic.as_ptr().write(2) }); // non-atomic write
76//! });
77//!
78//! thread::scope(|s| {
79//!     // This is fine: the accesses do not conflict (as none of them performs any modification).
80//!     // In C++ this would be disallowed since creating an `atomic_ref` precludes
81//!     // further non-atomic accesses, but Rust does not have that limitation.
82//!     s.spawn(|| atomic.load(Ordering::Relaxed)); // atomic load
83//!     s.spawn(|| unsafe { atomic.as_ptr().read() }); // non-atomic read
84//! });
85//!
86//! thread::scope(|s| {
87//!     // This is fine: `join` synchronizes the code in a way such that the atomic
88//!     // store happens-before the non-atomic write.
89//!     let handle = s.spawn(|| atomic.store(1, Ordering::Relaxed)); // atomic store
90//!     handle.join().expect("thread won't panic"); // synchronize
91//!     s.spawn(|| unsafe { atomic.as_ptr().write(2) }); // non-atomic write
92//! });
93//!
94//! thread::scope(|s| {
95//!     // This is UB: non-synchronized conflicting differently-sized atomic accesses.
96//!     s.spawn(|| atomic.store(1, Ordering::Relaxed));
97//!     s.spawn(|| unsafe {
98//!         let differently_sized = transmute::<&AtomicU16, &AtomicU8>(&atomic);
99//!         differently_sized.store(2, Ordering::Relaxed);
100//!     });
101//! });
102//!
103//! thread::scope(|s| {
104//!     // This is fine: `join` synchronizes the code in a way such that
105//!     // the 1-byte store happens-before the 2-byte store.
106//!     let handle = s.spawn(|| atomic.store(1, Ordering::Relaxed));
107//!     handle.join().expect("thread won't panic");
108//!     s.spawn(|| unsafe {
109//!         let differently_sized = transmute::<&AtomicU16, &AtomicU8>(&atomic);
110//!         differently_sized.store(2, Ordering::Relaxed);
111//!     });
112//! });
113//! ```
114//!
115//! # Portability
116//!
117//! All atomic types in this module are guaranteed to be [lock-free] if they're
118//! available. This means they don't internally acquire a global mutex. Atomic
119//! types and operations are not guaranteed to be wait-free. This means that
120//! operations like `fetch_or` may be implemented with a compare-and-swap loop.
121//!
122//! Atomic operations may be implemented at the instruction layer with
123//! larger-size atomics. For example some platforms use 4-byte atomic
124//! instructions to implement `AtomicI8`. Note that this emulation should not
125//! have an impact on correctness of code, it's just something to be aware of.
126//!
127//! The atomic types in this module might not be available on all platforms. The
128//! atomic types here are all widely available, however, and can generally be
129//! relied upon existing. Some notable exceptions are:
130//!
131//! * PowerPC and MIPS platforms with 32-bit pointers do not have `AtomicU64` or
132//!   `AtomicI64` types.
133//! * Legacy ARM platforms like ARMv4T and ARMv5TE have very limited hardware
134//!   support for atomics. The bare-metal targets disable this module
135//!   entirely, but the Linux targets [use the kernel] to assist (which comes
136//!   with a performance penalty). It's not until ARMv6K onwards that ARM CPUs
137//!   have support for load/store and Compare and Swap (CAS) atomics in hardware.
138//! * ARMv6-M targets (`thumbv6m-*`) only provide `load` and `store` operations, and do
139//!   not support Compare and Swap (CAS) operations, such as `swap`,
140//!   `fetch_add`, etc. Full CAS support is available on ARMv7-M and ARMv8-M
141//!   (`thumbv7m-*`, `thumbv7em*`, `thumbv8m.base-*` and `thumbv8m.main-*`).
142//!
143//! [use the kernel]: https://www.kernel.org/doc/Documentation/arm/kernel_user_helpers.txt
144//!
145//! Note that future platforms may be added that also do not have support for
146//! some atomic operations. Maximally portable code will want to be careful
147//! about which atomic types are used. `AtomicUsize` and `AtomicIsize` are
148//! generally the most portable, but even then they're not available everywhere.
149//! For reference, the `std` library requires `AtomicBool`s and pointer-sized atomics, although
150//! `core` does not.
151//!
152//! The `#[cfg(target_has_atomic)]` attribute can be used to conditionally
153//! compile based on the target's supported bit widths. It is a key-value
154//! option set for each supported size, with values "8", "16", "32", "64",
155//! "128", and "ptr" for pointer-sized atomics.
156//!
157//! [lock-free]: https://en.wikipedia.org/wiki/Non-blocking_algorithm
158//!
159//! # Atomic accesses to read-only memory
160//!
161//! In general, *all* atomic accesses on read-only memory are undefined behavior. For instance, attempting
162//! to do a `compare_exchange` that will definitely fail (making it conceptually a read-only
163//! operation) can still cause a segmentation fault if the underlying memory page is mapped read-only. Since
164//! atomic `load`s might be implemented using compare-exchange operations, even a `load` can fault
165//! on read-only memory.
166//!
167//! For the purpose of this section, "read-only memory" is defined as memory that is read-only in
168//! the underlying target, i.e., the pages are mapped with a read-only flag and any attempt to write
169//! will cause a page fault. In particular, an `&u128` reference that points to memory that is
170//! read-write mapped is *not* considered to point to "read-only memory". In Rust, almost all memory
171//! is read-write; the only exceptions are memory created by `const` items or `static` items without
172//! interior mutability, and memory that was specifically marked as read-only by the operating
173//! system via platform-specific APIs.
174//!
175//! As an exception from the general rule stated above, "sufficiently small" atomic loads with
176//! `Ordering::Relaxed` are implemented in a way that works on read-only memory, and are hence not
177//! undefined behavior. The exact size limit for what makes a load "sufficiently small" varies
178//! depending on the target:
179//!
180//! | `target_arch` | Size limit |
181//! |---------------|---------|
182//! | `x86`, `arm`, `loongarch32`, `mips`, `mips32r6`, `powerpc`, `riscv32`, `sparc`, `hexagon` | 4 bytes |
183//! | `x86_64`, `aarch64`, `loongarch64`, `mips64`, `mips64r6`, `powerpc64`, `riscv64`, `sparc64`, `s390x` | 8 bytes |
184//!
185//! Atomics loads that are larger than this limit as well as atomic loads with ordering other
186//! than `Relaxed`, as well as *all* atomic loads on targets not listed in the table, might still be
187//! read-only under certain conditions, but that is not a stable guarantee and should not be relied
188//! upon.
189//!
190//! If you need to do an acquire load on read-only memory, you can do a relaxed load followed by an
191//! acquire fence instead.
192//!
193//! # Examples
194//!
195//! A simple spinlock:
196//!
197//! ```ignore-wasm
198//! use std::sync::Arc;
199//! use std::sync::atomic::{AtomicUsize, Ordering};
200//! use std::{hint, thread};
201//!
202//! fn main() {
203//!     let spinlock = Arc::new(AtomicUsize::new(1));
204//!
205//!     let spinlock_clone = Arc::clone(&spinlock);
206//!
207//!     let thread = thread::spawn(move || {
208//!         spinlock_clone.store(0, Ordering::Release);
209//!     });
210//!
211//!     // Wait for the other thread to release the lock
212//!     while spinlock.load(Ordering::Acquire) != 0 {
213//!         hint::spin_loop();
214//!     }
215//!
216//!     if let Err(panic) = thread.join() {
217//!         println!("Thread had an error: {panic:?}");
218//!     }
219//! }
220//! ```
221//!
222//! Keep a global count of live threads:
223//!
224//! ```
225//! use std::sync::atomic::{AtomicUsize, Ordering};
226//!
227//! static GLOBAL_THREAD_COUNT: AtomicUsize = AtomicUsize::new(0);
228//!
229//! // Note that Relaxed ordering doesn't synchronize anything
230//! // except the global thread counter itself.
231//! let old_thread_count = GLOBAL_THREAD_COUNT.fetch_add(1, Ordering::Relaxed);
232//! // Note that this number may not be true at the moment of printing
233//! // because some other thread may have changed static value already.
234//! println!("live threads: {}", old_thread_count + 1);
235//! ```
236
237#![stable(feature = "rust1", since = "1.0.0")]
238#![cfg_attr(not(target_has_atomic_load_store = "8"), allow(dead_code))]
239#![cfg_attr(not(target_has_atomic_load_store = "8"), allow(unused_imports))]
240// Clippy complains about the pattern of "safe function calling unsafe function taking pointers".
241// This happens with AtomicPtr intrinsics but is fine, as the pointers clippy is concerned about
242// are just normal values that get loaded/stored, but not dereferenced.
243#![allow(clippy::not_unsafe_ptr_arg_deref)]
244
245use self::Ordering::*;
246use crate::cell::UnsafeCell;
247use crate::hint::spin_loop;
248use crate::intrinsics::AtomicOrdering as AO;
249use crate::mem::transmute;
250use crate::{fmt, intrinsics};
251
252#[unstable(
253    feature = "atomic_internals",
254    reason = "implementation detail which may disappear or be replaced at any time",
255    issue = "none"
256)]
257#[expect(missing_debug_implementations)]
258mod private {
259    #[cfg(target_has_atomic_load_store = "8")]
260    #[repr(C, align(1))]
261    pub struct Align1<T>(T);
262    #[cfg(target_has_atomic_load_store = "16")]
263    #[repr(C, align(2))]
264    pub struct Align2<T>(T);
265    #[cfg(target_has_atomic_load_store = "32")]
266    #[repr(C, align(4))]
267    pub struct Align4<T>(T);
268    #[cfg(target_has_atomic_load_store = "64")]
269    #[repr(C, align(8))]
270    pub struct Align8<T>(T);
271    #[cfg(any(target_has_atomic_load_store = "128", doc))]
272    #[repr(C, align(16))]
273    pub struct Align16<T>(T);
274}
275
276/// A marker trait for primitive types which can be modified atomically.
277///
278/// This is an implementation detail for <code>[Atomic]\<T></code> which may disappear or be replaced at any time.
279//
280// # Safety
281//
282// Types implementing this trait must be primitives that can be modified atomically.
283//
284// The associated `Self::Storage` type must have the same size, but may have fewer validity
285// invariants or a higher alignment requirement than `Self`.
286#[unstable(
287    feature = "atomic_internals",
288    reason = "implementation detail which may disappear or be replaced at any time",
289    issue = "none"
290)]
291pub impl(self) unsafe trait AtomicPrimitive: Sized + Copy {
292    /// Temporary implementation detail.
293    type Storage: Sized;
294}
295
296macro impl_atomic_primitive {
297    (
298        @impl [$($T:ident)?] $Primitive:ty as $Storage:ident<$Operand:ty>,
299        $cfg:meta
300    ) => {
301        #[unstable(
302            feature = "atomic_internals",
303            reason = "implementation detail which may disappear or be replaced at any time",
304            issue = "none"
305        )]
306        #[cfg($cfg)]
307        unsafe impl $(<$T>)? AtomicPrimitive for $Primitive {
308            type Storage = private::$Storage<$Operand>;
309        }
310    },
311
312    (
313        [$($T:ident)?] $Primitive:ty as $Storage:ident<$Operand:ty>,
314        size($size:literal)
315    ) => {
316        impl_atomic_primitive!(
317            @impl [$($T)?] $Primitive as $Storage<$Operand>,
318            target_has_atomic_load_store = $size
319        );
320    },
321
322    (
323        [$($T:ident)?] $Primitive:ty as $Storage:ident<$Operand:ty>,
324        size($size:literal),
325        doc
326    ) => {
327        impl_atomic_primitive!(
328            @impl [$($T)?] $Primitive as $Storage<$Operand>,
329            any(target_has_atomic_load_store = $size, doc)
330        );
331    },
332}
333
334impl_atomic_primitive!([] bool as Align1<u8>, size("8"));
335impl_atomic_primitive!([] i8 as Align1<i8>, size("8"));
336impl_atomic_primitive!([] u8 as Align1<u8>, size("8"));
337impl_atomic_primitive!([] i16 as Align2<i16>, size("16"));
338impl_atomic_primitive!([] u16 as Align2<u16>, size("16"));
339impl_atomic_primitive!([] i32 as Align4<i32>, size("32"));
340impl_atomic_primitive!([] u32 as Align4<u32>, size("32"));
341impl_atomic_primitive!([] i64 as Align8<i64>, size("64"));
342impl_atomic_primitive!([] u64 as Align8<u64>, size("64"));
343impl_atomic_primitive!([] i128 as Align16<i128>, size("128"), doc);
344impl_atomic_primitive!([] u128 as Align16<u128>, size("128"), doc);
345
346#[cfg(target_pointer_width = "16")]
347impl_atomic_primitive!([] isize as Align2<isize>, size("ptr"));
348#[cfg(target_pointer_width = "32")]
349impl_atomic_primitive!([] isize as Align4<isize>, size("ptr"));
350#[cfg(target_pointer_width = "64")]
351impl_atomic_primitive!([] isize as Align8<isize>, size("ptr"));
352
353#[cfg(target_pointer_width = "16")]
354impl_atomic_primitive!([] usize as Align2<usize>, size("ptr"));
355#[cfg(target_pointer_width = "32")]
356impl_atomic_primitive!([] usize as Align4<usize>, size("ptr"));
357#[cfg(target_pointer_width = "64")]
358impl_atomic_primitive!([] usize as Align8<usize>, size("ptr"));
359
360#[cfg(target_pointer_width = "16")]
361impl_atomic_primitive!([T] *mut T as Align2<*mut T>, size("ptr"));
362#[cfg(target_pointer_width = "32")]
363impl_atomic_primitive!([T] *mut T as Align4<*mut T>, size("ptr"));
364#[cfg(target_pointer_width = "64")]
365impl_atomic_primitive!([T] *mut T as Align8<*mut T>, size("ptr"));
366
367/// A memory location which can be safely modified from multiple threads.
368///
369/// This has the same size and bit validity as the underlying type `T`. However,
370/// the alignment of this type is always equal to its size, even on targets where
371/// `T` has alignment less than its size.
372///
373/// For more about the differences between atomic types and non-atomic types as
374/// well as information about the portability of this type, please see the
375/// [module-level documentation].
376///
377/// **Note:** This type is only available on platforms that support atomic loads
378/// and stores of `T`.
379///
380/// [module-level documentation]: crate::sync::atomic
381#[unstable(feature = "generic_atomic", issue = "130539")]
382#[repr(C)]
383#[rustc_diagnostic_item = "Atomic"]
384pub struct Atomic<T: AtomicPrimitive> {
385    v: UnsafeCell<T::Storage>,
386}
387
388#[stable(feature = "rust1", since = "1.0.0")]
389unsafe impl<T: AtomicPrimitive> Send for Atomic<T> {}
390#[stable(feature = "rust1", since = "1.0.0")]
391unsafe impl<T: AtomicPrimitive> Sync for Atomic<T> {}
392
393// Some architectures don't have byte-sized atomics, which results in LLVM
394// emulating them using a LL/SC loop. However for AtomicBool we can take
395// advantage of the fact that it only ever contains 0 or 1 and use atomic OR/AND
396// instead, which LLVM can emulate using a larger atomic OR/AND operation.
397//
398// This list should only contain architectures which have word-sized atomic-or/
399// atomic-and instructions but don't natively support byte-sized atomics.
400#[cfg(target_has_atomic = "8")]
401const EMULATE_ATOMIC_BOOL: bool = cfg!(any(
402    target_arch = "riscv32",
403    target_arch = "riscv64",
404    target_arch = "loongarch32",
405    target_arch = "loongarch64"
406));
407
408/// A boolean type which can be safely shared between threads.
409///
410/// This type has the same size, alignment, and bit validity as a [`bool`].
411///
412/// **Note**: This type is only available on platforms that support atomic
413/// loads and stores of `u8`.
414#[cfg(target_has_atomic_load_store = "8")]
415#[stable(feature = "rust1", since = "1.0.0")]
416pub type AtomicBool = Atomic<bool>;
417
418#[cfg(target_has_atomic_load_store = "8")]
419#[stable(feature = "rust1", since = "1.0.0")]
420impl Default for AtomicBool {
421    /// Creates an `AtomicBool` initialized to `false`.
422    #[inline]
423    fn default() -> Self {
424        Self::new(false)
425    }
426}
427
428/// A raw pointer type which can be safely shared between threads.
429///
430/// This type has the same size and bit validity as a `*mut T`.
431///
432/// **Note**: This type is only available on platforms that support atomic
433/// loads and stores of pointers. Its size depends on the target pointer's size.
434#[cfg(target_has_atomic_load_store = "ptr")]
435#[stable(feature = "rust1", since = "1.0.0")]
436pub type AtomicPtr<T> = Atomic<*mut T>;
437
438#[cfg(target_has_atomic_load_store = "ptr")]
439#[stable(feature = "rust1", since = "1.0.0")]
440impl<T> Default for AtomicPtr<T> {
441    /// Creates a null `AtomicPtr<T>`.
442    fn default() -> AtomicPtr<T> {
443        AtomicPtr::new(crate::ptr::null_mut())
444    }
445}
446
447/// Atomic memory orderings
448///
449/// Memory orderings specify the way atomic operations synchronize memory.
450/// In its weakest [`Ordering::Relaxed`], only the memory directly touched by the
451/// operation is synchronized. On the other hand, a store-load pair of [`Ordering::SeqCst`]
452/// operations synchronize other memory while additionally preserving a total order of such
453/// operations across all threads.
454///
455/// Rust's memory orderings are [the same as those of
456/// C++20](https://en.cppreference.com/w/cpp/atomic/memory_order).
457///
458/// For more information see the [nomicon].
459///
460/// [nomicon]: ../../../nomicon/atomics.html
461#[stable(feature = "rust1", since = "1.0.0")]
462#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
463#[non_exhaustive]
464#[rustc_diagnostic_item = "Ordering"]
465pub enum Ordering {
466    /// No ordering constraints, only atomic operations.
467    ///
468    /// Corresponds to [`memory_order_relaxed`] in C++20.
469    ///
470    /// [`memory_order_relaxed`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Relaxed_ordering
471    #[stable(feature = "rust1", since = "1.0.0")]
472    Relaxed,
473    /// When coupled with a store, all previous operations become ordered
474    /// before any load of this value with [`Acquire`] (or stronger) ordering.
475    /// In particular, all previous writes become visible to all threads
476    /// that perform an [`Acquire`] (or stronger) load of this value.
477    ///
478    /// Notice that using this ordering for an operation that combines loads
479    /// and stores leads to a [`Relaxed`] load operation!
480    ///
481    /// This ordering is only applicable for operations that can perform a store.
482    ///
483    /// Corresponds to [`memory_order_release`] in C++20.
484    ///
485    /// [`memory_order_release`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
486    #[stable(feature = "rust1", since = "1.0.0")]
487    Release,
488    /// When coupled with a load, if the loaded value was written by a store operation with
489    /// [`Release`] (or stronger) ordering, then all subsequent operations
490    /// become ordered after that store. In particular, all subsequent loads will see data
491    /// written before the store.
492    ///
493    /// Notice that using this ordering for an operation that combines loads
494    /// and stores leads to a [`Relaxed`] store operation!
495    ///
496    /// This ordering is only applicable for operations that can perform a load.
497    ///
498    /// Corresponds to [`memory_order_acquire`] in C++20.
499    ///
500    /// [`memory_order_acquire`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
501    #[stable(feature = "rust1", since = "1.0.0")]
502    Acquire,
503    /// Has the effects of both [`Acquire`] and [`Release`] together:
504    /// For loads it uses [`Acquire`] ordering. For stores it uses the [`Release`] ordering.
505    ///
506    /// Notice that in the case of `compare_and_swap`, it is possible that the operation ends up
507    /// not performing any store and hence it has just [`Acquire`] ordering. However,
508    /// `AcqRel` will never perform [`Relaxed`] accesses.
509    ///
510    /// This ordering is only applicable for operations that combine both loads and stores.
511    ///
512    /// Corresponds to [`memory_order_acq_rel`] in C++20.
513    ///
514    /// [`memory_order_acq_rel`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
515    #[stable(feature = "rust1", since = "1.0.0")]
516    AcqRel,
517    /// Like [`Acquire`]/[`Release`]/[`AcqRel`] (for load, store, and load-with-store
518    /// operations, respectively) with the additional guarantee that all threads see all
519    /// sequentially consistent operations in the same order.
520    ///
521    /// Corresponds to [`memory_order_seq_cst`] in C++20.
522    ///
523    /// [`memory_order_seq_cst`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Sequentially-consistent_ordering
524    #[stable(feature = "rust1", since = "1.0.0")]
525    SeqCst,
526}
527
528/// An [`AtomicBool`] initialized to `false`.
529#[cfg(target_has_atomic_load_store = "8")]
530#[stable(feature = "rust1", since = "1.0.0")]
531#[deprecated(
532    since = "1.34.0",
533    note = "the `new` function is now preferred",
534    suggestion = "AtomicBool::new(false)"
535)]
536#[expect(clippy::declare_interior_mutable_const, reason = "legacy atomic initializer")]
537pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false);
538
539#[cfg(target_has_atomic_load_store = "8")]
540impl AtomicBool {
541    /// Creates a new `AtomicBool`.
542    ///
543    /// # Examples
544    ///
545    /// ```
546    /// use std::sync::atomic::AtomicBool;
547    ///
548    /// let atomic_true = AtomicBool::new(true);
549    /// let atomic_false = AtomicBool::new(false);
550    /// ```
551    #[inline]
552    #[stable(feature = "rust1", since = "1.0.0")]
553    #[rustc_const_stable(feature = "const_atomic_new", since = "1.24.0")]
554    #[must_use]
555    pub const fn new(v: bool) -> AtomicBool {
556        // SAFETY:
557        // `Atomic<T>` is essentially a transparent wrapper around `T`.
558        unsafe { transmute(v) }
559    }
560
561    /// Creates a new `AtomicBool` from a pointer.
562    ///
563    /// # Examples
564    ///
565    /// ```
566    /// use std::sync::atomic::{self, AtomicBool};
567    ///
568    /// // Get a pointer to an allocated value
569    /// let ptr: *mut bool = Box::into_raw(Box::new(false));
570    ///
571    /// assert!(ptr.cast::<AtomicBool>().is_aligned());
572    ///
573    /// {
574    ///     // Create an atomic view of the allocated value
575    ///     let atomic = unsafe { AtomicBool::from_ptr(ptr) };
576    ///
577    ///     // Use `atomic` for atomic operations, possibly share it with other threads
578    ///     atomic.store(true, atomic::Ordering::Relaxed);
579    /// }
580    ///
581    /// // It's ok to non-atomically access the value behind `ptr`,
582    /// // since the reference to the atomic ended its lifetime in the block above
583    /// assert_eq!(unsafe { *ptr }, true);
584    ///
585    /// // Deallocate the value
586    /// unsafe { drop(Box::from_raw(ptr)) }
587    /// ```
588    ///
589    /// # Safety
590    ///
591    /// * `ptr` must be aligned to `align_of::<AtomicBool>()` (note that this is always true, since
592    ///   `align_of::<AtomicBool>() == 1`).
593    /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
594    /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
595    ///   allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different
596    ///   sizes, without synchronization.
597    ///
598    /// [valid]: crate::ptr#safety
599    /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
600    #[inline]
601    #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
602    #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
603    pub const unsafe fn from_ptr<'a>(ptr: *mut bool) -> &'a AtomicBool {
604        // SAFETY: guaranteed by the caller
605        unsafe { &*ptr.cast() }
606    }
607
608    /// Creates a new pointer to `AtomicBool` from a pointer.
609    ///
610    /// This is useful if you want to do volatile atomic accesses, and thus avoid creating
611    /// a reference to the destination.
612    #[inline]
613    #[unstable(feature = "atomic_volatile", issue = "158947")]
614    pub const fn from_ptr_raw(ptr: *mut bool) -> *const AtomicBool {
615        ptr.cast_const().cast()
616    }
617
618    /// Returns a mutable reference to the underlying [`bool`].
619    ///
620    /// This is safe because the mutable reference guarantees that no other threads are
621    /// concurrently accessing the atomic data.
622    ///
623    /// # Examples
624    ///
625    /// ```
626    /// use std::sync::atomic::{AtomicBool, Ordering};
627    ///
628    /// let mut some_bool = AtomicBool::new(true);
629    /// assert_eq!(*some_bool.get_mut(), true);
630    /// *some_bool.get_mut() = false;
631    /// assert_eq!(some_bool.load(Ordering::SeqCst), false);
632    /// ```
633    #[inline]
634    #[stable(feature = "atomic_access", since = "1.15.0")]
635    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
636    pub const fn get_mut(&mut self) -> &mut bool {
637        // SAFETY: the mutable reference guarantees unique ownership.
638        unsafe { &mut *self.as_ptr() }
639    }
640
641    /// Gets atomic access to a `&mut bool`.
642    ///
643    /// # Examples
644    ///
645    /// ```
646    /// use std::sync::atomic::{AtomicBool, Ordering};
647    ///
648    /// let mut some_bool = true;
649    /// let a = AtomicBool::from_mut(&mut some_bool);
650    /// a.store(false, Ordering::Relaxed);
651    /// assert_eq!(some_bool, false);
652    /// ```
653    #[inline]
654    #[cfg(target_has_atomic_primitive_alignment = "8")]
655    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
656    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
657    pub const fn from_mut(v: &mut bool) -> &mut Self {
658        // SAFETY: the mutable reference guarantees unique ownership, and
659        // alignment of both `bool` and `Self` is 1.
660        unsafe { &mut *(v as *mut bool as *mut Self) }
661    }
662
663    /// Gets non-atomic access to a `&mut [AtomicBool]` slice.
664    ///
665    /// This is safe because the mutable reference guarantees that no other threads are
666    /// concurrently accessing the atomic data.
667    ///
668    /// # Examples
669    ///
670    /// ```ignore-wasm
671    /// use std::sync::atomic::{AtomicBool, Ordering};
672    ///
673    /// let mut some_bools = [const { AtomicBool::new(false) }; 10];
674    ///
675    /// let view: &mut [bool] = AtomicBool::get_mut_slice(&mut some_bools);
676    /// assert_eq!(view, [false; 10]);
677    /// view[..5].copy_from_slice(&[true; 5]);
678    ///
679    /// std::thread::scope(|s| {
680    ///     for t in &some_bools[..5] {
681    ///         s.spawn(move || assert_eq!(t.load(Ordering::Relaxed), true));
682    ///     }
683    ///
684    ///     for f in &some_bools[5..] {
685    ///         s.spawn(move || assert_eq!(f.load(Ordering::Relaxed), false));
686    ///     }
687    /// });
688    /// ```
689    #[inline]
690    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
691    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
692    pub const fn get_mut_slice(this: &mut [Self]) -> &mut [bool] {
693        // SAFETY: the mutable reference guarantees unique ownership.
694        unsafe { &mut *(this as *mut [Self] as *mut [bool]) }
695    }
696
697    /// Gets atomic access to a `&mut [bool]` slice.
698    ///
699    /// # Examples
700    ///
701    /// ```rust,ignore-wasm
702    /// use std::sync::atomic::{AtomicBool, Ordering};
703    ///
704    /// let mut some_bools = [false; 10];
705    /// let a = &*AtomicBool::from_mut_slice(&mut some_bools);
706    /// std::thread::scope(|s| {
707    ///     for i in 0..a.len() {
708    ///         s.spawn(move || a[i].store(true, Ordering::Relaxed));
709    ///     }
710    /// });
711    /// assert_eq!(some_bools, [true; 10]);
712    /// ```
713    #[inline]
714    #[cfg(target_has_atomic_primitive_alignment = "8")]
715    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
716    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
717    pub const fn from_mut_slice(v: &mut [bool]) -> &mut [Self] {
718        // SAFETY: the mutable reference guarantees unique ownership, and
719        // alignment of both `bool` and `Self` is 1.
720        unsafe { &mut *(v as *mut [bool] as *mut [Self]) }
721    }
722
723    /// Consumes the atomic and returns the contained value.
724    ///
725    /// This is safe because passing `self` by value guarantees that no other threads are
726    /// concurrently accessing the atomic data.
727    ///
728    /// # Examples
729    ///
730    /// ```
731    /// use std::sync::atomic::AtomicBool;
732    ///
733    /// let some_bool = AtomicBool::new(true);
734    /// assert_eq!(some_bool.into_inner(), true);
735    /// ```
736    #[inline]
737    #[stable(feature = "atomic_access", since = "1.15.0")]
738    #[rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0")]
739    pub const fn into_inner(self) -> bool {
740        // SAFETY:
741        // * `Atomic<T>` is essentially a transparent wrapper around `T`.
742        // * all operations on `Atomic<bool>` ensure that `T::Storage` remains
743        //   a valid `bool`.
744        unsafe { transmute(self) }
745    }
746
747    /// Loads a value from the bool.
748    ///
749    /// `load` takes an [`Ordering`] argument which describes the memory ordering
750    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
751    ///
752    /// # Panics
753    ///
754    /// Panics if `order` is [`Release`] or [`AcqRel`].
755    ///
756    /// # Examples
757    ///
758    /// ```
759    /// use std::sync::atomic::{AtomicBool, Ordering};
760    ///
761    /// let some_bool = AtomicBool::new(true);
762    ///
763    /// assert_eq!(some_bool.load(Ordering::Relaxed), true);
764    /// ```
765    #[inline]
766    #[stable(feature = "rust1", since = "1.0.0")]
767    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
768    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
769    pub const fn load(&self, order: Ordering) -> bool {
770        // SAFETY: any data races are prevented by atomic intrinsics and the raw
771        // pointer passed in is valid because we got it from a reference.
772        unsafe {
773            atomic_load::<_, /* VOLATILE */ false>(self.v.get().cast::<u8>(), order) != 0
774        }
775    }
776
777    /// Perform a volatile atomic load from the bool.
778    ///
779    /// `load_volatile` takes an [`Ordering`] argument which describes the memory ordering
780    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
781    ///
782    #[doc = include_str!("./atomic_load_volatile.md")]
783    ///
784    /// # Safety
785    ///
786    /// Behavior is undefined if any of the following conditions are violated:
787    ///
788    /// * `self` must be [valid] for reads, or `self` must point to memory
789    ///   outside of all Rust allocations and reading from that memory must:
790    ///   - not trap, and
791    ///   - not cause any memory inside a Rust allocation to be modified.
792    ///
793    /// * Reading from `self` must produce a properly initialized value of type `bool`.
794    ///
795    /// [valid]: core::ptr#safety
796    ///
797    /// # Panics
798    ///
799    /// Panics if `order` is [`Release`] or [`AcqRel`].
800    #[inline]
801    #[unstable(feature = "atomic_volatile", issue = "158947")]
802    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
803    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
804    pub const unsafe fn load_volatile(self: *const Self, order: Ordering) -> bool {
805        // SAFETY: follows from our own safety requirements.
806        unsafe {
807            atomic_load::<_, /* VOLATILE */ true>(self.cast::<u8>(), order) != 0
808        }
809    }
810
811    /// Stores a value into the bool.
812    ///
813    /// `store` takes an [`Ordering`] argument which describes the memory ordering
814    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
815    ///
816    /// # Panics
817    ///
818    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
819    ///
820    /// # Examples
821    ///
822    /// ```
823    /// use std::sync::atomic::{AtomicBool, Ordering};
824    ///
825    /// let some_bool = AtomicBool::new(true);
826    ///
827    /// some_bool.store(false, Ordering::Relaxed);
828    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
829    /// ```
830    #[inline]
831    #[stable(feature = "rust1", since = "1.0.0")]
832    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
833    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
834    #[rustc_should_not_be_called_on_const_items]
835    pub const fn store(&self, val: bool, order: Ordering) {
836        // SAFETY: any data races are prevented by atomic intrinsics and the raw
837        // pointer passed in is valid because we got it from a reference.
838        unsafe {
839            atomic_store::<_, /* VOLATILE */ false>(self.v.get().cast::<u8>(), val as u8, order);
840        }
841    }
842
843    /// Performs a volatile atomic store into the bool.
844    ///
845    /// `store_volatile` takes an [`Ordering`] argument which describes the memory ordering
846    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
847    ///
848    #[doc = include_str!("./atomic_store_volatile.md")]
849    ///
850    /// # Safety
851    ///
852    /// Behavior is undefined if any of the following conditions are violated:
853    ///
854    /// * `self` must be either [valid] for writes, or `self` must point to memory
855    ///   outside of all Rust allocations and writing to that memory must:
856    ///   - not trap, and
857    ///   - not cause any memory inside a Rust allocation to be modified.
858    ///
859    /// [valid]: core::ptr#safety
860    ///
861    /// # Panics
862    ///
863    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
864    #[inline]
865    #[unstable(feature = "atomic_volatile", issue = "158947")]
866    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
867    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
868    #[rustc_should_not_be_called_on_const_items]
869    pub const unsafe fn store_volatile(self: *const Self, val: bool, order: Ordering) {
870        // SAFETY: follows from our own safety requirements.
871        unsafe {
872            atomic_store::<_, /* VOLATILE */ true>(self.cast::<u8>().cast_mut(), val as u8, order);
873        }
874    }
875
876    /// Stores a value into the bool, returning the previous value.
877    ///
878    /// `swap` takes an [`Ordering`] argument which describes the memory ordering
879    /// of this operation. All ordering modes are possible. Note that using
880    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
881    /// using [`Release`] makes the load part [`Relaxed`].
882    ///
883    /// **Note:** This method is only available on platforms that support atomic
884    /// operations on `u8`.
885    ///
886    /// # Examples
887    ///
888    /// ```
889    /// use std::sync::atomic::{AtomicBool, Ordering};
890    ///
891    /// let some_bool = AtomicBool::new(true);
892    ///
893    /// assert_eq!(some_bool.swap(false, Ordering::Relaxed), true);
894    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
895    /// ```
896    #[inline]
897    #[stable(feature = "rust1", since = "1.0.0")]
898    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
899    #[cfg(target_has_atomic = "8")]
900    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
901    #[rustc_should_not_be_called_on_const_items]
902    pub const fn swap(&self, val: bool, order: Ordering) -> bool {
903        if EMULATE_ATOMIC_BOOL {
904            if val { self.fetch_or(true, order) } else { self.fetch_and(false, order) }
905        } else {
906            // SAFETY: data races are prevented by atomic intrinsics.
907            unsafe { atomic_swap(self.v.get().cast::<u8>(), val as u8, order) != 0 }
908        }
909    }
910
911    /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
912    ///
913    /// The return value is always the previous value. If it is equal to `current`, then the value
914    /// was updated.
915    ///
916    /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
917    /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
918    /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
919    /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
920    /// happens, and using [`Release`] makes the load part [`Relaxed`].
921    ///
922    /// **Note:** This method is only available on platforms that support atomic
923    /// operations on `u8`.
924    ///
925    /// # Migrating to `compare_exchange` and `compare_exchange_weak`
926    ///
927    /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
928    /// memory orderings:
929    ///
930    /// Original | Success | Failure
931    /// -------- | ------- | -------
932    /// Relaxed  | Relaxed | Relaxed
933    /// Acquire  | Acquire | Acquire
934    /// Release  | Release | Relaxed
935    /// AcqRel   | AcqRel  | Acquire
936    /// SeqCst   | SeqCst  | SeqCst
937    ///
938    /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use
939    /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`,
940    /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err`
941    /// rather than to infer success vs failure based on the value that was read.
942    ///
943    /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead.
944    /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
945    /// which allows the compiler to generate better assembly code when the compare and swap
946    /// is used in a loop.
947    ///
948    /// # Examples
949    ///
950    /// ```
951    /// use std::sync::atomic::{AtomicBool, Ordering};
952    ///
953    /// let some_bool = AtomicBool::new(true);
954    ///
955    /// assert_eq!(some_bool.compare_and_swap(true, false, Ordering::Relaxed), true);
956    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
957    ///
958    /// assert_eq!(some_bool.compare_and_swap(true, true, Ordering::Relaxed), false);
959    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
960    /// ```
961    #[inline]
962    #[stable(feature = "rust1", since = "1.0.0")]
963    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
964    #[deprecated(
965        since = "1.50.0",
966        note = "Use `compare_exchange` or `compare_exchange_weak` instead"
967    )]
968    #[cfg(target_has_atomic = "8")]
969    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
970    #[rustc_should_not_be_called_on_const_items]
971    pub const fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> bool {
972        match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
973            Ok(x) => x,
974            Err(x) => x,
975        }
976    }
977
978    /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
979    ///
980    /// The return value is a result indicating whether the new value was written and containing
981    /// the previous value. On success this value is guaranteed to be equal to `current`.
982    ///
983    /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
984    /// ordering of this operation. `success` describes the required ordering for the
985    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
986    /// `failure` describes the required ordering for the load operation that takes place when
987    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
988    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
989    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
990    ///
991    /// **Note:** This method is only available on platforms that support atomic
992    /// operations on `u8`.
993    ///
994    /// # Examples
995    ///
996    /// ```
997    /// use std::sync::atomic::{AtomicBool, Ordering};
998    ///
999    /// let some_bool = AtomicBool::new(true);
1000    ///
1001    /// assert_eq!(some_bool.compare_exchange(true,
1002    ///                                       false,
1003    ///                                       Ordering::Acquire,
1004    ///                                       Ordering::Relaxed),
1005    ///            Ok(true));
1006    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
1007    ///
1008    /// assert_eq!(some_bool.compare_exchange(true, true,
1009    ///                                       Ordering::SeqCst,
1010    ///                                       Ordering::Acquire),
1011    ///            Err(false));
1012    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
1013    /// ```
1014    ///
1015    /// # Considerations
1016    ///
1017    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
1018    /// of CAS operations. In particular, a load of the value followed by a successful
1019    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
1020    /// changed the value in the interim. This is usually important when the *equality* check in
1021    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
1022    /// does not necessarily imply identity. In this case, `compare_exchange` can lead to the
1023    /// [ABA problem].
1024    ///
1025    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1026    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
1027    #[inline]
1028    #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
1029    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1030    #[doc(alias = "compare_and_swap")]
1031    #[cfg(target_has_atomic = "8")]
1032    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1033    #[rustc_should_not_be_called_on_const_items]
1034    pub const fn compare_exchange(
1035        &self,
1036        current: bool,
1037        new: bool,
1038        success: Ordering,
1039        failure: Ordering,
1040    ) -> Result<bool, bool> {
1041        if EMULATE_ATOMIC_BOOL {
1042            // Pick the strongest ordering from success and failure.
1043            let order = match (success, failure) {
1044                (SeqCst, _) => SeqCst,
1045                (_, SeqCst) => SeqCst,
1046                (AcqRel, _) => AcqRel,
1047                (_, AcqRel) => {
1048                    panic!("there is no such thing as an acquire-release failure ordering")
1049                }
1050                (Release, Acquire) => AcqRel,
1051                (Acquire, _) => Acquire,
1052                (_, Acquire) => Acquire,
1053                (Release, Relaxed) => Release,
1054                (_, Release) => panic!("there is no such thing as a release failure ordering"),
1055                (Relaxed, Relaxed) => Relaxed,
1056            };
1057            let old = if current == new {
1058                // This is a no-op, but we still need to perform the operation
1059                // for memory ordering reasons.
1060                self.fetch_or(false, order)
1061            } else {
1062                // This sets the value to the new one and returns the old one.
1063                self.swap(new, order)
1064            };
1065            if old == current { Ok(old) } else { Err(old) }
1066        } else {
1067            // SAFETY: data races are prevented by atomic intrinsics.
1068            match unsafe {
1069                atomic_compare_exchange(
1070                    self.v.get().cast::<u8>(),
1071                    current as u8,
1072                    new as u8,
1073                    success,
1074                    failure,
1075                )
1076            } {
1077                Ok(x) => Ok(x != 0),
1078                Err(x) => Err(x != 0),
1079            }
1080        }
1081    }
1082
1083    /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
1084    ///
1085    /// Unlike [`AtomicBool::compare_exchange`], this function is allowed to spuriously fail even when the
1086    /// comparison succeeds, which can result in more efficient code on some platforms. The
1087    /// return value is a result indicating whether the new value was written and containing the
1088    /// previous value.
1089    ///
1090    /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
1091    /// ordering of this operation. `success` describes the required ordering for the
1092    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
1093    /// `failure` describes the required ordering for the load operation that takes place when
1094    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
1095    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
1096    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
1097    ///
1098    /// **Note:** This method is only available on platforms that support atomic
1099    /// operations on `u8`.
1100    ///
1101    /// # Examples
1102    ///
1103    /// ```
1104    /// use std::sync::atomic::{AtomicBool, Ordering};
1105    ///
1106    /// let val = AtomicBool::new(false);
1107    ///
1108    /// let new = true;
1109    /// let mut old = val.load(Ordering::Relaxed);
1110    /// loop {
1111    ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
1112    ///         Ok(_) => break,
1113    ///         Err(x) => old = x,
1114    ///     }
1115    /// }
1116    /// ```
1117    ///
1118    /// # Considerations
1119    ///
1120    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
1121    /// of CAS operations. In particular, a load of the value followed by a successful
1122    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
1123    /// changed the value in the interim. This is usually important when the *equality* check in
1124    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
1125    /// does not necessarily imply identity. In this case, `compare_exchange` can lead to the
1126    /// [ABA problem].
1127    ///
1128    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1129    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
1130    #[inline]
1131    #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
1132    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1133    #[doc(alias = "compare_and_swap")]
1134    #[cfg(target_has_atomic = "8")]
1135    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1136    #[rustc_should_not_be_called_on_const_items]
1137    pub const fn compare_exchange_weak(
1138        &self,
1139        current: bool,
1140        new: bool,
1141        success: Ordering,
1142        failure: Ordering,
1143    ) -> Result<bool, bool> {
1144        if EMULATE_ATOMIC_BOOL {
1145            return self.compare_exchange(current, new, success, failure);
1146        }
1147
1148        // SAFETY: data races are prevented by atomic intrinsics.
1149        match unsafe {
1150            atomic_compare_exchange_weak(
1151                self.v.get().cast::<u8>(),
1152                current as u8,
1153                new as u8,
1154                success,
1155                failure,
1156            )
1157        } {
1158            Ok(x) => Ok(x != 0),
1159            Err(x) => Err(x != 0),
1160        }
1161    }
1162
1163    /// Logical "and" with a boolean value.
1164    ///
1165    /// Performs a logical "and" operation on the current value and the argument `val`, and sets
1166    /// the new value to the result.
1167    ///
1168    /// Returns the previous value.
1169    ///
1170    /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
1171    /// of this operation. All ordering modes are possible. Note that using
1172    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
1173    /// using [`Release`] makes the load part [`Relaxed`].
1174    ///
1175    /// **Note:** This method is only available on platforms that support atomic
1176    /// operations on `u8`.
1177    ///
1178    /// # Examples
1179    ///
1180    /// ```
1181    /// use std::sync::atomic::{AtomicBool, Ordering};
1182    ///
1183    /// let foo = AtomicBool::new(true);
1184    /// assert_eq!(foo.fetch_and(false, Ordering::SeqCst), true);
1185    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1186    ///
1187    /// let foo = AtomicBool::new(true);
1188    /// assert_eq!(foo.fetch_and(true, Ordering::SeqCst), true);
1189    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1190    ///
1191    /// let foo = AtomicBool::new(false);
1192    /// assert_eq!(foo.fetch_and(false, Ordering::SeqCst), false);
1193    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1194    /// ```
1195    #[inline]
1196    #[stable(feature = "rust1", since = "1.0.0")]
1197    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1198    #[cfg(target_has_atomic = "8")]
1199    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1200    #[rustc_should_not_be_called_on_const_items]
1201    pub const fn fetch_and(&self, val: bool, order: Ordering) -> bool {
1202        // SAFETY: data races are prevented by atomic intrinsics.
1203        unsafe { atomic_and(self.v.get().cast::<u8>(), val as u8, order) != 0 }
1204    }
1205
1206    /// Logical "nand" with a boolean value.
1207    ///
1208    /// Performs a logical "nand" operation on the current value and the argument `val`, and sets
1209    /// the new value to the result.
1210    ///
1211    /// Returns the previous value.
1212    ///
1213    /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
1214    /// of this operation. All ordering modes are possible. Note that using
1215    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
1216    /// using [`Release`] makes the load part [`Relaxed`].
1217    ///
1218    /// **Note:** This method is only available on platforms that support atomic
1219    /// operations on `u8`.
1220    ///
1221    /// # Examples
1222    ///
1223    /// ```
1224    /// use std::sync::atomic::{AtomicBool, Ordering};
1225    ///
1226    /// let foo = AtomicBool::new(true);
1227    /// assert_eq!(foo.fetch_nand(false, Ordering::SeqCst), true);
1228    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1229    ///
1230    /// let foo = AtomicBool::new(true);
1231    /// assert_eq!(foo.fetch_nand(true, Ordering::SeqCst), true);
1232    /// assert_eq!(foo.load(Ordering::SeqCst) as usize, 0);
1233    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1234    ///
1235    /// let foo = AtomicBool::new(false);
1236    /// assert_eq!(foo.fetch_nand(false, Ordering::SeqCst), false);
1237    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1238    /// ```
1239    #[inline]
1240    #[stable(feature = "rust1", since = "1.0.0")]
1241    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1242    #[cfg(target_has_atomic = "8")]
1243    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1244    #[rustc_should_not_be_called_on_const_items]
1245    pub const fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
1246        // We can't use atomic_nand here because it can result in a bool with
1247        // an invalid value. This happens because the atomic operation is done
1248        // with an 8-bit integer internally, which would set the upper 7 bits.
1249        // So we just use fetch_xor or swap instead.
1250        if val {
1251            // !(x & true) == !x
1252            // We must invert the bool.
1253            self.fetch_xor(true, order)
1254        } else {
1255            // !(x & false) == true
1256            // We must set the bool to true.
1257            self.swap(true, order)
1258        }
1259    }
1260
1261    /// Logical "or" with a boolean value.
1262    ///
1263    /// Performs a logical "or" operation on the current value and the argument `val`, and sets the
1264    /// new value to the result.
1265    ///
1266    /// Returns the previous value.
1267    ///
1268    /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
1269    /// of this operation. All ordering modes are possible. Note that using
1270    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
1271    /// using [`Release`] makes the load part [`Relaxed`].
1272    ///
1273    /// **Note:** This method is only available on platforms that support atomic
1274    /// operations on `u8`.
1275    ///
1276    /// # Examples
1277    ///
1278    /// ```
1279    /// use std::sync::atomic::{AtomicBool, Ordering};
1280    ///
1281    /// let foo = AtomicBool::new(true);
1282    /// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), true);
1283    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1284    ///
1285    /// let foo = AtomicBool::new(false);
1286    /// assert_eq!(foo.fetch_or(true, Ordering::SeqCst), false);
1287    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1288    ///
1289    /// let foo = AtomicBool::new(false);
1290    /// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), false);
1291    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1292    /// ```
1293    #[inline]
1294    #[stable(feature = "rust1", since = "1.0.0")]
1295    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1296    #[cfg(target_has_atomic = "8")]
1297    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1298    #[rustc_should_not_be_called_on_const_items]
1299    pub const fn fetch_or(&self, val: bool, order: Ordering) -> bool {
1300        // SAFETY: data races are prevented by atomic intrinsics.
1301        unsafe { atomic_or(self.v.get().cast::<u8>(), val as u8, order) != 0 }
1302    }
1303
1304    /// Logical "xor" with a boolean value.
1305    ///
1306    /// Performs a logical "xor" operation on the current value and the argument `val`, and sets
1307    /// the new value to the result.
1308    ///
1309    /// Returns the previous value.
1310    ///
1311    /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
1312    /// of this operation. All ordering modes are possible. Note that using
1313    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
1314    /// using [`Release`] makes the load part [`Relaxed`].
1315    ///
1316    /// **Note:** This method is only available on platforms that support atomic
1317    /// operations on `u8`.
1318    ///
1319    /// # Examples
1320    ///
1321    /// ```
1322    /// use std::sync::atomic::{AtomicBool, Ordering};
1323    ///
1324    /// let foo = AtomicBool::new(true);
1325    /// assert_eq!(foo.fetch_xor(false, Ordering::SeqCst), true);
1326    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1327    ///
1328    /// let foo = AtomicBool::new(true);
1329    /// assert_eq!(foo.fetch_xor(true, Ordering::SeqCst), true);
1330    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1331    ///
1332    /// let foo = AtomicBool::new(false);
1333    /// assert_eq!(foo.fetch_xor(false, Ordering::SeqCst), false);
1334    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1335    /// ```
1336    #[inline]
1337    #[stable(feature = "rust1", since = "1.0.0")]
1338    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1339    #[cfg(target_has_atomic = "8")]
1340    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1341    #[rustc_should_not_be_called_on_const_items]
1342    pub const fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
1343        // SAFETY: data races are prevented by atomic intrinsics.
1344        unsafe { atomic_xor(self.v.get().cast::<u8>(), val as u8, order) != 0 }
1345    }
1346
1347    /// Logical "not" with a boolean value.
1348    ///
1349    /// Performs a logical "not" operation on the current value, and sets
1350    /// the new value to the result.
1351    ///
1352    /// Returns the previous value.
1353    ///
1354    /// `fetch_not` takes an [`Ordering`] argument which describes the memory ordering
1355    /// of this operation. All ordering modes are possible. Note that using
1356    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
1357    /// using [`Release`] makes the load part [`Relaxed`].
1358    ///
1359    /// **Note:** This method is only available on platforms that support atomic
1360    /// operations on `u8`.
1361    ///
1362    /// # Examples
1363    ///
1364    /// ```
1365    /// use std::sync::atomic::{AtomicBool, Ordering};
1366    ///
1367    /// let foo = AtomicBool::new(true);
1368    /// assert_eq!(foo.fetch_not(Ordering::SeqCst), true);
1369    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1370    ///
1371    /// let foo = AtomicBool::new(false);
1372    /// assert_eq!(foo.fetch_not(Ordering::SeqCst), false);
1373    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1374    /// ```
1375    #[inline]
1376    #[stable(feature = "atomic_bool_fetch_not", since = "1.81.0")]
1377    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1378    #[cfg(target_has_atomic = "8")]
1379    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1380    #[rustc_should_not_be_called_on_const_items]
1381    pub const fn fetch_not(&self, order: Ordering) -> bool {
1382        self.fetch_xor(true, order)
1383    }
1384
1385    /// Returns a mutable pointer to the underlying [`bool`].
1386    ///
1387    /// Doing non-atomic reads and writes on the resulting boolean can be a data race.
1388    /// This method is mostly useful for FFI, where the function signature may use
1389    /// `*mut bool` instead of `&AtomicBool`.
1390    ///
1391    /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
1392    /// atomic types work with interior mutability. All modifications of an atomic change the value
1393    /// through a shared reference, and can do so safely as long as they use atomic operations. Any
1394    /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the
1395    /// requirements of the [memory model].
1396    ///
1397    /// # Examples
1398    ///
1399    /// ```ignore (extern-declaration)
1400    /// # fn main() {
1401    /// use std::sync::atomic::AtomicBool;
1402    ///
1403    /// extern "C" {
1404    ///     fn my_atomic_op(arg: *mut bool);
1405    /// }
1406    ///
1407    /// let mut atomic = AtomicBool::new(true);
1408    /// unsafe {
1409    ///     my_atomic_op(atomic.as_ptr());
1410    /// }
1411    /// # }
1412    /// ```
1413    ///
1414    /// [memory model]: self#memory-model-for-atomic-accesses
1415    #[inline]
1416    #[stable(feature = "atomic_as_ptr", since = "1.70.0")]
1417    #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
1418    #[rustc_never_returns_null_ptr]
1419    #[rustc_should_not_be_called_on_const_items]
1420    pub const fn as_ptr(&self) -> *mut bool {
1421        self.v.get().cast()
1422    }
1423
1424    /// An alias for [`AtomicBool::try_update`].
1425    #[inline]
1426    #[stable(feature = "atomic_fetch_update", since = "1.53.0")]
1427    #[cfg(target_has_atomic = "8")]
1428    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1429    #[rustc_should_not_be_called_on_const_items]
1430    #[deprecated(
1431        since = "1.99.0",
1432        note = "renamed to `try_update` for consistency",
1433        suggestion = "try_update"
1434    )]
1435    pub fn fetch_update<F>(
1436        &self,
1437        set_order: Ordering,
1438        fetch_order: Ordering,
1439        f: F,
1440    ) -> Result<bool, bool>
1441    where
1442        F: FnMut(bool) -> Option<bool>,
1443    {
1444        self.try_update(set_order, fetch_order, f)
1445    }
1446
1447    /// Fetches the value, and applies a function to it that returns an optional
1448    /// new value. Returns a `Result` of `Ok(previous_value)` if the function
1449    /// returned `Some(_)`, else `Err(previous_value)`.
1450    ///
1451    /// See also: [`update`](`AtomicBool::update`).
1452    ///
1453    /// Note: This may call the function multiple times if the value has been
1454    /// changed from other threads in the meantime, as long as the function
1455    /// returns `Some(_)`, but the function will have been applied only once to
1456    /// the stored value.
1457    ///
1458    /// `try_update` takes two [`Ordering`] arguments to describe the memory
1459    /// ordering of this operation. The first describes the required ordering for
1460    /// when the operation finally succeeds while the second describes the
1461    /// required ordering for loads. These correspond to the success and failure
1462    /// orderings of [`AtomicBool::compare_exchange`] respectively.
1463    ///
1464    /// Using [`Acquire`] as success ordering makes the store part of this
1465    /// operation [`Relaxed`], and using [`Release`] makes the final successful
1466    /// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`],
1467    /// [`Acquire`] or [`Relaxed`].
1468    ///
1469    /// **Note:** This method is only available on platforms that support atomic
1470    /// operations on `u8`.
1471    ///
1472    /// # Considerations
1473    ///
1474    /// This method is not magic; it is not provided by the hardware, and does not act like a
1475    /// critical section or mutex.
1476    ///
1477    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
1478    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem].
1479    ///
1480    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1481    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
1482    ///
1483    /// # Examples
1484    ///
1485    /// ```rust
1486    /// use std::sync::atomic::{AtomicBool, Ordering};
1487    ///
1488    /// let x = AtomicBool::new(false);
1489    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(false));
1490    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(!x)), Ok(false));
1491    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(!x)), Ok(true));
1492    /// assert_eq!(x.load(Ordering::SeqCst), false);
1493    /// ```
1494    #[inline]
1495    #[stable(feature = "atomic_try_update", since = "1.95.0")]
1496    #[cfg(target_has_atomic = "8")]
1497    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1498    #[rustc_should_not_be_called_on_const_items]
1499    pub fn try_update(
1500        &self,
1501        set_order: Ordering,
1502        fetch_order: Ordering,
1503        mut f: impl FnMut(bool) -> Option<bool>,
1504    ) -> Result<bool, bool> {
1505        let mut prev = self.load(fetch_order);
1506        while let Some(next) = f(prev) {
1507            match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
1508                x @ Ok(_) => return x,
1509                Err(next_prev) => prev = next_prev,
1510            }
1511        }
1512        Err(prev)
1513    }
1514
1515    /// Fetches the value, applies a function to it that it return a new value.
1516    /// The new value is stored and the old value is returned.
1517    ///
1518    /// See also: [`try_update`](`AtomicBool::try_update`).
1519    ///
1520    /// Note: This may call the function multiple times if the value has been changed from other threads in
1521    /// the meantime, but the function will have been applied only once to the stored value.
1522    ///
1523    /// `update` takes two [`Ordering`] arguments to describe the memory
1524    /// ordering of this operation. The first describes the required ordering for
1525    /// when the operation finally succeeds while the second describes the
1526    /// required ordering for loads. These correspond to the success and failure
1527    /// orderings of [`AtomicBool::compare_exchange`] respectively.
1528    ///
1529    /// Using [`Acquire`] as success ordering makes the store part
1530    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
1531    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
1532    ///
1533    /// **Note:** This method is only available on platforms that support atomic operations on `u8`.
1534    ///
1535    /// # Considerations
1536    ///
1537    /// This method is not magic; it is not provided by the hardware, and does not act like a
1538    /// critical section or mutex.
1539    ///
1540    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
1541    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem].
1542    ///
1543    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1544    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
1545    ///
1546    /// # Examples
1547    ///
1548    /// ```rust
1549    ///
1550    /// use std::sync::atomic::{AtomicBool, Ordering};
1551    ///
1552    /// let x = AtomicBool::new(false);
1553    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| !x), false);
1554    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| !x), true);
1555    /// assert_eq!(x.load(Ordering::SeqCst), false);
1556    /// ```
1557    #[inline]
1558    #[stable(feature = "atomic_try_update", since = "1.95.0")]
1559    #[cfg(target_has_atomic = "8")]
1560    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1561    #[rustc_should_not_be_called_on_const_items]
1562    pub fn update(
1563        &self,
1564        set_order: Ordering,
1565        fetch_order: Ordering,
1566        mut f: impl FnMut(bool) -> bool,
1567    ) -> bool {
1568        let mut prev = self.load(fetch_order);
1569        loop {
1570            match self.compare_exchange_weak(prev, f(prev), set_order, fetch_order) {
1571                Ok(x) => break x,
1572                Err(next_prev) => prev = next_prev,
1573            }
1574        }
1575    }
1576}
1577
1578#[cfg(target_has_atomic_load_store = "ptr")]
1579impl<T> AtomicPtr<T> {
1580    /// Creates a new `AtomicPtr`.
1581    ///
1582    /// # Examples
1583    ///
1584    /// ```
1585    /// use std::sync::atomic::AtomicPtr;
1586    ///
1587    /// let ptr = &mut 5;
1588    /// let atomic_ptr = AtomicPtr::new(ptr);
1589    /// ```
1590    #[inline]
1591    #[stable(feature = "rust1", since = "1.0.0")]
1592    #[rustc_const_stable(feature = "const_atomic_new", since = "1.24.0")]
1593    pub const fn new(p: *mut T) -> AtomicPtr<T> {
1594        // SAFETY:
1595        // `Atomic<T>` is essentially a transparent wrapper around `T`.
1596        unsafe { transmute(p) }
1597    }
1598
1599    /// Creates a new `AtomicPtr` from a pointer.
1600    ///
1601    /// # Examples
1602    ///
1603    /// ```
1604    /// use std::sync::atomic::{self, AtomicPtr};
1605    ///
1606    /// // Get a pointer to an allocated value
1607    /// let ptr: *mut *mut u8 = Box::into_raw(Box::new(std::ptr::null_mut()));
1608    ///
1609    /// assert!(ptr.cast::<AtomicPtr<u8>>().is_aligned());
1610    ///
1611    /// {
1612    ///     // Create an atomic view of the allocated value
1613    ///     let atomic = unsafe { AtomicPtr::from_ptr(ptr) };
1614    ///
1615    ///     // Use `atomic` for atomic operations, possibly share it with other threads
1616    ///     atomic.store(std::ptr::NonNull::dangling().as_ptr(), atomic::Ordering::Relaxed);
1617    /// }
1618    ///
1619    /// // It's ok to non-atomically access the value behind `ptr`,
1620    /// // since the reference to the atomic ended its lifetime in the block above
1621    /// assert!(!unsafe { *ptr }.is_null());
1622    ///
1623    /// // Deallocate the value
1624    /// unsafe { drop(Box::from_raw(ptr)) }
1625    /// ```
1626    ///
1627    /// # Safety
1628    ///
1629    /// * `ptr` must be aligned to `align_of::<AtomicPtr<T>>()` (note that on some platforms this
1630    ///   can be bigger than `align_of::<*mut T>()`).
1631    /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
1632    /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
1633    ///   allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different
1634    ///   sizes, without synchronization.
1635    ///
1636    /// [valid]: crate::ptr#safety
1637    /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
1638    #[inline]
1639    #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
1640    #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
1641    pub const unsafe fn from_ptr<'a>(ptr: *mut *mut T) -> &'a AtomicPtr<T> {
1642        // SAFETY: guaranteed by the caller
1643        unsafe { &*ptr.cast() }
1644    }
1645
1646    /// Creates a new pointer to `AtomicPtr` from a pointer.
1647    ///
1648    /// This is useful if you want to do volatile atomic accesses, and thus avoid creating
1649    /// a reference to the destination.
1650    #[inline]
1651    #[unstable(feature = "atomic_volatile", issue = "158947")]
1652    pub const fn from_ptr_raw(ptr: *mut *mut T) -> *const AtomicPtr<T> {
1653        ptr.cast_const().cast()
1654    }
1655
1656    /// Creates a new `AtomicPtr` initialized with a null pointer.
1657    ///
1658    /// # Examples
1659    ///
1660    /// ```
1661    /// #![feature(atomic_ptr_null)]
1662    /// use std::sync::atomic::{AtomicPtr, Ordering};
1663    ///
1664    /// let atomic_ptr = AtomicPtr::<()>::null();
1665    /// assert!(atomic_ptr.load(Ordering::Relaxed).is_null());
1666    /// ```
1667    #[inline]
1668    #[must_use]
1669    #[unstable(feature = "atomic_ptr_null", issue = "150733")]
1670    pub const fn null() -> AtomicPtr<T> {
1671        AtomicPtr::new(crate::ptr::null_mut())
1672    }
1673
1674    /// Returns a mutable reference to the underlying pointer.
1675    ///
1676    /// This is safe because the mutable reference guarantees that no other threads are
1677    /// concurrently accessing the atomic data.
1678    ///
1679    /// # Examples
1680    ///
1681    /// ```
1682    /// use std::sync::atomic::{AtomicPtr, Ordering};
1683    ///
1684    /// let mut data = 10;
1685    /// let mut atomic_ptr = AtomicPtr::new(&mut data);
1686    /// let mut other_data = 5;
1687    /// *atomic_ptr.get_mut() = &mut other_data;
1688    /// assert_eq!(unsafe { *atomic_ptr.load(Ordering::SeqCst) }, 5);
1689    /// ```
1690    #[inline]
1691    #[stable(feature = "atomic_access", since = "1.15.0")]
1692    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1693    pub const fn get_mut(&mut self) -> &mut *mut T {
1694        // SAFETY:
1695        // `Atomic<T>` is essentially a transparent wrapper around `T`.
1696        unsafe { &mut *self.as_ptr() }
1697    }
1698
1699    /// Gets atomic access to a pointer.
1700    ///
1701    /// **Note:** This function is only available on targets where `AtomicPtr<T>` has the same alignment as `*const T`
1702    ///
1703    /// # Examples
1704    ///
1705    /// ```
1706    /// use std::sync::atomic::{AtomicPtr, Ordering};
1707    ///
1708    /// let mut data = 123;
1709    /// let mut some_ptr = &mut data as *mut i32;
1710    /// let a = AtomicPtr::from_mut(&mut some_ptr);
1711    /// let mut other_data = 456;
1712    /// a.store(&mut other_data, Ordering::Relaxed);
1713    /// assert_eq!(unsafe { *some_ptr }, 456);
1714    /// ```
1715    #[inline]
1716    #[cfg(target_has_atomic_primitive_alignment = "ptr")]
1717    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
1718    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1719    pub const fn from_mut(v: &mut *mut T) -> &mut Self {
1720        let [] = [(); align_of::<AtomicPtr<()>>() - align_of::<*mut ()>()];
1721        // SAFETY:
1722        //  - the mutable reference guarantees unique ownership.
1723        //  - the alignment of `*mut T` and `Self` is the same on all platforms
1724        //    supported by rust, as verified above.
1725        unsafe { &mut *(v as *mut *mut T as *mut Self) }
1726    }
1727
1728    /// Gets non-atomic access to a `&mut [AtomicPtr]` slice.
1729    ///
1730    /// This is safe because the mutable reference guarantees that no other threads are
1731    /// concurrently accessing the atomic data.
1732    ///
1733    /// # Examples
1734    ///
1735    /// ```ignore-wasm
1736    /// use std::ptr::null_mut;
1737    /// use std::sync::atomic::{AtomicPtr, Ordering};
1738    ///
1739    /// let mut some_ptrs = [const { AtomicPtr::new(null_mut::<String>()) }; 10];
1740    ///
1741    /// let view: &mut [*mut String] = AtomicPtr::get_mut_slice(&mut some_ptrs);
1742    /// assert_eq!(view, [null_mut::<String>(); 10]);
1743    /// view
1744    ///     .iter_mut()
1745    ///     .enumerate()
1746    ///     .for_each(|(i, ptr)| *ptr = Box::into_raw(Box::new(format!("iteration#{i}"))));
1747    ///
1748    /// std::thread::scope(|s| {
1749    ///     for ptr in &some_ptrs {
1750    ///         s.spawn(move || {
1751    ///             let ptr = ptr.load(Ordering::Relaxed);
1752    ///             assert!(!ptr.is_null());
1753    ///
1754    ///             let name = unsafe { Box::from_raw(ptr) };
1755    ///             println!("Hello, {name}!");
1756    ///         });
1757    ///     }
1758    /// });
1759    /// ```
1760    #[inline]
1761    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
1762    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1763    pub const fn get_mut_slice(this: &mut [Self]) -> &mut [*mut T] {
1764        // SAFETY: the mutable reference guarantees unique ownership.
1765        unsafe { &mut *(this as *mut [Self] as *mut [*mut T]) }
1766    }
1767
1768    /// Gets atomic access to a slice of pointers.
1769    ///
1770    /// **Note:** This function is only available on targets where `AtomicPtr<T>` has the same alignment as `*const T`
1771    ///
1772    /// # Examples
1773    ///
1774    /// ```ignore-wasm
1775    /// use std::ptr::null_mut;
1776    /// use std::sync::atomic::{AtomicPtr, Ordering};
1777    ///
1778    /// let mut some_ptrs = [null_mut::<String>(); 10];
1779    /// let a = &*AtomicPtr::from_mut_slice(&mut some_ptrs);
1780    /// std::thread::scope(|s| {
1781    ///     for i in 0..a.len() {
1782    ///         s.spawn(move || {
1783    ///             let name = Box::new(format!("thread{i}"));
1784    ///             a[i].store(Box::into_raw(name), Ordering::Relaxed);
1785    ///         });
1786    ///     }
1787    /// });
1788    /// for p in some_ptrs {
1789    ///     assert!(!p.is_null());
1790    ///     let name = unsafe { Box::from_raw(p) };
1791    ///     println!("Hello, {name}!");
1792    /// }
1793    /// ```
1794    #[inline]
1795    #[cfg(target_has_atomic_primitive_alignment = "ptr")]
1796    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
1797    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1798    pub const fn from_mut_slice(v: &mut [*mut T]) -> &mut [Self] {
1799        // SAFETY:
1800        //  - the mutable reference guarantees unique ownership.
1801        //  - the alignment of `*mut T` and `Self` is the same on all platforms
1802        //    supported by rust, as verified above.
1803        unsafe { &mut *(v as *mut [*mut T] as *mut [Self]) }
1804    }
1805
1806    /// Consumes the atomic and returns the contained value.
1807    ///
1808    /// This is safe because passing `self` by value guarantees that no other threads are
1809    /// concurrently accessing the atomic data.
1810    ///
1811    /// # Examples
1812    ///
1813    /// ```
1814    /// use std::sync::atomic::AtomicPtr;
1815    ///
1816    /// let mut data = 5;
1817    /// let atomic_ptr = AtomicPtr::new(&mut data);
1818    /// assert_eq!(unsafe { *atomic_ptr.into_inner() }, 5);
1819    /// ```
1820    #[inline]
1821    #[stable(feature = "atomic_access", since = "1.15.0")]
1822    #[rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0")]
1823    pub const fn into_inner(self) -> *mut T {
1824        // SAFETY:
1825        // `Atomic<T>` is essentially a transparent wrapper around `T`.
1826        unsafe { transmute(self) }
1827    }
1828
1829    /// Loads a value from the pointer.
1830    ///
1831    /// `load` takes an [`Ordering`] argument which describes the memory ordering
1832    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
1833    ///
1834    /// # Panics
1835    ///
1836    /// Panics if `order` is [`Release`] or [`AcqRel`].
1837    ///
1838    /// # Examples
1839    ///
1840    /// ```
1841    /// use std::sync::atomic::{AtomicPtr, Ordering};
1842    ///
1843    /// let ptr = &mut 5;
1844    /// let some_ptr = AtomicPtr::new(ptr);
1845    ///
1846    /// let value = some_ptr.load(Ordering::Relaxed);
1847    /// ```
1848    #[inline]
1849    #[stable(feature = "rust1", since = "1.0.0")]
1850    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1851    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1852    pub const fn load(&self, order: Ordering) -> *mut T {
1853        // SAFETY: data races are prevented by atomic intrinsics.
1854        unsafe {
1855            atomic_load::<_, /* VOLATILE */ false>(self.as_ptr(), order)
1856        }
1857    }
1858
1859    /// Perform a volatile atomic load from the pointer.
1860    ///
1861    /// `load_volatile` takes an [`Ordering`] argument which describes the memory ordering
1862    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
1863    ///
1864    #[doc = include_str!("./atomic_load_volatile.md")]
1865    ///
1866    /// # Safety
1867    ///
1868    /// Behavior is undefined if any of the following conditions are violated:
1869    ///
1870    /// * `self` must be [valid] for reads, or `self` must point to memory
1871    ///   outside of all Rust allocations and reading from that memory must:
1872    ///   - not trap, and
1873    ///   - not cause any memory inside a Rust allocation to be modified.
1874    ///
1875    /// * `self` must be aligned to `align_of::<AtomicPtr<T>>()` (note that on some platforms this
1876    ///   can be bigger than `align_of::<*mut T>()`).
1877    ///
1878    /// * Reading from `self` must produce a properly initialized value of type `*mut T`.
1879    ///
1880    /// [valid]: core::ptr#safety
1881    ///
1882    /// # Panics
1883    ///
1884    /// Panics if `order` is [`Release`] or [`AcqRel`].
1885    ///
1886    /// # Examples
1887    ///
1888    /// Assuming an MMIO region at `MMIO_ADDR` that belongs to a device with direct memory
1889    /// access, we may receive a buffer in shared memory from that device as follows:
1890    ///
1891    /// ```rust,no_run
1892    /// #![feature(atomic_volatile)]
1893    /// use std::sync::atomic::{fence, AtomicPtr, Ordering};
1894    /// use std::ptr;
1895    ///
1896    /// const MMIO_ADDR: *mut *mut u8 = ptr::without_provenance_mut(0xCAF0);
1897    /// let atomic_ptr = AtomicPtr::<u8>::from_ptr_raw(MMIO_ADDR);
1898    ///
1899    /// // Spin until we see a non-zero value.
1900    /// let buf = 'buf: loop {
1901    ///     let buf = unsafe { atomic_ptr.load_volatile(Ordering::Relaxed) };
1902    ///     if !buf.is_null() {
1903    ///         break 'buf buf;
1904    ///     }
1905    /// };
1906    /// // Synchronize with the store whose value we just read.
1907    /// // Note: a standard acquire fence may not be sufficient to synchronize with DMA devices.
1908    /// // Depending on your target, you may have to use inline assembly to emit a special fence.
1909    /// fence(Ordering::Acquire);
1910    ///
1911    /// // Now process the data in `buf`.
1912    /// ```
1913    #[inline]
1914    #[unstable(feature = "atomic_volatile", issue = "158947")]
1915    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
1916    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1917    pub const unsafe fn load_volatile(self: *const Self, order: Ordering) -> *mut T {
1918        // SAFETY: follows from our own safety requirements.
1919        unsafe {
1920            atomic_load::<_, /* VOLATILE */ true>(self.cast::<*mut T>(), order)
1921        }
1922    }
1923
1924    /// Stores a value into the pointer.
1925    ///
1926    /// `store` takes an [`Ordering`] argument which describes the memory ordering
1927    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
1928    ///
1929    /// # Panics
1930    ///
1931    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
1932    ///
1933    /// # Examples
1934    ///
1935    /// ```
1936    /// use std::sync::atomic::{AtomicPtr, Ordering};
1937    ///
1938    /// let ptr = &mut 5;
1939    /// let some_ptr = AtomicPtr::new(ptr);
1940    ///
1941    /// let other_ptr = &mut 10;
1942    ///
1943    /// some_ptr.store(other_ptr, Ordering::Relaxed);
1944    /// ```
1945    #[inline]
1946    #[stable(feature = "rust1", since = "1.0.0")]
1947    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1948    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1949    #[rustc_should_not_be_called_on_const_items]
1950    pub const fn store(&self, ptr: *mut T, order: Ordering) {
1951        // SAFETY: data races are prevented by atomic intrinsics.
1952        unsafe {
1953            atomic_store::<_, /* VOLATILE */ false>(self.as_ptr(), ptr, order);
1954        }
1955    }
1956
1957    /// Performs a volatile atomic store into the pointer.
1958    ///
1959    /// `store_volatile` takes an [`Ordering`] argument which describes the memory ordering
1960    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
1961    ///
1962    #[doc = include_str!("./atomic_store_volatile.md")]
1963    ///
1964    /// # Safety
1965    ///
1966    /// Behavior is undefined if any of the following conditions are violated:
1967    ///
1968    /// * `self` must be either [valid] for writes, or `self` must point to memory
1969    ///   outside of all Rust allocations and writing to that memory must:
1970    ///   - not trap, and
1971    ///   - not cause any memory inside a Rust allocation to be modified.
1972    ///
1973    /// * `self` must be aligned to `align_of::<AtomicPtr<T>>()` (note that on some platforms this
1974    ///   can be bigger than `align_of::<*mut T>()`).
1975    ///
1976    /// [valid]: core::ptr#safety
1977    ///
1978    /// # Panics
1979    ///
1980    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
1981    ///
1982    /// # Examples
1983    ///
1984    /// Assuming an MMIO region at `MMIO_ADDR` that belongs to a device with direct memory
1985    /// access, we may submit a buffer in shared memory to that device as follows:
1986    ///
1987    /// ```rust,no_run
1988    /// #![feature(atomic_volatile)]
1989    /// use std::sync::atomic::{fence, AtomicPtr, Ordering};
1990    /// use std::ptr;
1991    ///
1992    /// const MMIO_ADDR: *mut *mut u8 = ptr::without_provenance_mut(0xCAF0);
1993    /// let atomic_ptr = AtomicPtr::<u8>::from_ptr_raw(MMIO_ADDR);
1994    ///
1995    /// // Prepare some data for the DMA device.
1996    /// # fn get_dma_buffer() -> *mut u8 { panic!() }
1997    /// let buf = get_dma_buffer();
1998    ///
1999    /// // Ensure the other side can synchronize with the store we do below.
2000    /// // Note: a standard release fence may not be sufficient to synchronize with DMA devices.
2001    /// // Depending on your target, you may have to use inline assembly to emit a special fence.
2002    /// fence(Ordering::Release);
2003    ///
2004    /// unsafe { atomic_ptr.store_volatile(buf, Ordering::Relaxed) };
2005    /// ```
2006    #[inline]
2007    #[unstable(feature = "atomic_volatile", issue = "158947")]
2008    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
2009    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2010    #[rustc_should_not_be_called_on_const_items]
2011    pub const unsafe fn store_volatile(self: *const Self, ptr: *mut T, order: Ordering) {
2012        // SAFETY: follows from our own safety requirements.
2013        unsafe {
2014            atomic_store::<_, /* VOLATILE */ true>(self.cast::<*mut T>().cast_mut(), ptr, order);
2015        }
2016    }
2017
2018    /// Stores a value into the pointer, returning the previous value.
2019    ///
2020    /// `swap` takes an [`Ordering`] argument which describes the memory ordering
2021    /// of this operation. All ordering modes are possible. Note that using
2022    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2023    /// using [`Release`] makes the load part [`Relaxed`].
2024    ///
2025    /// **Note:** This method is only available on platforms that support atomic
2026    /// operations on pointers.
2027    ///
2028    /// # Examples
2029    ///
2030    /// ```
2031    /// use std::sync::atomic::{AtomicPtr, Ordering};
2032    ///
2033    /// let ptr = &mut 5;
2034    /// let some_ptr = AtomicPtr::new(ptr);
2035    ///
2036    /// let other_ptr = &mut 10;
2037    ///
2038    /// let value = some_ptr.swap(other_ptr, Ordering::Relaxed);
2039    /// ```
2040    #[inline]
2041    #[stable(feature = "rust1", since = "1.0.0")]
2042    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
2043    #[cfg(target_has_atomic = "ptr")]
2044    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2045    #[rustc_should_not_be_called_on_const_items]
2046    pub const fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
2047        // SAFETY: data races are prevented by atomic intrinsics.
2048        unsafe { atomic_swap(self.as_ptr(), ptr, order) }
2049    }
2050
2051    /// Stores a value into the pointer if the current value is the same as the `current` value.
2052    ///
2053    /// The return value is always the previous value. If it is equal to `current`, then the value
2054    /// was updated.
2055    ///
2056    /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
2057    /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
2058    /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
2059    /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
2060    /// happens, and using [`Release`] makes the load part [`Relaxed`].
2061    ///
2062    /// **Note:** This method is only available on platforms that support atomic
2063    /// operations on pointers.
2064    ///
2065    /// # Migrating to `compare_exchange` and `compare_exchange_weak`
2066    ///
2067    /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
2068    /// memory orderings:
2069    ///
2070    /// Original | Success | Failure
2071    /// -------- | ------- | -------
2072    /// Relaxed  | Relaxed | Relaxed
2073    /// Acquire  | Acquire | Acquire
2074    /// Release  | Release | Relaxed
2075    /// AcqRel   | AcqRel  | Acquire
2076    /// SeqCst   | SeqCst  | SeqCst
2077    ///
2078    /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use
2079    /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`,
2080    /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err`
2081    /// rather than to infer success vs failure based on the value that was read.
2082    ///
2083    /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead.
2084    /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
2085    /// which allows the compiler to generate better assembly code when the compare and swap
2086    /// is used in a loop.
2087    ///
2088    /// # Examples
2089    ///
2090    /// ```
2091    /// use std::sync::atomic::{AtomicPtr, Ordering};
2092    ///
2093    /// let ptr = &mut 5;
2094    /// let some_ptr = AtomicPtr::new(ptr);
2095    ///
2096    /// let other_ptr = &mut 10;
2097    ///
2098    /// let value = some_ptr.compare_and_swap(ptr, other_ptr, Ordering::Relaxed);
2099    /// ```
2100    #[inline]
2101    #[stable(feature = "rust1", since = "1.0.0")]
2102    #[deprecated(
2103        since = "1.50.0",
2104        note = "Use `compare_exchange` or `compare_exchange_weak` instead"
2105    )]
2106    #[cfg(target_has_atomic = "ptr")]
2107    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2108    #[rustc_should_not_be_called_on_const_items]
2109    pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) -> *mut T {
2110        match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
2111            Ok(x) => x,
2112            Err(x) => x,
2113        }
2114    }
2115
2116    /// Stores a value into the pointer if the current value is the same as the `current` value.
2117    ///
2118    /// The return value is a result indicating whether the new value was written and containing
2119    /// the previous value. On success this value is guaranteed to be equal to `current`.
2120    ///
2121    /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
2122    /// ordering of this operation. `success` describes the required ordering for the
2123    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
2124    /// `failure` describes the required ordering for the load operation that takes place when
2125    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
2126    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
2127    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
2128    ///
2129    /// **Note:** This method is only available on platforms that support atomic
2130    /// operations on pointers.
2131    ///
2132    /// # Examples
2133    ///
2134    /// ```
2135    /// use std::sync::atomic::{AtomicPtr, Ordering};
2136    ///
2137    /// let ptr = &mut 5;
2138    /// let some_ptr = AtomicPtr::new(ptr);
2139    ///
2140    /// let other_ptr = &mut 10;
2141    ///
2142    /// let value = some_ptr.compare_exchange(ptr, other_ptr,
2143    ///                                       Ordering::SeqCst, Ordering::Relaxed);
2144    /// ```
2145    ///
2146    /// # Considerations
2147    ///
2148    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
2149    /// of CAS operations. In particular, a load of the value followed by a successful
2150    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
2151    /// changed the value in the interim. This is usually important when the *equality* check in
2152    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
2153    /// does not necessarily imply identity. This is a particularly common case for pointers, as
2154    /// a pointer holding the same address does not imply that the same object exists at that
2155    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
2156    ///
2157    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
2158    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
2159    #[inline]
2160    #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
2161    #[cfg(target_has_atomic = "ptr")]
2162    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2163    #[rustc_should_not_be_called_on_const_items]
2164    pub fn compare_exchange(
2165        &self,
2166        current: *mut T,
2167        new: *mut T,
2168        success: Ordering,
2169        failure: Ordering,
2170    ) -> Result<*mut T, *mut T> {
2171        // SAFETY: data races are prevented by atomic intrinsics.
2172        unsafe { atomic_compare_exchange(self.as_ptr(), current, new, success, failure) }
2173    }
2174
2175    /// Stores a value into the pointer if the current value is the same as the `current` value.
2176    ///
2177    /// Unlike [`AtomicPtr::compare_exchange`], this function is allowed to spuriously fail even when the
2178    /// comparison succeeds, which can result in more efficient code on some platforms. The
2179    /// return value is a result indicating whether the new value was written and containing the
2180    /// previous value.
2181    ///
2182    /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
2183    /// ordering of this operation. `success` describes the required ordering for the
2184    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
2185    /// `failure` describes the required ordering for the load operation that takes place when
2186    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
2187    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
2188    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
2189    ///
2190    /// **Note:** This method is only available on platforms that support atomic
2191    /// operations on pointers.
2192    ///
2193    /// # Examples
2194    ///
2195    /// ```
2196    /// use std::sync::atomic::{AtomicPtr, Ordering};
2197    ///
2198    /// let some_ptr = AtomicPtr::new(&mut 5);
2199    ///
2200    /// let new = &mut 10;
2201    /// let mut old = some_ptr.load(Ordering::Relaxed);
2202    /// loop {
2203    ///     match some_ptr.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
2204    ///         Ok(_) => break,
2205    ///         Err(x) => old = x,
2206    ///     }
2207    /// }
2208    /// ```
2209    ///
2210    /// # Considerations
2211    ///
2212    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
2213    /// of CAS operations. In particular, a load of the value followed by a successful
2214    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
2215    /// changed the value in the interim. This is usually important when the *equality* check in
2216    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
2217    /// does not necessarily imply identity. This is a particularly common case for pointers, as
2218    /// a pointer holding the same address does not imply that the same object exists at that
2219    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
2220    ///
2221    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
2222    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
2223    #[inline]
2224    #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
2225    #[cfg(target_has_atomic = "ptr")]
2226    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2227    #[rustc_should_not_be_called_on_const_items]
2228    pub fn compare_exchange_weak(
2229        &self,
2230        current: *mut T,
2231        new: *mut T,
2232        success: Ordering,
2233        failure: Ordering,
2234    ) -> Result<*mut T, *mut T> {
2235        // SAFETY: This intrinsic is unsafe because it operates on a raw pointer
2236        // but we know for sure that the pointer is valid (we just got it from
2237        // an `UnsafeCell` that we have by reference) and the atomic operation
2238        // itself allows us to safely mutate the `UnsafeCell` contents.
2239        unsafe { atomic_compare_exchange_weak(self.as_ptr(), current, new, success, failure) }
2240    }
2241
2242    /// An alias for [`AtomicPtr::try_update`].
2243    #[inline]
2244    #[stable(feature = "atomic_fetch_update", since = "1.53.0")]
2245    #[cfg(target_has_atomic = "ptr")]
2246    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2247    #[rustc_should_not_be_called_on_const_items]
2248    #[deprecated(
2249        since = "1.99.0",
2250        note = "renamed to `try_update` for consistency",
2251        suggestion = "try_update"
2252    )]
2253    pub fn fetch_update<F>(
2254        &self,
2255        set_order: Ordering,
2256        fetch_order: Ordering,
2257        f: F,
2258    ) -> Result<*mut T, *mut T>
2259    where
2260        F: FnMut(*mut T) -> Option<*mut T>,
2261    {
2262        self.try_update(set_order, fetch_order, f)
2263    }
2264    /// Fetches the value, and applies a function to it that returns an optional
2265    /// new value. Returns a `Result` of `Ok(previous_value)` if the function
2266    /// returned `Some(_)`, else `Err(previous_value)`.
2267    ///
2268    /// See also: [`update`](`AtomicPtr::update`).
2269    ///
2270    /// Note: This may call the function multiple times if the value has been
2271    /// changed from other threads in the meantime, as long as the function
2272    /// returns `Some(_)`, but the function will have been applied only once to
2273    /// the stored value.
2274    ///
2275    /// `try_update` takes two [`Ordering`] arguments to describe the memory
2276    /// ordering of this operation. The first describes the required ordering for
2277    /// when the operation finally succeeds while the second describes the
2278    /// required ordering for loads. These correspond to the success and failure
2279    /// orderings of [`AtomicPtr::compare_exchange`] respectively.
2280    ///
2281    /// Using [`Acquire`] as success ordering makes the store part of this
2282    /// operation [`Relaxed`], and using [`Release`] makes the final successful
2283    /// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`],
2284    /// [`Acquire`] or [`Relaxed`].
2285    ///
2286    /// **Note:** This method is only available on platforms that support atomic
2287    /// operations on pointers.
2288    ///
2289    /// # Considerations
2290    ///
2291    /// This method is not magic; it is not provided by the hardware, and does not act like a
2292    /// critical section or mutex.
2293    ///
2294    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
2295    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem],
2296    /// which is a particularly common pitfall for pointers!
2297    ///
2298    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
2299    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
2300    ///
2301    /// # Examples
2302    ///
2303    /// ```rust
2304    /// use std::sync::atomic::{AtomicPtr, Ordering};
2305    ///
2306    /// let ptr: *mut _ = &mut 5;
2307    /// let some_ptr = AtomicPtr::new(ptr);
2308    ///
2309    /// let new: *mut _ = &mut 10;
2310    /// assert_eq!(some_ptr.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(ptr));
2311    /// let result = some_ptr.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| {
2312    ///     if x == ptr {
2313    ///         Some(new)
2314    ///     } else {
2315    ///         None
2316    ///     }
2317    /// });
2318    /// assert_eq!(result, Ok(ptr));
2319    /// assert_eq!(some_ptr.load(Ordering::SeqCst), new);
2320    /// ```
2321    #[inline]
2322    #[stable(feature = "atomic_try_update", since = "1.95.0")]
2323    #[cfg(target_has_atomic = "ptr")]
2324    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2325    #[rustc_should_not_be_called_on_const_items]
2326    pub fn try_update(
2327        &self,
2328        set_order: Ordering,
2329        fetch_order: Ordering,
2330        mut f: impl FnMut(*mut T) -> Option<*mut T>,
2331    ) -> Result<*mut T, *mut T> {
2332        let mut prev = self.load(fetch_order);
2333        while let Some(next) = f(prev) {
2334            match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
2335                x @ Ok(_) => return x,
2336                Err(next_prev) => prev = next_prev,
2337            }
2338        }
2339        Err(prev)
2340    }
2341
2342    /// Fetches the value, applies a function to it that it return a new value.
2343    /// The new value is stored and the old value is returned.
2344    ///
2345    /// See also: [`try_update`](`AtomicPtr::try_update`).
2346    ///
2347    /// Note: This may call the function multiple times if the value has been changed from other threads in
2348    /// the meantime, but the function will have been applied only once to the stored value.
2349    ///
2350    /// `update` takes two [`Ordering`] arguments to describe the memory
2351    /// ordering of this operation. The first describes the required ordering for
2352    /// when the operation finally succeeds while the second describes the
2353    /// required ordering for loads. These correspond to the success and failure
2354    /// orderings of [`AtomicPtr::compare_exchange`] respectively.
2355    ///
2356    /// Using [`Acquire`] as success ordering makes the store part
2357    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
2358    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
2359    ///
2360    /// **Note:** This method is only available on platforms that support atomic
2361    /// operations on pointers.
2362    ///
2363    /// # Considerations
2364    ///
2365    /// This method is not magic; it is not provided by the hardware, and does not act like a
2366    /// critical section or mutex.
2367    ///
2368    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
2369    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem],
2370    /// which is a particularly common pitfall for pointers!
2371    ///
2372    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
2373    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
2374    ///
2375    /// # Examples
2376    ///
2377    /// ```rust
2378    ///
2379    /// use std::sync::atomic::{AtomicPtr, Ordering};
2380    ///
2381    /// let ptr: *mut _ = &mut 5;
2382    /// let some_ptr = AtomicPtr::new(ptr);
2383    ///
2384    /// let new: *mut _ = &mut 10;
2385    /// let result = some_ptr.update(Ordering::SeqCst, Ordering::SeqCst, |_| new);
2386    /// assert_eq!(result, ptr);
2387    /// assert_eq!(some_ptr.load(Ordering::SeqCst), new);
2388    /// ```
2389    #[inline]
2390    #[stable(feature = "atomic_try_update", since = "1.95.0")]
2391    #[cfg(target_has_atomic = "ptr")]
2392    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2393    #[rustc_should_not_be_called_on_const_items]
2394    pub fn update(
2395        &self,
2396        set_order: Ordering,
2397        fetch_order: Ordering,
2398        mut f: impl FnMut(*mut T) -> *mut T,
2399    ) -> *mut T {
2400        let mut prev = self.load(fetch_order);
2401        loop {
2402            match self.compare_exchange_weak(prev, f(prev), set_order, fetch_order) {
2403                Ok(x) => break x,
2404                Err(next_prev) => prev = next_prev,
2405            }
2406        }
2407    }
2408
2409    /// Offsets the pointer's address by adding `val` (in units of `T`),
2410    /// returning the previous pointer.
2411    ///
2412    /// This is equivalent to using [`wrapping_add`] to atomically perform the
2413    /// equivalent of `ptr = ptr.wrapping_add(val);`.
2414    ///
2415    /// This method operates in units of `T`, which means that it cannot be used
2416    /// to offset the pointer by an amount which is not a multiple of
2417    /// `size_of::<T>()`. This can sometimes be inconvenient, as you may want to
2418    /// work with a deliberately misaligned pointer. In such cases, you may use
2419    /// the [`fetch_byte_add`](Self::fetch_byte_add) method instead.
2420    ///
2421    /// `fetch_ptr_add` takes an [`Ordering`] argument which describes the
2422    /// memory ordering of this operation. All ordering modes are possible. Note
2423    /// that using [`Acquire`] makes the store part of this operation
2424    /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].
2425    ///
2426    /// **Note**: This method is only available on platforms that support atomic
2427    /// operations on [`AtomicPtr`].
2428    ///
2429    /// [`wrapping_add`]: pointer::wrapping_add
2430    ///
2431    /// # Examples
2432    ///
2433    /// ```
2434    /// use core::sync::atomic::{AtomicPtr, Ordering};
2435    ///
2436    /// let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());
2437    /// assert_eq!(atom.fetch_ptr_add(1, Ordering::Relaxed).addr(), 0);
2438    /// // Note: units of `size_of::<i64>()`.
2439    /// assert_eq!(atom.load(Ordering::Relaxed).addr(), 8);
2440    /// ```
2441    #[inline]
2442    #[cfg(target_has_atomic = "ptr")]
2443    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2444    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2445    #[rustc_should_not_be_called_on_const_items]
2446    pub fn fetch_ptr_add(&self, val: usize, order: Ordering) -> *mut T {
2447        self.fetch_byte_add(val.wrapping_mul(size_of::<T>()), order)
2448    }
2449
2450    /// Offsets the pointer's address by subtracting `val` (in units of `T`),
2451    /// returning the previous pointer.
2452    ///
2453    /// This is equivalent to using [`wrapping_sub`] to atomically perform the
2454    /// equivalent of `ptr = ptr.wrapping_sub(val);`.
2455    ///
2456    /// This method operates in units of `T`, which means that it cannot be used
2457    /// to offset the pointer by an amount which is not a multiple of
2458    /// `size_of::<T>()`. This can sometimes be inconvenient, as you may want to
2459    /// work with a deliberately misaligned pointer. In such cases, you may use
2460    /// the [`fetch_byte_sub`](Self::fetch_byte_sub) method instead.
2461    ///
2462    /// `fetch_ptr_sub` takes an [`Ordering`] argument which describes the memory
2463    /// ordering of this operation. All ordering modes are possible. Note that
2464    /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
2465    /// and using [`Release`] makes the load part [`Relaxed`].
2466    ///
2467    /// **Note**: This method is only available on platforms that support atomic
2468    /// operations on [`AtomicPtr`].
2469    ///
2470    /// [`wrapping_sub`]: pointer::wrapping_sub
2471    ///
2472    /// # Examples
2473    ///
2474    /// ```
2475    /// use core::sync::atomic::{AtomicPtr, Ordering};
2476    ///
2477    /// let array = [1i32, 2i32];
2478    /// let atom = AtomicPtr::new(array.as_ptr().wrapping_add(1) as *mut _);
2479    ///
2480    /// assert!(core::ptr::eq(
2481    ///     atom.fetch_ptr_sub(1, Ordering::Relaxed),
2482    ///     &array[1],
2483    /// ));
2484    /// assert!(core::ptr::eq(atom.load(Ordering::Relaxed), &array[0]));
2485    /// ```
2486    #[inline]
2487    #[cfg(target_has_atomic = "ptr")]
2488    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2489    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2490    #[rustc_should_not_be_called_on_const_items]
2491    pub fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T {
2492        self.fetch_byte_sub(val.wrapping_mul(size_of::<T>()), order)
2493    }
2494
2495    /// Offsets the pointer's address by adding `val` *bytes*, returning the
2496    /// previous pointer.
2497    ///
2498    /// This is equivalent to using [`wrapping_byte_add`] to atomically
2499    /// perform `ptr = ptr.wrapping_byte_add(val)`.
2500    ///
2501    /// `fetch_byte_add` takes an [`Ordering`] argument which describes the
2502    /// memory ordering of this operation. All ordering modes are possible. Note
2503    /// that using [`Acquire`] makes the store part of this operation
2504    /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].
2505    ///
2506    /// **Note**: This method is only available on platforms that support atomic
2507    /// operations on [`AtomicPtr`].
2508    ///
2509    /// [`wrapping_byte_add`]: pointer::wrapping_byte_add
2510    ///
2511    /// # Examples
2512    ///
2513    /// ```
2514    /// use core::sync::atomic::{AtomicPtr, Ordering};
2515    ///
2516    /// let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());
2517    /// assert_eq!(atom.fetch_byte_add(1, Ordering::Relaxed).addr(), 0);
2518    /// // Note: in units of bytes, not `size_of::<i64>()`.
2519    /// assert_eq!(atom.load(Ordering::Relaxed).addr(), 1);
2520    /// ```
2521    #[inline]
2522    #[cfg(target_has_atomic = "ptr")]
2523    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2524    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2525    #[rustc_should_not_be_called_on_const_items]
2526    pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T {
2527        // SAFETY: data races are prevented by atomic intrinsics.
2528        unsafe { atomic_add(self.as_ptr(), val, order).cast() }
2529    }
2530
2531    /// Offsets the pointer's address by subtracting `val` *bytes*, returning the
2532    /// previous pointer.
2533    ///
2534    /// This is equivalent to using [`wrapping_byte_sub`] to atomically
2535    /// perform `ptr = ptr.wrapping_byte_sub(val)`.
2536    ///
2537    /// `fetch_byte_sub` takes an [`Ordering`] argument which describes the
2538    /// memory ordering of this operation. All ordering modes are possible. Note
2539    /// that using [`Acquire`] makes the store part of this operation
2540    /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].
2541    ///
2542    /// **Note**: This method is only available on platforms that support atomic
2543    /// operations on [`AtomicPtr`].
2544    ///
2545    /// [`wrapping_byte_sub`]: pointer::wrapping_byte_sub
2546    ///
2547    /// # Examples
2548    ///
2549    /// ```
2550    /// use core::sync::atomic::{AtomicPtr, Ordering};
2551    ///
2552    /// let mut arr = [0i64, 1];
2553    /// let atom = AtomicPtr::<i64>::new(&raw mut arr[1]);
2554    /// assert_eq!(atom.fetch_byte_sub(8, Ordering::Relaxed).addr(), (&raw const arr[1]).addr());
2555    /// assert_eq!(atom.load(Ordering::Relaxed).addr(), (&raw const arr[0]).addr());
2556    /// ```
2557    #[inline]
2558    #[cfg(target_has_atomic = "ptr")]
2559    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2560    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2561    #[rustc_should_not_be_called_on_const_items]
2562    pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T {
2563        // SAFETY: data races are prevented by atomic intrinsics.
2564        unsafe { atomic_sub(self.as_ptr(), val, order).cast() }
2565    }
2566
2567    /// Performs a bitwise "or" operation on the address of the current pointer,
2568    /// and the argument `val`, and stores a pointer with provenance of the
2569    /// current pointer and the resulting address.
2570    ///
2571    /// This is equivalent to using [`map_addr`] to atomically perform
2572    /// `ptr = ptr.map_addr(|a| a | val)`. This can be used in tagged
2573    /// pointer schemes to atomically set tag bits.
2574    ///
2575    /// **Caveat**: This operation returns the previous value. To compute the
2576    /// stored value without losing provenance, you may use [`map_addr`]. For
2577    /// example: `a.fetch_or(val).map_addr(|a| a | val)`.
2578    ///
2579    /// `fetch_or` takes an [`Ordering`] argument which describes the memory
2580    /// ordering of this operation. All ordering modes are possible. Note that
2581    /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
2582    /// and using [`Release`] makes the load part [`Relaxed`].
2583    ///
2584    /// **Note**: This method is only available on platforms that support atomic
2585    /// operations on [`AtomicPtr`].
2586    ///
2587    /// This API and its claimed semantics are part of the Strict Provenance
2588    /// experiment, see the [module documentation for `ptr`][crate::ptr] for
2589    /// details.
2590    ///
2591    /// [`map_addr`]: pointer::map_addr
2592    ///
2593    /// # Examples
2594    ///
2595    /// ```
2596    /// use core::sync::atomic::{AtomicPtr, Ordering};
2597    ///
2598    /// let pointer = &mut 3i64 as *mut i64;
2599    ///
2600    /// let atom = AtomicPtr::<i64>::new(pointer);
2601    /// // Tag the bottom bit of the pointer.
2602    /// assert_eq!(atom.fetch_or(1, Ordering::Relaxed).addr() & 1, 0);
2603    /// // Extract and untag.
2604    /// let tagged = atom.load(Ordering::Relaxed);
2605    /// assert_eq!(tagged.addr() & 1, 1);
2606    /// assert_eq!(tagged.map_addr(|p| p & !1), pointer);
2607    /// ```
2608    #[inline]
2609    #[cfg(target_has_atomic = "ptr")]
2610    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2611    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2612    #[rustc_should_not_be_called_on_const_items]
2613    pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T {
2614        // SAFETY: data races are prevented by atomic intrinsics.
2615        unsafe { atomic_or(self.as_ptr(), val, order).cast() }
2616    }
2617
2618    /// Performs a bitwise "and" operation on the address of the current
2619    /// pointer, and the argument `val`, and stores a pointer with provenance of
2620    /// the current pointer and the resulting address.
2621    ///
2622    /// This is equivalent to using [`map_addr`] to atomically perform
2623    /// `ptr = ptr.map_addr(|a| a & val)`. This can be used in tagged
2624    /// pointer schemes to atomically unset tag bits.
2625    ///
2626    /// **Caveat**: This operation returns the previous value. To compute the
2627    /// stored value without losing provenance, you may use [`map_addr`]. For
2628    /// example: `a.fetch_and(val).map_addr(|a| a & val)`.
2629    ///
2630    /// `fetch_and` takes an [`Ordering`] argument which describes the memory
2631    /// ordering of this operation. All ordering modes are possible. Note that
2632    /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
2633    /// and using [`Release`] makes the load part [`Relaxed`].
2634    ///
2635    /// **Note**: This method is only available on platforms that support atomic
2636    /// operations on [`AtomicPtr`].
2637    ///
2638    /// This API and its claimed semantics are part of the Strict Provenance
2639    /// experiment, see the [module documentation for `ptr`][crate::ptr] for
2640    /// details.
2641    ///
2642    /// [`map_addr`]: pointer::map_addr
2643    ///
2644    /// # Examples
2645    ///
2646    /// ```
2647    /// use core::sync::atomic::{AtomicPtr, Ordering};
2648    ///
2649    /// let pointer = &mut 3i64 as *mut i64;
2650    /// // A tagged pointer
2651    /// let atom = AtomicPtr::<i64>::new(pointer.map_addr(|a| a | 1));
2652    /// assert_eq!(atom.fetch_or(1, Ordering::Relaxed).addr() & 1, 1);
2653    /// // Untag, and extract the previously tagged pointer.
2654    /// let untagged = atom.fetch_and(!1, Ordering::Relaxed)
2655    ///     .map_addr(|a| a & !1);
2656    /// assert_eq!(untagged, pointer);
2657    /// ```
2658    #[inline]
2659    #[cfg(target_has_atomic = "ptr")]
2660    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2661    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2662    #[rustc_should_not_be_called_on_const_items]
2663    pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T {
2664        // SAFETY: data races are prevented by atomic intrinsics.
2665        unsafe { atomic_and(self.as_ptr(), val, order).cast() }
2666    }
2667
2668    /// Performs a bitwise "xor" operation on the address of the current
2669    /// pointer, and the argument `val`, and stores a pointer with provenance of
2670    /// the current pointer and the resulting address.
2671    ///
2672    /// This is equivalent to using [`map_addr`] to atomically perform
2673    /// `ptr = ptr.map_addr(|a| a ^ val)`. This can be used in tagged
2674    /// pointer schemes to atomically toggle tag bits.
2675    ///
2676    /// **Caveat**: This operation returns the previous value. To compute the
2677    /// stored value without losing provenance, you may use [`map_addr`]. For
2678    /// example: `a.fetch_xor(val).map_addr(|a| a ^ val)`.
2679    ///
2680    /// `fetch_xor` takes an [`Ordering`] argument which describes the memory
2681    /// ordering of this operation. All ordering modes are possible. Note that
2682    /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
2683    /// and using [`Release`] makes the load part [`Relaxed`].
2684    ///
2685    /// **Note**: This method is only available on platforms that support atomic
2686    /// operations on [`AtomicPtr`].
2687    ///
2688    /// This API and its claimed semantics are part of the Strict Provenance
2689    /// experiment, see the [module documentation for `ptr`][crate::ptr] for
2690    /// details.
2691    ///
2692    /// [`map_addr`]: pointer::map_addr
2693    ///
2694    /// # Examples
2695    ///
2696    /// ```
2697    /// use core::sync::atomic::{AtomicPtr, Ordering};
2698    ///
2699    /// let pointer = &mut 3i64 as *mut i64;
2700    /// let atom = AtomicPtr::<i64>::new(pointer);
2701    ///
2702    /// // Toggle a tag bit on the pointer.
2703    /// atom.fetch_xor(1, Ordering::Relaxed);
2704    /// assert_eq!(atom.load(Ordering::Relaxed).addr() & 1, 1);
2705    /// ```
2706    #[inline]
2707    #[cfg(target_has_atomic = "ptr")]
2708    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2709    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2710    #[rustc_should_not_be_called_on_const_items]
2711    pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T {
2712        // SAFETY: data races are prevented by atomic intrinsics.
2713        unsafe { atomic_xor(self.as_ptr(), val, order).cast() }
2714    }
2715
2716    /// Returns a mutable pointer to the underlying pointer.
2717    ///
2718    /// Doing non-atomic reads and writes on the resulting pointer can be a data race.
2719    /// This method is mostly useful for FFI, where the function signature may use
2720    /// `*mut *mut T` instead of `&AtomicPtr<T>`.
2721    ///
2722    /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
2723    /// atomic types work with interior mutability. All modifications of an atomic change the value
2724    /// through a shared reference, and can do so safely as long as they use atomic operations. Any
2725    /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the
2726    /// requirements of the [memory model].
2727    ///
2728    /// # Examples
2729    ///
2730    /// ```ignore (extern-declaration)
2731    /// use std::sync::atomic::AtomicPtr;
2732    ///
2733    /// extern "C" {
2734    ///     fn my_atomic_op(arg: *mut *mut u32);
2735    /// }
2736    ///
2737    /// let mut value = 17;
2738    /// let atomic = AtomicPtr::new(&mut value);
2739    ///
2740    /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
2741    /// unsafe {
2742    ///     my_atomic_op(atomic.as_ptr());
2743    /// }
2744    /// ```
2745    ///
2746    /// [memory model]: self#memory-model-for-atomic-accesses
2747    #[inline]
2748    #[stable(feature = "atomic_as_ptr", since = "1.70.0")]
2749    #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
2750    #[rustc_never_returns_null_ptr]
2751    pub const fn as_ptr(&self) -> *mut *mut T {
2752        self.v.get().cast()
2753    }
2754}
2755
2756#[cfg(target_has_atomic_load_store = "8")]
2757#[stable(feature = "atomic_bool_from", since = "1.24.0")]
2758#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
2759const impl From<bool> for AtomicBool {
2760    /// Converts a `bool` into an `AtomicBool`.
2761    ///
2762    /// # Examples
2763    ///
2764    /// ```
2765    /// use std::sync::atomic::AtomicBool;
2766    /// let atomic_bool = AtomicBool::from(true);
2767    /// assert_eq!(format!("{atomic_bool:?}"), "true")
2768    /// ```
2769    #[inline]
2770    fn from(b: bool) -> Self {
2771        Self::new(b)
2772    }
2773}
2774
2775#[cfg(target_has_atomic_load_store = "ptr")]
2776#[stable(feature = "atomic_from", since = "1.23.0")]
2777#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
2778const impl<T> From<*mut T> for AtomicPtr<T> {
2779    /// Converts a `*mut T` into an `AtomicPtr<T>`.
2780    #[inline]
2781    fn from(p: *mut T) -> Self {
2782        Self::new(p)
2783    }
2784}
2785
2786#[allow(unused_macros)] // This macro ends up being unused on some architectures.
2787macro_rules! if_8_bit {
2788    (u8, $( yes = [$($yes:tt)*], )? $( no = [$($no:tt)*], )? ) => { concat!("", $($($yes)*)?) };
2789    (i8, $( yes = [$($yes:tt)*], )? $( no = [$($no:tt)*], )? ) => { concat!("", $($($yes)*)?) };
2790    ($_:ident, $( yes = [$($yes:tt)*], )? $( no = [$($no:tt)*], )? ) => { concat!("", $($($no)*)?) };
2791}
2792
2793#[cfg(target_has_atomic_load_store)]
2794macro_rules! atomic_int {
2795    ($cfg_base:meta,
2796     $cfg_cas:meta,
2797     $cfg_align:meta,
2798     $stable:meta,
2799     $stable_cxchg:meta,
2800     $stable_debug:meta,
2801     $stable_access:meta,
2802     $stable_from:meta,
2803     $stable_nand:meta,
2804     $const_stable_new:meta,
2805     $const_stable_into_inner:meta,
2806     $s_int_type:literal,
2807     $extra_feature:expr,
2808     $min_fn:ident, $max_fn:ident,
2809     $align:expr,
2810     $int_type:ident $atomic_type:ident) => {
2811        /// An integer type which can be safely shared between threads.
2812        ///
2813        /// This type has the same
2814        #[doc = if_8_bit!(
2815            $int_type,
2816            yes = ["size, alignment, and bit validity"],
2817            no = ["size and bit validity"],
2818        )]
2819        /// as the underlying integer type, [`
2820        #[doc = $s_int_type]
2821        /// `].
2822        #[doc = if_8_bit! {
2823            $int_type,
2824            no = [
2825                "However, the alignment of this type is always equal to its ",
2826                "size, even on targets where [`", $s_int_type, "`] has a ",
2827                "lesser alignment."
2828            ],
2829        }]
2830        ///
2831        /// For more about the differences between atomic types and
2832        /// non-atomic types as well as information about the portability of
2833        /// this type, please see the [module-level documentation].
2834        ///
2835        /// **Note:** This type is only available on platforms that support
2836        /// atomic loads and stores of [`
2837        #[doc = $s_int_type]
2838        /// `].
2839        ///
2840        /// [module-level documentation]: crate::sync::atomic
2841        #[$stable]
2842        pub type $atomic_type = Atomic<$int_type>;
2843
2844        #[$stable]
2845        impl Default for $atomic_type {
2846            #[inline]
2847            fn default() -> Self {
2848                Self::new(Default::default())
2849            }
2850        }
2851
2852        #[$stable_from]
2853        #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
2854        const impl From<$int_type> for $atomic_type {
2855            #[doc = concat!("Converts an `", stringify!($int_type), "` into an `", stringify!($atomic_type), "`.")]
2856            #[inline]
2857            fn from(v: $int_type) -> Self { Self::new(v) }
2858        }
2859
2860        #[$stable_debug]
2861        impl fmt::Debug for $atomic_type {
2862            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2863                fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
2864            }
2865        }
2866
2867        impl $atomic_type {
2868            /// Creates a new atomic integer.
2869            ///
2870            /// # Examples
2871            ///
2872            #[cfg_attr($cfg_base, doc = "```")]
2873            #[cfg_attr(not($cfg_base), doc = "```compile_fail")]
2874            #[doc = concat!($extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";")]
2875            ///
2876            #[doc = concat!("let atomic_forty_two = ", stringify!($atomic_type), "::new(42);")]
2877            /// ```
2878            #[inline]
2879            #[$stable]
2880            #[$const_stable_new]
2881            #[must_use]
2882            pub const fn new(v: $int_type) -> Self {
2883                // SAFETY:
2884                // `Atomic<T>` is essentially a transparent wrapper around `T`.
2885                unsafe { transmute(v) }
2886            }
2887
2888            /// Creates a new reference to an atomic integer from a pointer.
2889            ///
2890            /// # Examples
2891            ///
2892            #[cfg_attr($cfg_base, doc = "```rust")]
2893            #[cfg_attr(not($cfg_base), doc = "```rust,compile_fail")]
2894            #[doc = concat!($extra_feature, "use std::sync::atomic::{self, ", stringify!($atomic_type), "};")]
2895            ///
2896            /// // Get a pointer to an allocated value
2897            #[doc = concat!("let ptr: *mut ", stringify!($int_type), " = Box::into_raw(Box::new(0));")]
2898            ///
2899            #[doc = concat!("assert!(ptr.cast::<", stringify!($atomic_type), ">().is_aligned());")]
2900            ///
2901            /// {
2902            ///     // Create an atomic view of the allocated value
2903            // SAFETY: this is a doc comment, tidy, it can't hurt you (also guaranteed by the construction of `ptr` and the assert above)
2904            #[doc = concat!("    let atomic = unsafe {", stringify!($atomic_type), "::from_ptr(ptr) };")]
2905            ///
2906            ///     // Use `atomic` for atomic operations, possibly share it with other threads
2907            ///     atomic.store(1, atomic::Ordering::Relaxed);
2908            /// }
2909            ///
2910            /// // It's ok to non-atomically access the value behind `ptr`,
2911            /// // since the reference to the atomic ended its lifetime in the block above
2912            /// assert_eq!(unsafe { *ptr }, 1);
2913            ///
2914            /// // Deallocate the value
2915            /// unsafe { drop(Box::from_raw(ptr)) }
2916            /// ```
2917            ///
2918            /// # Safety
2919            ///
2920            /// * `ptr` must be aligned to
2921            #[doc = concat!("  `align_of::<", stringify!($atomic_type), ">()`")]
2922            #[doc = if_8_bit!{
2923                $int_type,
2924                yes = [
2925                    "  (note that this is always true, since `align_of::<",
2926                    stringify!($atomic_type), ">() == 1`)."
2927                ],
2928                no = [
2929                    "  (note that on some platforms this can be bigger than `align_of::<",
2930                    stringify!($int_type), ">()`)."
2931                ],
2932            }]
2933            /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
2934            /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
2935            ///   allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different
2936            ///   sizes, without synchronization.
2937            ///
2938            /// [valid]: crate::ptr#safety
2939            /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
2940            #[inline]
2941            #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
2942            #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
2943            pub const unsafe fn from_ptr<'a>(ptr: *mut $int_type) -> &'a $atomic_type {
2944                // SAFETY: guaranteed by the caller
2945                unsafe { &*ptr.cast() }
2946            }
2947
2948            /// Creates a new pointer to an atomic integer from a pointer.
2949            ///
2950            /// This is useful if you want to do volatile atomic accesses, and thus avoid creating
2951            /// a reference to the destination.
2952            #[inline]
2953            #[unstable(feature = "atomic_volatile", issue = "158947")]
2954            pub const fn from_ptr_raw(ptr: *mut $int_type) -> *const $atomic_type {
2955                ptr.cast_const().cast()
2956            }
2957
2958            /// Returns a mutable reference to the underlying integer.
2959            ///
2960            /// This is safe because the mutable reference guarantees that no other threads are
2961            /// concurrently accessing the atomic data.
2962            ///
2963            /// # Examples
2964            ///
2965            #[cfg_attr($cfg_base, doc = "```")]
2966            #[cfg_attr(not($cfg_base), doc = "```compile_fail")]
2967            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2968            ///
2969            #[doc = concat!("let mut some_var = ", stringify!($atomic_type), "::new(10);")]
2970            /// assert_eq!(*some_var.get_mut(), 10);
2971            /// *some_var.get_mut() = 5;
2972            /// assert_eq!(some_var.load(Ordering::SeqCst), 5);
2973            /// ```
2974            #[inline]
2975            #[$stable_access]
2976            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
2977            pub const fn get_mut(&mut self) -> &mut $int_type {
2978                // SAFETY:
2979                // `Atomic<T>` is essentially a transparent wrapper around `T`.
2980                unsafe { &mut *self.as_ptr() }
2981            }
2982
2983            #[doc = concat!("Get atomic access to a `&mut ", stringify!($int_type), "`.")]
2984            ///
2985            #[doc = if_8_bit! {
2986                $int_type,
2987                no = [
2988                    "**Note:** This function is only available on targets where `",
2989                    stringify!($atomic_type), "` has the same alignment as `", stringify!($int_type), "`."
2990                ],
2991            }]
2992            ///
2993            /// # Examples
2994            ///
2995            #[cfg_attr($cfg_align, doc = "```rust")]
2996            #[cfg_attr(not($cfg_align), doc = "```rust,compile_fail")]
2997            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2998            ///
2999            /// let mut some_int = 123;
3000            #[doc = concat!("let a = ", stringify!($atomic_type), "::from_mut(&mut some_int);")]
3001            /// a.store(100, Ordering::Relaxed);
3002            /// assert_eq!(some_int, 100);
3003            /// ```
3004            ///
3005            #[inline]
3006            #[cfg(any($cfg_align, doc))]
3007            #[stable(feature = "atomic_from_mut", since = "1.98.0")]
3008            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3009            pub const fn from_mut(v: &mut $int_type) -> &mut Self {
3010                let [] = [(); align_of::<Self>() - align_of::<$int_type>()];
3011                // SAFETY:
3012                //  - the mutable reference guarantees unique ownership.
3013                //  - the alignment of `$int_type` and `Self` is the
3014                //    same, as promised by $cfg_align and verified above.
3015                unsafe { &mut *(v as *mut $int_type as *mut Self) }
3016            }
3017
3018            #[doc = concat!("Get non-atomic access to a `&mut [", stringify!($atomic_type), "]` slice")]
3019            ///
3020            /// This is safe because the mutable reference guarantees that no other threads are
3021            /// concurrently accessing the atomic data.
3022            ///
3023            /// # Examples
3024            ///
3025            #[cfg_attr($cfg_base, doc = "```ignore-wasm")]
3026            #[cfg_attr(not($cfg_base), doc = "```ignore-wasm,compile_fail")]
3027            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3028            ///
3029            #[doc = concat!("let mut some_ints = [const { ", stringify!($atomic_type), "::new(0) }; 10];")]
3030            ///
3031            #[doc = concat!("let view: &mut [", stringify!($int_type), "] = ", stringify!($atomic_type), "::get_mut_slice(&mut some_ints);")]
3032            /// assert_eq!(view, [0; 10]);
3033            /// view
3034            ///     .iter_mut()
3035            ///     .enumerate()
3036            ///     .for_each(|(idx, int)| *int = idx as _);
3037            ///
3038            /// std::thread::scope(|s| {
3039            ///     some_ints
3040            ///         .iter()
3041            ///         .enumerate()
3042            ///         .for_each(|(idx, int)| {
3043            ///             s.spawn(move || assert_eq!(int.load(Ordering::Relaxed), idx as _));
3044            ///         })
3045            /// });
3046            /// ```
3047            #[inline]
3048            #[stable(feature = "atomic_from_mut", since = "1.98.0")]
3049            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3050            pub const fn get_mut_slice(this: &mut [Self]) -> &mut [$int_type] {
3051                // SAFETY: the mutable reference guarantees unique ownership.
3052                unsafe { &mut *(this as *mut [Self] as *mut [$int_type]) }
3053            }
3054
3055            #[doc = concat!("Get atomic access to a `&mut [", stringify!($int_type), "]` slice.")]
3056            ///
3057            #[doc = if_8_bit! {
3058                $int_type,
3059                no = [
3060                    "**Note:** This function is only available on targets where `",
3061                    stringify!($atomic_type), "` has the same alignment as `", stringify!($int_type), "`."
3062                ],
3063            }]
3064            ///
3065            /// # Examples
3066            ///
3067            #[cfg_attr($cfg_align, doc = "```ignore-wasm")]
3068            #[cfg_attr(not($cfg_align), doc = "```ignore-wasm,compile_fail")]
3069            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3070            ///
3071            /// let mut some_ints = [0; 10];
3072            #[doc = concat!("let a = &*", stringify!($atomic_type), "::from_mut_slice(&mut some_ints);")]
3073            /// std::thread::scope(|s| {
3074            ///     for i in 0..a.len() {
3075            ///         s.spawn(move || a[i].store(i as _, Ordering::Relaxed));
3076            ///     }
3077            /// });
3078            /// for (i, n) in some_ints.into_iter().enumerate() {
3079            ///     assert_eq!(i, n as usize);
3080            /// }
3081            /// ```
3082            #[inline]
3083            #[cfg(any($cfg_align, doc))]
3084            #[stable(feature = "atomic_from_mut", since = "1.98.0")]
3085            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3086            pub const fn from_mut_slice(v: &mut [$int_type]) -> &mut [Self] {
3087                let [] = [(); align_of::<Self>() - align_of::<$int_type>()];
3088                // SAFETY:
3089                //  - the mutable reference guarantees unique ownership.
3090                //  - the alignment of `$int_type` and `Self` is the
3091                //    same, as promised by $cfg_align and verified above.
3092                unsafe { &mut *(v as *mut [$int_type] as *mut [Self]) }
3093            }
3094
3095            /// Consumes the atomic and returns the contained value.
3096            ///
3097            /// This is safe because passing `self` by value guarantees that no other threads are
3098            /// concurrently accessing the atomic data.
3099            ///
3100            /// # Examples
3101            ///
3102            #[cfg_attr($cfg_base, doc = "```")]
3103            #[cfg_attr(not($cfg_base), doc = "```compile_fail")]
3104            #[doc = concat!($extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";")]
3105            ///
3106            #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
3107            /// assert_eq!(some_var.into_inner(), 5);
3108            /// ```
3109            #[inline]
3110            #[$stable_access]
3111            #[$const_stable_into_inner]
3112            pub const fn into_inner(self) -> $int_type {
3113                // SAFETY:
3114                // `Atomic<T>` is essentially a transparent wrapper around `T`.
3115                unsafe { transmute(self) }
3116            }
3117
3118            /// Loads a value from the atomic integer.
3119            ///
3120            /// `load` takes an [`Ordering`] argument which describes the memory ordering of this operation.
3121            /// Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
3122            ///
3123            /// # Panics
3124            ///
3125            /// Panics if `order` is [`Release`] or [`AcqRel`].
3126            ///
3127            /// # Examples
3128            ///
3129            #[cfg_attr($cfg_base, doc = "```")]
3130            #[cfg_attr(not($cfg_base), doc = "```compile_fail")]
3131            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3132            ///
3133            #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
3134            ///
3135            /// assert_eq!(some_var.load(Ordering::Relaxed), 5);
3136            /// ```
3137            #[inline]
3138            #[$stable]
3139            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3140            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3141            pub const fn load(&self, order: Ordering) -> $int_type {
3142                // SAFETY: data races are prevented by atomic intrinsics.
3143                unsafe { atomic_load::<_, /* VOLATILE */ false>(self.as_ptr(), order) }
3144            }
3145
3146            /// Perform a volatile load from the atomic integer.
3147            ///
3148            /// `load_volatile` takes an [`Ordering`] argument which describes the memory ordering
3149            /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
3150            ///
3151            #[doc = include_str!("./atomic_load_volatile.md")]
3152            ///
3153            /// # Safety
3154            ///
3155            /// Behavior is undefined if any of the following conditions are violated:
3156            ///
3157            /// * `self` must be [valid] for reads, or `self` must point to memory
3158            ///   outside of all Rust allocations and reading from that memory must:
3159            ///   - not trap, and
3160            ///   - not cause any memory inside a Rust allocation to be modified.
3161            ///
3162            /// * `self` must be aligned to
3163            #[doc = concat!("  `align_of::<", stringify!($atomic_type), ">()`")]
3164            #[doc = if_8_bit!{
3165                $int_type,
3166                yes = [
3167                    "  (note that this is always true, since `align_of::<",
3168                    stringify!($atomic_type), ">() == 1`)."
3169                ],
3170                no = [
3171                    "  (note that on some platforms this can be bigger than `align_of::<",
3172                    stringify!($int_type), ">()`)."
3173                ],
3174            }]
3175            ///
3176            /// * Reading from `self` must produce a properly initialized value of the underlying
3177            ///   integer type.
3178            ///
3179            /// [valid]: core::ptr#safety
3180            ///
3181            /// # Panics
3182            ///
3183            /// Panics if `order` is [`Release`] or [`AcqRel`].
3184            #[inline]
3185            #[unstable(feature = "atomic_volatile", issue = "158947")]
3186            #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
3187            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3188            pub const unsafe fn load_volatile(self: *const Self, order: Ordering) -> $int_type {
3189                // SAFETY: follows from our own safety requirements.
3190                unsafe {
3191                    atomic_load::<_, /* VOLATILE */ true>(self.cast::<$int_type>(), order)
3192                }
3193            }
3194
3195            /// Stores a value into the atomic integer.
3196            ///
3197            /// `store` takes an [`Ordering`] argument which describes the memory ordering of this operation.
3198            ///  Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
3199            ///
3200            /// # Panics
3201            ///
3202            /// Panics if `order` is [`Acquire`] or [`AcqRel`].
3203            ///
3204            /// # Examples
3205            ///
3206            #[cfg_attr($cfg_base, doc = "```")]
3207            #[cfg_attr(not($cfg_base), doc = "```compile_fail")]
3208            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3209            ///
3210            #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
3211            ///
3212            /// some_var.store(10, Ordering::Relaxed);
3213            /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
3214            /// ```
3215            #[inline]
3216            #[$stable]
3217            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3218            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3219            #[rustc_should_not_be_called_on_const_items]
3220            pub const fn store(&self, val: $int_type, order: Ordering) {
3221                // SAFETY: data races are prevented by atomic intrinsics.
3222                unsafe { atomic_store::<_, /* VOLATILE */ false>(self.as_ptr(), val, order); }
3223            }
3224
3225            /// Performs a volatile store into the atomic integer.
3226            ///
3227            /// `store_volatile` takes an [`Ordering`] argument which describes the memory ordering
3228            /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
3229            ///
3230            #[doc = include_str!("./atomic_store_volatile.md")]
3231            ///
3232            /// # Safety
3233            ///
3234            /// Behavior is undefined if any of the following conditions are violated:
3235            ///
3236            /// * `self` must be either [valid] for writes, or `self` must point to memory
3237            ///   outside of all Rust allocations and writing to that memory must:
3238            ///   - not trap, and
3239            ///   - not cause any memory inside a Rust allocation to be modified.
3240            ///
3241            /// * `self` must be aligned to
3242            #[doc = concat!("  `align_of::<", stringify!($atomic_type), ">()`")]
3243            #[doc = if_8_bit!{
3244                $int_type,
3245                yes = [
3246                    "  (note that this is always true, since `align_of::<",
3247                    stringify!($atomic_type), ">() == 1`)."
3248                ],
3249                no = [
3250                    "  (note that on some platforms this can be bigger than `align_of::<",
3251                    stringify!($int_type), ">()`)."
3252                ],
3253            }]
3254            ///
3255            /// [valid]: core::ptr#safety
3256            ///
3257            /// # Panics
3258            ///
3259            /// Panics if `order` is [`Acquire`] or [`AcqRel`].
3260            #[inline]
3261            #[unstable(feature = "atomic_volatile", issue = "158947")]
3262            #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
3263            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3264            #[rustc_should_not_be_called_on_const_items]
3265            pub const unsafe fn store_volatile(self: *const Self, val: $int_type, order: Ordering) {
3266                // SAFETY: follows from our own safety requirements.
3267                unsafe {
3268                    atomic_store::<_, /* VOLATILE */ true>(self.cast::<$int_type>().cast_mut(), val, order);
3269                }
3270            }
3271
3272            /// Stores a value into the atomic integer, returning the previous value.
3273            ///
3274            /// `swap` takes an [`Ordering`] argument which describes the memory ordering
3275            /// of this operation. All ordering modes are possible. Note that using
3276            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3277            /// using [`Release`] makes the load part [`Relaxed`].
3278            ///
3279            /// **Note**: This method is only available on platforms that support atomic operations on
3280            #[doc = concat!("[`", $s_int_type, "`].")]
3281            ///
3282            /// # Examples
3283            ///
3284            #[cfg_attr($cfg_cas, doc = "```")]
3285            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3286            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3287            ///
3288            #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
3289            ///
3290            /// assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
3291            /// ```
3292            #[inline]
3293            #[$stable]
3294            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3295            #[cfg(any($cfg_cas, doc))]
3296            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3297            #[rustc_should_not_be_called_on_const_items]
3298            pub const fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
3299                // SAFETY: data races are prevented by atomic intrinsics.
3300                unsafe { atomic_swap(self.as_ptr(), val, order) }
3301            }
3302
3303            /// Stores a value into the atomic integer if the current value is the same as
3304            /// the `current` value.
3305            ///
3306            /// The return value is always the previous value. If it is equal to `current`, then the
3307            /// value was updated.
3308            ///
3309            /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
3310            /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
3311            /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
3312            /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
3313            /// happens, and using [`Release`] makes the load part [`Relaxed`].
3314            ///
3315            /// **Note**: This method is only available on platforms that support atomic operations on
3316            #[doc = concat!("[`", $s_int_type, "`].")]
3317            ///
3318            /// # Migrating to `compare_exchange` and `compare_exchange_weak`
3319            ///
3320            /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
3321            /// memory orderings:
3322            ///
3323            /// Original | Success | Failure
3324            /// -------- | ------- | -------
3325            /// Relaxed  | Relaxed | Relaxed
3326            /// Acquire  | Acquire | Acquire
3327            /// Release  | Release | Relaxed
3328            /// AcqRel   | AcqRel  | Acquire
3329            /// SeqCst   | SeqCst  | SeqCst
3330            ///
3331            /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use
3332            /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`,
3333            /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err`
3334            /// rather than to infer success vs failure based on the value that was read.
3335            ///
3336            /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead.
3337            /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
3338            /// which allows the compiler to generate better assembly code when the compare and swap
3339            /// is used in a loop.
3340            ///
3341            /// # Examples
3342            ///
3343            #[cfg_attr($cfg_cas, doc = "```")]
3344            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3345            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3346            ///
3347            #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
3348            ///
3349            /// assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5);
3350            /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
3351            ///
3352            /// assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10);
3353            /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
3354            /// ```
3355            #[inline]
3356            #[$stable]
3357            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3358            #[deprecated(
3359                since = "1.50.0",
3360                note = "Use `compare_exchange` or `compare_exchange_weak` instead")
3361            ]
3362            #[cfg(any($cfg_cas, doc))]
3363            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3364            #[rustc_should_not_be_called_on_const_items]
3365            pub const fn compare_and_swap(&self,
3366                                    current: $int_type,
3367                                    new: $int_type,
3368                                    order: Ordering) -> $int_type {
3369                match self.compare_exchange(current,
3370                                            new,
3371                                            order,
3372                                            strongest_failure_ordering(order)) {
3373                    Ok(x) => x,
3374                    Err(x) => x,
3375                }
3376            }
3377
3378            /// Stores a value into the atomic integer if the current value is the same as
3379            /// the `current` value.
3380            ///
3381            /// The return value is a result indicating whether the new value was written and
3382            /// containing the previous value. On success this value is guaranteed to be equal to
3383            /// `current`.
3384            ///
3385            /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
3386            /// ordering of this operation. `success` describes the required ordering for the
3387            /// read-modify-write operation that takes place if the comparison with `current` succeeds.
3388            /// `failure` describes the required ordering for the load operation that takes place when
3389            /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
3390            /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
3391            /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
3392            ///
3393            /// **Note**: This method is only available on platforms that support atomic operations on
3394            #[doc = concat!("[`", $s_int_type, "`].")]
3395            ///
3396            /// # Examples
3397            ///
3398            #[cfg_attr($cfg_cas, doc = "```")]
3399            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3400            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3401            ///
3402            #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
3403            ///
3404            /// assert_eq!(some_var.compare_exchange(5, 10,
3405            ///                                      Ordering::Acquire,
3406            ///                                      Ordering::Relaxed),
3407            ///            Ok(5));
3408            /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
3409            ///
3410            /// assert_eq!(some_var.compare_exchange(6, 12,
3411            ///                                      Ordering::SeqCst,
3412            ///                                      Ordering::Acquire),
3413            ///            Err(10));
3414            /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
3415            /// ```
3416            ///
3417            /// # Considerations
3418            ///
3419            /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
3420            /// of CAS operations. In particular, a load of the value followed by a successful
3421            /// `compare_exchange` with the previous load *does not ensure* that other threads have not
3422            /// changed the value in the interim! This is usually important when the *equality* check in
3423            /// the `compare_exchange` is being used to check the *identity* of a value, but equality
3424            /// does not necessarily imply identity. This is a particularly common case for pointers, as
3425            /// a pointer holding the same address does not imply that the same object exists at that
3426            /// address! In this case, `compare_exchange` can lead to the [ABA problem].
3427            ///
3428            /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
3429            /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
3430            #[inline]
3431            #[$stable_cxchg]
3432            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3433            #[cfg(any($cfg_cas, doc))]
3434            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3435            #[rustc_should_not_be_called_on_const_items]
3436            pub const fn compare_exchange(&self,
3437                                    current: $int_type,
3438                                    new: $int_type,
3439                                    success: Ordering,
3440                                    failure: Ordering) -> Result<$int_type, $int_type> {
3441                // SAFETY: data races are prevented by atomic intrinsics.
3442                unsafe { atomic_compare_exchange(self.as_ptr(), current, new, success, failure) }
3443            }
3444
3445            /// Stores a value into the atomic integer if the current value is the same as
3446            /// the `current` value.
3447            ///
3448            #[doc = concat!("Unlike [`", stringify!($atomic_type), "::compare_exchange`],")]
3449            /// this function is allowed to spuriously fail even
3450            /// when the comparison succeeds, which can result in more efficient code on some
3451            /// platforms. The return value is a result indicating whether the new value was
3452            /// written and containing the previous value.
3453            ///
3454            /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
3455            /// ordering of this operation. `success` describes the required ordering for the
3456            /// read-modify-write operation that takes place if the comparison with `current` succeeds.
3457            /// `failure` describes the required ordering for the load operation that takes place when
3458            /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
3459            /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
3460            /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
3461            ///
3462            /// **Note**: This method is only available on platforms that support atomic operations on
3463            #[doc = concat!("[`", $s_int_type, "`].")]
3464            ///
3465            /// # Examples
3466            ///
3467            #[cfg_attr($cfg_cas, doc = "```")]
3468            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3469            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3470            ///
3471            #[doc = concat!("let val = ", stringify!($atomic_type), "::new(4);")]
3472            ///
3473            /// let mut old = val.load(Ordering::Relaxed);
3474            /// loop {
3475            ///     let new = old * 2;
3476            ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
3477            ///         Ok(_) => break,
3478            ///         Err(x) => old = x,
3479            ///     }
3480            /// }
3481            /// ```
3482            ///
3483            /// # Considerations
3484            ///
3485            /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
3486            /// of CAS operations. In particular, a load of the value followed by a successful
3487            /// `compare_exchange` with the previous load *does not ensure* that other threads have not
3488            /// changed the value in the interim. This is usually important when the *equality* check in
3489            /// the `compare_exchange` is being used to check the *identity* of a value, but equality
3490            /// does not necessarily imply identity. This is a particularly common case for pointers, as
3491            /// a pointer holding the same address does not imply that the same object exists at that
3492            /// address! In this case, `compare_exchange` can lead to the [ABA problem].
3493            ///
3494            /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
3495            /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
3496            #[inline]
3497            #[$stable_cxchg]
3498            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3499            #[cfg(any($cfg_cas, doc))]
3500            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3501            #[rustc_should_not_be_called_on_const_items]
3502            pub const fn compare_exchange_weak(&self,
3503                                         current: $int_type,
3504                                         new: $int_type,
3505                                         success: Ordering,
3506                                         failure: Ordering) -> Result<$int_type, $int_type> {
3507                // SAFETY: data races are prevented by atomic intrinsics.
3508                unsafe {
3509                    atomic_compare_exchange_weak(self.as_ptr(), current, new, success, failure)
3510                }
3511            }
3512
3513            /// Adds to the current value, returning the previous value.
3514            ///
3515            /// This operation wraps around on overflow.
3516            ///
3517            /// `fetch_add` takes an [`Ordering`] argument which describes the memory ordering
3518            /// of this operation. All ordering modes are possible. Note that using
3519            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3520            /// using [`Release`] makes the load part [`Relaxed`].
3521            ///
3522            /// **Note**: This method is only available on platforms that support atomic operations on
3523            #[doc = concat!("[`", $s_int_type, "`].")]
3524            ///
3525            /// # Examples
3526            ///
3527            #[cfg_attr($cfg_cas, doc = "```")]
3528            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3529            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3530            ///
3531            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0);")]
3532            /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
3533            /// assert_eq!(foo.load(Ordering::SeqCst), 10);
3534            /// ```
3535            #[inline]
3536            #[$stable]
3537            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3538            #[cfg(any($cfg_cas, doc))]
3539            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3540            #[rustc_should_not_be_called_on_const_items]
3541            pub const fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
3542                // SAFETY: data races are prevented by atomic intrinsics.
3543                unsafe { atomic_add(self.as_ptr(), val, order) }
3544            }
3545
3546            /// Subtracts from the current value, returning the previous value.
3547            ///
3548            /// This operation wraps around on overflow.
3549            ///
3550            /// `fetch_sub` takes an [`Ordering`] argument which describes the memory ordering
3551            /// of this operation. All ordering modes are possible. Note that using
3552            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3553            /// using [`Release`] makes the load part [`Relaxed`].
3554            ///
3555            /// **Note**: This method is only available on platforms that support atomic operations on
3556            #[doc = concat!("[`", $s_int_type, "`].")]
3557            ///
3558            /// # Examples
3559            ///
3560            #[cfg_attr($cfg_cas, doc = "```")]
3561            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3562            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3563            ///
3564            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(20);")]
3565            /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);
3566            /// assert_eq!(foo.load(Ordering::SeqCst), 10);
3567            /// ```
3568            #[inline]
3569            #[$stable]
3570            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3571            #[cfg(any($cfg_cas, doc))]
3572            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3573            #[rustc_should_not_be_called_on_const_items]
3574            pub const fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
3575                // SAFETY: data races are prevented by atomic intrinsics.
3576                unsafe { atomic_sub(self.as_ptr(), val, order) }
3577            }
3578
3579            /// Bitwise "and" with the current value.
3580            ///
3581            /// Performs a bitwise "and" operation on the current value and the argument `val`, and
3582            /// sets the new value to the result.
3583            ///
3584            /// Returns the previous value.
3585            ///
3586            /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
3587            /// of this operation. All ordering modes are possible. Note that using
3588            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3589            /// using [`Release`] makes the load part [`Relaxed`].
3590            ///
3591            /// **Note**: This method is only available on platforms that support atomic operations on
3592            #[doc = concat!("[`", $s_int_type, "`].")]
3593            ///
3594            /// # Examples
3595            ///
3596            #[cfg_attr($cfg_cas, doc = "```")]
3597            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3598            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3599            ///
3600            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0b101101);")]
3601            /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
3602            /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
3603            /// ```
3604            #[inline]
3605            #[$stable]
3606            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3607            #[cfg(any($cfg_cas, doc))]
3608            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3609            #[rustc_should_not_be_called_on_const_items]
3610            pub const fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
3611                // SAFETY: data races are prevented by atomic intrinsics.
3612                unsafe { atomic_and(self.as_ptr(), val, order) }
3613            }
3614
3615            /// Bitwise "nand" with the current value.
3616            ///
3617            /// Performs a bitwise "nand" operation on the current value and the argument `val`, and
3618            /// sets the new value to the result.
3619            ///
3620            /// Returns the previous value.
3621            ///
3622            /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
3623            /// of this operation. All ordering modes are possible. Note that using
3624            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3625            /// using [`Release`] makes the load part [`Relaxed`].
3626            ///
3627            /// **Note**: This method is only available on platforms that support atomic operations on
3628            #[doc = concat!("[`", $s_int_type, "`].")]
3629            ///
3630            /// # Examples
3631            ///
3632            #[cfg_attr($cfg_cas, doc = "```")]
3633            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3634            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3635            ///
3636            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0x13);")]
3637            /// assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);
3638            /// assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
3639            /// ```
3640            #[inline]
3641            #[$stable_nand]
3642            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3643            #[cfg(any($cfg_cas, doc))]
3644            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3645            #[rustc_should_not_be_called_on_const_items]
3646            pub const fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
3647                // SAFETY: data races are prevented by atomic intrinsics.
3648                unsafe { atomic_nand(self.as_ptr(), val, order) }
3649            }
3650
3651            /// Bitwise "or" with the current value.
3652            ///
3653            /// Performs a bitwise "or" operation on the current value and the argument `val`, and
3654            /// sets the new value to the result.
3655            ///
3656            /// Returns the previous value.
3657            ///
3658            /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
3659            /// of this operation. All ordering modes are possible. Note that using
3660            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3661            /// using [`Release`] makes the load part [`Relaxed`].
3662            ///
3663            /// **Note**: This method is only available on platforms that support atomic operations on
3664            #[doc = concat!("[`", $s_int_type, "`].")]
3665            ///
3666            /// # Examples
3667            ///
3668            #[cfg_attr($cfg_cas, doc = "```")]
3669            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3670            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3671            ///
3672            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0b101101);")]
3673            /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
3674            /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
3675            /// ```
3676            #[inline]
3677            #[$stable]
3678            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3679            #[cfg(any($cfg_cas, doc))]
3680            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3681            #[rustc_should_not_be_called_on_const_items]
3682            pub const fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
3683                // SAFETY: data races are prevented by atomic intrinsics.
3684                unsafe { atomic_or(self.as_ptr(), val, order) }
3685            }
3686
3687            /// Bitwise "xor" with the current value.
3688            ///
3689            /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
3690            /// sets the new value to the result.
3691            ///
3692            /// Returns the previous value.
3693            ///
3694            /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
3695            /// of this operation. All ordering modes are possible. Note that using
3696            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3697            /// using [`Release`] makes the load part [`Relaxed`].
3698            ///
3699            /// **Note**: This method is only available on platforms that support atomic operations on
3700            #[doc = concat!("[`", $s_int_type, "`].")]
3701            ///
3702            /// # Examples
3703            ///
3704            #[cfg_attr($cfg_cas, doc = "```")]
3705            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3706            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3707            ///
3708            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0b101101);")]
3709            /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
3710            /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
3711            /// ```
3712            #[inline]
3713            #[$stable]
3714            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3715            #[cfg(any($cfg_cas, doc))]
3716            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3717            #[rustc_should_not_be_called_on_const_items]
3718            pub const fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
3719                // SAFETY: data races are prevented by atomic intrinsics.
3720                unsafe { atomic_xor(self.as_ptr(), val, order) }
3721            }
3722
3723            /// An alias for
3724            #[doc = concat!("[`", stringify!($atomic_type), "::try_update`]")]
3725            /// .
3726            #[inline]
3727            #[stable(feature = "no_more_cas", since = "1.45.0")]
3728            #[cfg(any($cfg_cas, doc))]
3729            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3730            #[rustc_should_not_be_called_on_const_items]
3731            #[deprecated(
3732                since = "1.99.0",
3733                note = "renamed to `try_update` for consistency",
3734                suggestion = "try_update"
3735            )]
3736            pub fn fetch_update<F>(&self,
3737                                   set_order: Ordering,
3738                                   fetch_order: Ordering,
3739                                   f: F) -> Result<$int_type, $int_type>
3740            where F: FnMut($int_type) -> Option<$int_type> {
3741                self.try_update(set_order, fetch_order, f)
3742            }
3743
3744            /// Fetches the value, and applies a function to it that returns an optional
3745            /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else
3746            /// `Err(previous_value)`.
3747            ///
3748            #[doc = concat!("See also: [`update`](`", stringify!($atomic_type), "::update`).")]
3749            ///
3750            /// Note: This may call the function multiple times if the value has been changed from other threads in
3751            /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied
3752            /// only once to the stored value.
3753            ///
3754            /// `try_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
3755            /// The first describes the required ordering for when the operation finally succeeds while the second
3756            /// describes the required ordering for loads. These correspond to the success and failure orderings of
3757            #[doc = concat!("[`", stringify!($atomic_type), "::compare_exchange`]")]
3758            /// respectively.
3759            ///
3760            /// Using [`Acquire`] as success ordering makes the store part
3761            /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
3762            /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
3763            ///
3764            /// **Note**: This method is only available on platforms that support atomic operations on
3765            #[doc = concat!("[`", $s_int_type, "`].")]
3766            ///
3767            /// # Considerations
3768            ///
3769            /// This method is not magic; it is not provided by the hardware, and does not act like a
3770            /// critical section or mutex.
3771            ///
3772            /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
3773            /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
3774            /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
3775            /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
3776            ///
3777            /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
3778            /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
3779            ///
3780            /// # Examples
3781            ///
3782            #[cfg_attr($cfg_cas, doc = "```rust")]
3783            #[cfg_attr(not($cfg_cas), doc = "```rust,compile_fail")]
3784            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3785            ///
3786            #[doc = concat!("let x = ", stringify!($atomic_type), "::new(7);")]
3787            /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));
3788            /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7));
3789            /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8));
3790            /// assert_eq!(x.load(Ordering::SeqCst), 9);
3791            /// ```
3792            #[inline]
3793            #[stable(feature = "atomic_try_update", since = "1.95.0")]
3794            #[cfg(any($cfg_cas, doc))]
3795            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3796            #[rustc_should_not_be_called_on_const_items]
3797            pub fn try_update(
3798                &self,
3799                set_order: Ordering,
3800                fetch_order: Ordering,
3801                mut f: impl FnMut($int_type) -> Option<$int_type>,
3802            ) -> Result<$int_type, $int_type> {
3803                let mut prev = self.load(fetch_order);
3804                while let Some(next) = f(prev) {
3805                    match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
3806                        x @ Ok(_) => return x,
3807                        Err(next_prev) => prev = next_prev
3808                    }
3809                }
3810                Err(prev)
3811            }
3812
3813            /// Fetches the value, applies a function to it that it return a new value.
3814            /// The new value is stored and the old value is returned.
3815            ///
3816            #[doc = concat!("See also: [`try_update`](`", stringify!($atomic_type), "::try_update`).")]
3817            ///
3818            /// Note: This may call the function multiple times if the value has been changed from other threads in
3819            /// the meantime, but the function will have been applied only once to the stored value.
3820            ///
3821            /// `update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
3822            /// The first describes the required ordering for when the operation finally succeeds while the second
3823            /// describes the required ordering for loads. These correspond to the success and failure orderings of
3824            #[doc = concat!("[`", stringify!($atomic_type), "::compare_exchange`]")]
3825            /// respectively.
3826            ///
3827            /// Using [`Acquire`] as success ordering makes the store part
3828            /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
3829            /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
3830            ///
3831            /// **Note**: This method is only available on platforms that support atomic operations on
3832            #[doc = concat!("[`", $s_int_type, "`].")]
3833            ///
3834            /// # Considerations
3835            ///
3836            /// [CAS operation]: https://en.wikipedia.org/wiki/Compare-and-swap
3837            /// This method is not magic; it is not provided by the hardware, and does not act like a
3838            /// critical section or mutex.
3839            ///
3840            /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
3841            /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
3842            /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
3843            /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
3844            ///
3845            /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
3846            /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
3847            ///
3848            /// # Examples
3849            ///
3850            #[cfg_attr($cfg_cas, doc = "```rust")]
3851            #[cfg_attr(not($cfg_cas), doc = "```rust,compile_fail")]
3852            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3853            ///
3854            #[doc = concat!("let x = ", stringify!($atomic_type), "::new(7);")]
3855            /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 7);
3856            /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 8);
3857            /// assert_eq!(x.load(Ordering::SeqCst), 9);
3858            /// ```
3859            #[inline]
3860            #[stable(feature = "atomic_try_update", since = "1.95.0")]
3861            #[cfg(any($cfg_cas, doc))]
3862            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3863            #[rustc_should_not_be_called_on_const_items]
3864            pub fn update(
3865                &self,
3866                set_order: Ordering,
3867                fetch_order: Ordering,
3868                mut f: impl FnMut($int_type) -> $int_type,
3869            ) -> $int_type {
3870                let mut prev = self.load(fetch_order);
3871                loop {
3872                    match self.compare_exchange_weak(prev, f(prev), set_order, fetch_order) {
3873                        Ok(x) => break x,
3874                        Err(next_prev) => prev = next_prev,
3875                    }
3876                }
3877            }
3878
3879            /// Maximum with the current value.
3880            ///
3881            /// Finds the maximum of the current value and the argument `val`, and
3882            /// sets the new value to the result.
3883            ///
3884            /// Returns the previous value.
3885            ///
3886            /// `fetch_max` takes an [`Ordering`] argument which describes the memory ordering
3887            /// of this operation. All ordering modes are possible. Note that using
3888            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3889            /// using [`Release`] makes the load part [`Relaxed`].
3890            ///
3891            /// **Note**: This method is only available on platforms that support atomic operations on
3892            #[doc = concat!("[`", $s_int_type, "`].")]
3893            ///
3894            /// # Examples
3895            ///
3896            #[cfg_attr($cfg_cas, doc = "```")]
3897            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3898            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3899            ///
3900            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
3901            /// assert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23);
3902            /// assert_eq!(foo.load(Ordering::SeqCst), 42);
3903            /// ```
3904            ///
3905            /// If you want to obtain the maximum value in one step, you can use the following:
3906            ///
3907            #[cfg_attr($cfg_cas, doc = "```")]
3908            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3909            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3910            ///
3911            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
3912            /// let bar = 42;
3913            /// let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar);
3914            /// assert!(max_foo == 42);
3915            /// ```
3916            #[inline]
3917            #[stable(feature = "atomic_min_max", since = "1.45.0")]
3918            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3919            #[cfg(any($cfg_cas, doc))]
3920            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3921            #[rustc_should_not_be_called_on_const_items]
3922            pub const fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {
3923                // SAFETY: data races are prevented by atomic intrinsics.
3924                unsafe { $max_fn(self.as_ptr(), val, order) }
3925            }
3926
3927            /// Minimum with the current value.
3928            ///
3929            /// Finds the minimum of the current value and the argument `val`, and
3930            /// sets the new value to the result.
3931            ///
3932            /// Returns the previous value.
3933            ///
3934            /// `fetch_min` takes an [`Ordering`] argument which describes the memory ordering
3935            /// of this operation. All ordering modes are possible. Note that using
3936            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3937            /// using [`Release`] makes the load part [`Relaxed`].
3938            ///
3939            /// **Note**: This method is only available on platforms that support atomic operations on
3940            #[doc = concat!("[`", $s_int_type, "`].")]
3941            ///
3942            /// # Examples
3943            ///
3944            #[cfg_attr($cfg_cas, doc = "```")]
3945            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3946            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3947            ///
3948            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
3949            /// assert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23);
3950            /// assert_eq!(foo.load(Ordering::Relaxed), 23);
3951            /// assert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23);
3952            /// assert_eq!(foo.load(Ordering::Relaxed), 22);
3953            /// ```
3954            ///
3955            /// If you want to obtain the minimum value in one step, you can use the following:
3956            ///
3957            #[cfg_attr($cfg_cas, doc = "```")]
3958            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3959            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3960            ///
3961            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
3962            /// let bar = 12;
3963            /// let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar);
3964            /// assert_eq!(min_foo, 12);
3965            /// ```
3966            #[inline]
3967            #[stable(feature = "atomic_min_max", since = "1.45.0")]
3968            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3969            #[cfg(any($cfg_cas, doc))]
3970            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3971            #[rustc_should_not_be_called_on_const_items]
3972            pub const fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {
3973                // SAFETY: data races are prevented by atomic intrinsics.
3974                unsafe { $min_fn(self.as_ptr(), val, order) }
3975            }
3976
3977            /// Returns a mutable pointer to the underlying integer.
3978            ///
3979            /// Doing non-atomic reads and writes on the resulting integer can be a data race.
3980            /// This method is mostly useful for FFI, where the function signature may use
3981            #[doc = concat!("`*mut ", stringify!($int_type), "` instead of `&", stringify!($atomic_type), "`.")]
3982            ///
3983            /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
3984            /// atomic types work with interior mutability. All modifications of an atomic change the value
3985            /// through a shared reference, and can do so safely as long as they use atomic operations. Any
3986            /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the
3987            /// requirements of the [memory model].
3988            ///
3989            /// # Examples
3990            ///
3991            /// ```ignore (extern-declaration)
3992            /// # fn main() {
3993            #[doc = concat!($extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";")]
3994            ///
3995            /// extern "C" {
3996            #[doc = concat!("    fn my_atomic_op(arg: *mut ", stringify!($int_type), ");")]
3997            /// }
3998            ///
3999            #[doc = concat!("let atomic = ", stringify!($atomic_type), "::new(1);")]
4000            ///
4001            /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
4002            /// unsafe {
4003            ///     my_atomic_op(atomic.as_ptr());
4004            /// }
4005            /// # }
4006            /// ```
4007            ///
4008            /// [memory model]: self#memory-model-for-atomic-accesses
4009            #[inline]
4010            #[stable(feature = "atomic_as_ptr", since = "1.70.0")]
4011            #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
4012            #[rustc_never_returns_null_ptr]
4013            pub const fn as_ptr(&self) -> *mut $int_type {
4014                self.v.get().cast()
4015            }
4016        }
4017    }
4018}
4019
4020#[cfg(target_has_atomic_load_store = "8")]
4021atomic_int! {
4022    target_has_atomic_load_store = "8",
4023    target_has_atomic = "8",
4024    target_has_atomic_primitive_alignment = "8",
4025    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4026    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4027    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4028    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4029    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4030    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4031    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
4032    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4033    "i8",
4034    "",
4035    atomic_min, atomic_max,
4036    1,
4037    i8 AtomicI8
4038}
4039#[cfg(target_has_atomic_load_store = "8")]
4040atomic_int! {
4041    target_has_atomic_load_store = "8",
4042    target_has_atomic = "8",
4043    target_has_atomic_primitive_alignment = "8",
4044    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4045    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4046    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4047    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4048    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4049    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4050    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
4051    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4052    "u8",
4053    "",
4054    atomic_umin, atomic_umax,
4055    1,
4056    u8 AtomicU8
4057}
4058#[cfg(target_has_atomic_load_store = "16")]
4059atomic_int! {
4060    target_has_atomic_load_store = "16",
4061    target_has_atomic = "16",
4062    target_has_atomic_primitive_alignment = "16",
4063    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4064    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4065    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4066    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4067    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4068    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4069    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
4070    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4071    "i16",
4072    "",
4073    atomic_min, atomic_max,
4074    2,
4075    i16 AtomicI16
4076}
4077#[cfg(target_has_atomic_load_store = "16")]
4078atomic_int! {
4079    target_has_atomic_load_store = "16",
4080    target_has_atomic = "16",
4081    target_has_atomic_primitive_alignment = "16",
4082    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4083    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4084    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4085    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4086    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4087    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4088    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
4089    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4090    "u16",
4091    "",
4092    atomic_umin, atomic_umax,
4093    2,
4094    u16 AtomicU16
4095}
4096#[cfg(target_has_atomic_load_store = "32")]
4097atomic_int! {
4098    target_has_atomic_load_store = "32",
4099    target_has_atomic = "32",
4100    target_has_atomic_primitive_alignment = "32",
4101    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4102    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4103    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4104    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4105    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4106    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4107    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
4108    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4109    "i32",
4110    "",
4111    atomic_min, atomic_max,
4112    4,
4113    i32 AtomicI32
4114}
4115#[cfg(target_has_atomic_load_store = "32")]
4116atomic_int! {
4117    target_has_atomic_load_store = "32",
4118    target_has_atomic = "32",
4119    target_has_atomic_primitive_alignment = "32",
4120    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4121    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4122    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4123    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4124    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4125    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4126    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
4127    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4128    "u32",
4129    "",
4130    atomic_umin, atomic_umax,
4131    4,
4132    u32 AtomicU32
4133}
4134#[cfg(target_has_atomic_load_store = "64")]
4135atomic_int! {
4136    target_has_atomic_load_store = "64",
4137    target_has_atomic = "64",
4138    target_has_atomic_primitive_alignment = "64",
4139    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4140    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4141    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4142    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4143    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4144    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4145    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
4146    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4147    "i64",
4148    "",
4149    atomic_min, atomic_max,
4150    8,
4151    i64 AtomicI64
4152}
4153#[cfg(target_has_atomic_load_store = "64")]
4154atomic_int! {
4155    target_has_atomic_load_store = "64",
4156    target_has_atomic = "64",
4157    target_has_atomic_primitive_alignment = "64",
4158    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4159    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4160    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4161    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4162    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4163    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4164    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
4165    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4166    "u64",
4167    "",
4168    atomic_umin, atomic_umax,
4169    8,
4170    u64 AtomicU64
4171}
4172#[cfg(any(target_has_atomic_load_store = "128", doc))]
4173atomic_int! {
4174    target_has_atomic_load_store = "128",
4175    target_has_atomic = "128",
4176    target_has_atomic_primitive_alignment = "128",
4177    unstable(feature = "integer_atomics", issue = "99069"),
4178    unstable(feature = "integer_atomics", issue = "99069"),
4179    unstable(feature = "integer_atomics", issue = "99069"),
4180    unstable(feature = "integer_atomics", issue = "99069"),
4181    unstable(feature = "integer_atomics", issue = "99069"),
4182    unstable(feature = "integer_atomics", issue = "99069"),
4183    rustc_const_unstable(feature = "integer_atomics", issue = "99069"),
4184    rustc_const_unstable(feature = "integer_atomics", issue = "99069"),
4185    "i128",
4186    "#![feature(integer_atomics)]\n\n",
4187    atomic_min, atomic_max,
4188    16,
4189    i128 AtomicI128
4190}
4191#[cfg(any(target_has_atomic_load_store = "128", doc))]
4192atomic_int! {
4193    target_has_atomic_load_store = "128",
4194    target_has_atomic = "128",
4195    target_has_atomic_primitive_alignment = "128",
4196    unstable(feature = "integer_atomics", issue = "99069"),
4197    unstable(feature = "integer_atomics", issue = "99069"),
4198    unstable(feature = "integer_atomics", issue = "99069"),
4199    unstable(feature = "integer_atomics", issue = "99069"),
4200    unstable(feature = "integer_atomics", issue = "99069"),
4201    unstable(feature = "integer_atomics", issue = "99069"),
4202    rustc_const_unstable(feature = "integer_atomics", issue = "99069"),
4203    rustc_const_unstable(feature = "integer_atomics", issue = "99069"),
4204    "u128",
4205    "#![feature(integer_atomics)]\n\n",
4206    atomic_umin, atomic_umax,
4207    16,
4208    u128 AtomicU128
4209}
4210
4211#[cfg(target_has_atomic_load_store = "ptr")]
4212macro_rules! atomic_int_ptr_sized {
4213    ( $($target_pointer_width:literal $align:literal)* ) => { $(
4214        #[cfg(target_pointer_width = $target_pointer_width)]
4215        atomic_int! {
4216            target_has_atomic_load_store = "ptr",
4217            target_has_atomic = "ptr",
4218            target_has_atomic_primitive_alignment = "ptr",
4219            stable(feature = "rust1", since = "1.0.0"),
4220            stable(feature = "extended_compare_and_swap", since = "1.10.0"),
4221            stable(feature = "atomic_debug", since = "1.3.0"),
4222            stable(feature = "atomic_access", since = "1.15.0"),
4223            stable(feature = "atomic_from", since = "1.23.0"),
4224            stable(feature = "atomic_nand", since = "1.27.0"),
4225            rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"),
4226            rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4227            "isize",
4228            "",
4229            atomic_min, atomic_max,
4230            $align,
4231            isize AtomicIsize
4232        }
4233        #[cfg(target_pointer_width = $target_pointer_width)]
4234        atomic_int! {
4235            target_has_atomic_load_store = "ptr",
4236            target_has_atomic = "ptr",
4237            target_has_atomic_primitive_alignment = "ptr",
4238            stable(feature = "rust1", since = "1.0.0"),
4239            stable(feature = "extended_compare_and_swap", since = "1.10.0"),
4240            stable(feature = "atomic_debug", since = "1.3.0"),
4241            stable(feature = "atomic_access", since = "1.15.0"),
4242            stable(feature = "atomic_from", since = "1.23.0"),
4243            stable(feature = "atomic_nand", since = "1.27.0"),
4244            rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"),
4245            rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4246            "usize",
4247            "",
4248            atomic_umin, atomic_umax,
4249            $align,
4250            usize AtomicUsize
4251        }
4252
4253        /// An [`AtomicIsize`] initialized to `0`.
4254        #[cfg(target_pointer_width = $target_pointer_width)]
4255        #[stable(feature = "rust1", since = "1.0.0")]
4256        #[deprecated(
4257            since = "1.34.0",
4258            note = "the `new` function is now preferred",
4259            suggestion = "AtomicIsize::new(0)",
4260        )]
4261        #[expect(clippy::declare_interior_mutable_const, reason = "legacy atomic initializer")]
4262        pub const ATOMIC_ISIZE_INIT: AtomicIsize = AtomicIsize::new(0);
4263
4264        /// An [`AtomicUsize`] initialized to `0`.
4265        #[cfg(target_pointer_width = $target_pointer_width)]
4266        #[stable(feature = "rust1", since = "1.0.0")]
4267        #[deprecated(
4268            since = "1.34.0",
4269            note = "the `new` function is now preferred",
4270            suggestion = "AtomicUsize::new(0)",
4271        )]
4272        #[expect(clippy::declare_interior_mutable_const, reason = "legacy atomic initializer")]
4273        pub const ATOMIC_USIZE_INIT: AtomicUsize = AtomicUsize::new(0);
4274    )* };
4275}
4276
4277#[cfg(target_has_atomic_load_store = "ptr")]
4278atomic_int_ptr_sized! {
4279    "16" 2
4280    "32" 4
4281    "64" 8
4282}
4283
4284#[inline]
4285#[cfg(target_has_atomic)]
4286const fn strongest_failure_ordering(order: Ordering) -> Ordering {
4287    match order {
4288        Release => Relaxed,
4289        Relaxed => Relaxed,
4290        SeqCst => SeqCst,
4291        Acquire => Acquire,
4292        AcqRel => Acquire,
4293    }
4294}
4295
4296#[inline]
4297#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4298#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4299const unsafe fn atomic_store<T: Copy, const VOLATILE: bool>(dst: *mut T, val: T, order: Ordering) {
4300    // SAFETY: the caller must uphold the safety contract for `atomic_store`.
4301    unsafe {
4302        match order {
4303            Relaxed => intrinsics::atomic_store::<T, { AO::Relaxed }, VOLATILE>(dst, val),
4304            Release => intrinsics::atomic_store::<T, { AO::Release }, VOLATILE>(dst, val),
4305            SeqCst => intrinsics::atomic_store::<T, { AO::SeqCst }, VOLATILE>(dst, val),
4306            Acquire => panic!("there is no such thing as an acquire store"),
4307            AcqRel => panic!("there is no such thing as an acquire-release store"),
4308        }
4309    }
4310}
4311
4312#[inline]
4313#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4314#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4315const unsafe fn atomic_load<T: Copy, const VOLATILE: bool>(dst: *const T, order: Ordering) -> T {
4316    // SAFETY: the caller must uphold the safety contract for `atomic_load`.
4317    unsafe {
4318        match order {
4319            Relaxed => intrinsics::atomic_load::<T, { AO::Relaxed }, VOLATILE>(dst),
4320            Acquire => intrinsics::atomic_load::<T, { AO::Acquire }, VOLATILE>(dst),
4321            SeqCst => intrinsics::atomic_load::<T, { AO::SeqCst }, VOLATILE>(dst),
4322            Release => panic!("there is no such thing as a release load"),
4323            AcqRel => panic!("there is no such thing as an acquire-release load"),
4324        }
4325    }
4326}
4327
4328#[inline]
4329#[cfg(target_has_atomic)]
4330#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4331#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4332const unsafe fn atomic_swap<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
4333    // SAFETY: the caller must uphold the safety contract for `atomic_swap`.
4334    unsafe {
4335        match order {
4336            Relaxed => intrinsics::atomic_xchg::<T, { AO::Relaxed }>(dst, val),
4337            Acquire => intrinsics::atomic_xchg::<T, { AO::Acquire }>(dst, val),
4338            Release => intrinsics::atomic_xchg::<T, { AO::Release }>(dst, val),
4339            AcqRel => intrinsics::atomic_xchg::<T, { AO::AcqRel }>(dst, val),
4340            SeqCst => intrinsics::atomic_xchg::<T, { AO::SeqCst }>(dst, val),
4341        }
4342    }
4343}
4344
4345/// Returns the previous value (like __sync_fetch_and_add).
4346#[inline]
4347#[cfg(target_has_atomic)]
4348#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4349#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4350const unsafe fn atomic_add<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
4351    // SAFETY: the caller must uphold the safety contract for `atomic_add`.
4352    unsafe {
4353        match order {
4354            Relaxed => intrinsics::atomic_xadd::<T, U, { AO::Relaxed }>(dst, val),
4355            Acquire => intrinsics::atomic_xadd::<T, U, { AO::Acquire }>(dst, val),
4356            Release => intrinsics::atomic_xadd::<T, U, { AO::Release }>(dst, val),
4357            AcqRel => intrinsics::atomic_xadd::<T, U, { AO::AcqRel }>(dst, val),
4358            SeqCst => intrinsics::atomic_xadd::<T, U, { AO::SeqCst }>(dst, val),
4359        }
4360    }
4361}
4362
4363/// Returns the previous value (like __sync_fetch_and_sub).
4364#[inline]
4365#[cfg(target_has_atomic)]
4366#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4367#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4368const unsafe fn atomic_sub<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
4369    // SAFETY: the caller must uphold the safety contract for `atomic_sub`.
4370    unsafe {
4371        match order {
4372            Relaxed => intrinsics::atomic_xsub::<T, U, { AO::Relaxed }>(dst, val),
4373            Acquire => intrinsics::atomic_xsub::<T, U, { AO::Acquire }>(dst, val),
4374            Release => intrinsics::atomic_xsub::<T, U, { AO::Release }>(dst, val),
4375            AcqRel => intrinsics::atomic_xsub::<T, U, { AO::AcqRel }>(dst, val),
4376            SeqCst => intrinsics::atomic_xsub::<T, U, { AO::SeqCst }>(dst, val),
4377        }
4378    }
4379}
4380
4381/// Publicly exposed for stdarch; nobody else should use this.
4382#[inline]
4383#[cfg(target_has_atomic)]
4384#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4385#[unstable(feature = "core_intrinsics", issue = "none")]
4386#[doc(hidden)]
4387#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4388pub const unsafe fn atomic_compare_exchange<T: Copy>(
4389    dst: *mut T,
4390    old: T,
4391    new: T,
4392    success: Ordering,
4393    failure: Ordering,
4394) -> Result<T, T> {
4395    // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange`.
4396    let (val, ok) = unsafe {
4397        match (success, failure) {
4398            (Relaxed, Relaxed) => {
4399                intrinsics::atomic_cxchg::<T, { AO::Relaxed }, { AO::Relaxed }>(dst, old, new)
4400            }
4401            (Relaxed, Acquire) => {
4402                intrinsics::atomic_cxchg::<T, { AO::Relaxed }, { AO::Acquire }>(dst, old, new)
4403            }
4404            (Relaxed, SeqCst) => {
4405                intrinsics::atomic_cxchg::<T, { AO::Relaxed }, { AO::SeqCst }>(dst, old, new)
4406            }
4407            (Acquire, Relaxed) => {
4408                intrinsics::atomic_cxchg::<T, { AO::Acquire }, { AO::Relaxed }>(dst, old, new)
4409            }
4410            (Acquire, Acquire) => {
4411                intrinsics::atomic_cxchg::<T, { AO::Acquire }, { AO::Acquire }>(dst, old, new)
4412            }
4413            (Acquire, SeqCst) => {
4414                intrinsics::atomic_cxchg::<T, { AO::Acquire }, { AO::SeqCst }>(dst, old, new)
4415            }
4416            (Release, Relaxed) => {
4417                intrinsics::atomic_cxchg::<T, { AO::Release }, { AO::Relaxed }>(dst, old, new)
4418            }
4419            (Release, Acquire) => {
4420                intrinsics::atomic_cxchg::<T, { AO::Release }, { AO::Acquire }>(dst, old, new)
4421            }
4422            (Release, SeqCst) => {
4423                intrinsics::atomic_cxchg::<T, { AO::Release }, { AO::SeqCst }>(dst, old, new)
4424            }
4425            (AcqRel, Relaxed) => {
4426                intrinsics::atomic_cxchg::<T, { AO::AcqRel }, { AO::Relaxed }>(dst, old, new)
4427            }
4428            (AcqRel, Acquire) => {
4429                intrinsics::atomic_cxchg::<T, { AO::AcqRel }, { AO::Acquire }>(dst, old, new)
4430            }
4431            (AcqRel, SeqCst) => {
4432                intrinsics::atomic_cxchg::<T, { AO::AcqRel }, { AO::SeqCst }>(dst, old, new)
4433            }
4434            (SeqCst, Relaxed) => {
4435                intrinsics::atomic_cxchg::<T, { AO::SeqCst }, { AO::Relaxed }>(dst, old, new)
4436            }
4437            (SeqCst, Acquire) => {
4438                intrinsics::atomic_cxchg::<T, { AO::SeqCst }, { AO::Acquire }>(dst, old, new)
4439            }
4440            (SeqCst, SeqCst) => {
4441                intrinsics::atomic_cxchg::<T, { AO::SeqCst }, { AO::SeqCst }>(dst, old, new)
4442            }
4443            (_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"),
4444            (_, Release) => panic!("there is no such thing as a release failure ordering"),
4445        }
4446    };
4447    if ok { Ok(val) } else { Err(val) }
4448}
4449
4450#[inline]
4451#[cfg(target_has_atomic)]
4452#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4453#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4454const unsafe fn atomic_compare_exchange_weak<T: Copy>(
4455    dst: *mut T,
4456    old: T,
4457    new: T,
4458    success: Ordering,
4459    failure: Ordering,
4460) -> Result<T, T> {
4461    // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange_weak`.
4462    let (val, ok) = unsafe {
4463        match (success, failure) {
4464            (Relaxed, Relaxed) => {
4465                intrinsics::atomic_cxchgweak::<T, { AO::Relaxed }, { AO::Relaxed }>(dst, old, new)
4466            }
4467            (Relaxed, Acquire) => {
4468                intrinsics::atomic_cxchgweak::<T, { AO::Relaxed }, { AO::Acquire }>(dst, old, new)
4469            }
4470            (Relaxed, SeqCst) => {
4471                intrinsics::atomic_cxchgweak::<T, { AO::Relaxed }, { AO::SeqCst }>(dst, old, new)
4472            }
4473            (Acquire, Relaxed) => {
4474                intrinsics::atomic_cxchgweak::<T, { AO::Acquire }, { AO::Relaxed }>(dst, old, new)
4475            }
4476            (Acquire, Acquire) => {
4477                intrinsics::atomic_cxchgweak::<T, { AO::Acquire }, { AO::Acquire }>(dst, old, new)
4478            }
4479            (Acquire, SeqCst) => {
4480                intrinsics::atomic_cxchgweak::<T, { AO::Acquire }, { AO::SeqCst }>(dst, old, new)
4481            }
4482            (Release, Relaxed) => {
4483                intrinsics::atomic_cxchgweak::<T, { AO::Release }, { AO::Relaxed }>(dst, old, new)
4484            }
4485            (Release, Acquire) => {
4486                intrinsics::atomic_cxchgweak::<T, { AO::Release }, { AO::Acquire }>(dst, old, new)
4487            }
4488            (Release, SeqCst) => {
4489                intrinsics::atomic_cxchgweak::<T, { AO::Release }, { AO::SeqCst }>(dst, old, new)
4490            }
4491            (AcqRel, Relaxed) => {
4492                intrinsics::atomic_cxchgweak::<T, { AO::AcqRel }, { AO::Relaxed }>(dst, old, new)
4493            }
4494            (AcqRel, Acquire) => {
4495                intrinsics::atomic_cxchgweak::<T, { AO::AcqRel }, { AO::Acquire }>(dst, old, new)
4496            }
4497            (AcqRel, SeqCst) => {
4498                intrinsics::atomic_cxchgweak::<T, { AO::AcqRel }, { AO::SeqCst }>(dst, old, new)
4499            }
4500            (SeqCst, Relaxed) => {
4501                intrinsics::atomic_cxchgweak::<T, { AO::SeqCst }, { AO::Relaxed }>(dst, old, new)
4502            }
4503            (SeqCst, Acquire) => {
4504                intrinsics::atomic_cxchgweak::<T, { AO::SeqCst }, { AO::Acquire }>(dst, old, new)
4505            }
4506            (SeqCst, SeqCst) => {
4507                intrinsics::atomic_cxchgweak::<T, { AO::SeqCst }, { AO::SeqCst }>(dst, old, new)
4508            }
4509            (_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"),
4510            (_, Release) => panic!("there is no such thing as a release failure ordering"),
4511        }
4512    };
4513    if ok { Ok(val) } else { Err(val) }
4514}
4515
4516#[inline]
4517#[cfg(target_has_atomic)]
4518#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4519#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4520const unsafe fn atomic_and<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
4521    // SAFETY: the caller must uphold the safety contract for `atomic_and`
4522    unsafe {
4523        match order {
4524            Relaxed => intrinsics::atomic_and::<T, U, { AO::Relaxed }>(dst, val),
4525            Acquire => intrinsics::atomic_and::<T, U, { AO::Acquire }>(dst, val),
4526            Release => intrinsics::atomic_and::<T, U, { AO::Release }>(dst, val),
4527            AcqRel => intrinsics::atomic_and::<T, U, { AO::AcqRel }>(dst, val),
4528            SeqCst => intrinsics::atomic_and::<T, U, { AO::SeqCst }>(dst, val),
4529        }
4530    }
4531}
4532
4533#[inline]
4534#[cfg(target_has_atomic)]
4535#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4536#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4537const unsafe fn atomic_nand<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
4538    // SAFETY: the caller must uphold the safety contract for `atomic_nand`
4539    unsafe {
4540        match order {
4541            Relaxed => intrinsics::atomic_nand::<T, U, { AO::Relaxed }>(dst, val),
4542            Acquire => intrinsics::atomic_nand::<T, U, { AO::Acquire }>(dst, val),
4543            Release => intrinsics::atomic_nand::<T, U, { AO::Release }>(dst, val),
4544            AcqRel => intrinsics::atomic_nand::<T, U, { AO::AcqRel }>(dst, val),
4545            SeqCst => intrinsics::atomic_nand::<T, U, { AO::SeqCst }>(dst, val),
4546        }
4547    }
4548}
4549
4550#[inline]
4551#[cfg(target_has_atomic)]
4552#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4553#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4554const unsafe fn atomic_or<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
4555    // SAFETY: the caller must uphold the safety contract for `atomic_or`
4556    unsafe {
4557        match order {
4558            SeqCst => intrinsics::atomic_or::<T, U, { AO::SeqCst }>(dst, val),
4559            Acquire => intrinsics::atomic_or::<T, U, { AO::Acquire }>(dst, val),
4560            Release => intrinsics::atomic_or::<T, U, { AO::Release }>(dst, val),
4561            AcqRel => intrinsics::atomic_or::<T, U, { AO::AcqRel }>(dst, val),
4562            Relaxed => intrinsics::atomic_or::<T, U, { AO::Relaxed }>(dst, val),
4563        }
4564    }
4565}
4566
4567#[inline]
4568#[cfg(target_has_atomic)]
4569#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4570#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4571const unsafe fn atomic_xor<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
4572    // SAFETY: the caller must uphold the safety contract for `atomic_xor`
4573    unsafe {
4574        match order {
4575            SeqCst => intrinsics::atomic_xor::<T, U, { AO::SeqCst }>(dst, val),
4576            Acquire => intrinsics::atomic_xor::<T, U, { AO::Acquire }>(dst, val),
4577            Release => intrinsics::atomic_xor::<T, U, { AO::Release }>(dst, val),
4578            AcqRel => intrinsics::atomic_xor::<T, U, { AO::AcqRel }>(dst, val),
4579            Relaxed => intrinsics::atomic_xor::<T, U, { AO::Relaxed }>(dst, val),
4580        }
4581    }
4582}
4583
4584/// Updates `*dst` to the max value of `val` and the old value (signed comparison)
4585#[inline]
4586#[cfg(target_has_atomic)]
4587#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4588#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4589const unsafe fn atomic_max<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
4590    // SAFETY: the caller must uphold the safety contract for `atomic_max`
4591    unsafe {
4592        match order {
4593            Relaxed => intrinsics::atomic_max::<T, { AO::Relaxed }>(dst, val),
4594            Acquire => intrinsics::atomic_max::<T, { AO::Acquire }>(dst, val),
4595            Release => intrinsics::atomic_max::<T, { AO::Release }>(dst, val),
4596            AcqRel => intrinsics::atomic_max::<T, { AO::AcqRel }>(dst, val),
4597            SeqCst => intrinsics::atomic_max::<T, { AO::SeqCst }>(dst, val),
4598        }
4599    }
4600}
4601
4602/// Updates `*dst` to the min value of `val` and the old value (signed comparison)
4603#[inline]
4604#[cfg(target_has_atomic)]
4605#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4606#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4607const unsafe fn atomic_min<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
4608    // SAFETY: the caller must uphold the safety contract for `atomic_min`
4609    unsafe {
4610        match order {
4611            Relaxed => intrinsics::atomic_min::<T, { AO::Relaxed }>(dst, val),
4612            Acquire => intrinsics::atomic_min::<T, { AO::Acquire }>(dst, val),
4613            Release => intrinsics::atomic_min::<T, { AO::Release }>(dst, val),
4614            AcqRel => intrinsics::atomic_min::<T, { AO::AcqRel }>(dst, val),
4615            SeqCst => intrinsics::atomic_min::<T, { AO::SeqCst }>(dst, val),
4616        }
4617    }
4618}
4619
4620/// Updates `*dst` to the max value of `val` and the old value (unsigned comparison)
4621#[inline]
4622#[cfg(target_has_atomic)]
4623#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4624#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4625const unsafe fn atomic_umax<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
4626    // SAFETY: the caller must uphold the safety contract for `atomic_umax`
4627    unsafe {
4628        match order {
4629            Relaxed => intrinsics::atomic_umax::<T, { AO::Relaxed }>(dst, val),
4630            Acquire => intrinsics::atomic_umax::<T, { AO::Acquire }>(dst, val),
4631            Release => intrinsics::atomic_umax::<T, { AO::Release }>(dst, val),
4632            AcqRel => intrinsics::atomic_umax::<T, { AO::AcqRel }>(dst, val),
4633            SeqCst => intrinsics::atomic_umax::<T, { AO::SeqCst }>(dst, val),
4634        }
4635    }
4636}
4637
4638/// Updates `*dst` to the min value of `val` and the old value (unsigned comparison)
4639#[inline]
4640#[cfg(target_has_atomic)]
4641#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4642#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4643const unsafe fn atomic_umin<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
4644    // SAFETY: the caller must uphold the safety contract for `atomic_umin`
4645    unsafe {
4646        match order {
4647            Relaxed => intrinsics::atomic_umin::<T, { AO::Relaxed }>(dst, val),
4648            Acquire => intrinsics::atomic_umin::<T, { AO::Acquire }>(dst, val),
4649            Release => intrinsics::atomic_umin::<T, { AO::Release }>(dst, val),
4650            AcqRel => intrinsics::atomic_umin::<T, { AO::AcqRel }>(dst, val),
4651            SeqCst => intrinsics::atomic_umin::<T, { AO::SeqCst }>(dst, val),
4652        }
4653    }
4654}
4655
4656/// An atomic fence.
4657///
4658/// Fences create synchronization between themselves and atomic operations or fences in other
4659/// threads. It can be helpful to think of a fence as preventing the compiler and CPU from
4660/// reordering certain types of memory operations around it, but that is a simplified model which
4661/// fails to capture some of the nuances.
4662///
4663/// There are 3 different ways to use an atomic fence:
4664///
4665/// - atomic - fence synchronization: an atomic operation with (at least) [`Release`] ordering
4666///   semantics synchronizes with a fence with (at least) [`Acquire`] ordering semantics.
4667/// - fence - atomic synchronization: a fence with (at least) [`Release`] ordering semantics
4668///   synchronizes with an atomic operation with (at least) [`Acquire`] ordering semantics.
4669/// - fence - fence synchronization: a fence with (at least) [`Release`] ordering semantics
4670///   synchronizes with a fence with (at least) [`Acquire`] ordering semantics.
4671///
4672/// These 3 ways complement the regular, fence-less, atomic - atomic synchronization.
4673///
4674/// ## Atomic - Fence
4675///
4676/// An atomic operation on one thread will synchronize with a fence on another thread when:
4677///
4678/// -   on thread 1:
4679///     -   an atomic operation 'X' with (at least) [`Release`] ordering semantics on some atomic
4680///         object 'm',
4681///
4682/// -   is paired on thread 2 with:
4683///     -   an atomic read 'Y' with any order on 'm',
4684///     -   followed by a fence 'B' with (at least) [`Acquire`] ordering semantics.
4685///
4686/// This provides a happens-before dependence between X and B.
4687///
4688/// ```text
4689///     Thread 1                                          Thread 2
4690///
4691/// m.store(3, Release); X ---------
4692///                                |
4693///                                |
4694///                                -------------> Y  if m.load(Relaxed) == 3 {
4695///                                               B      fence(Acquire);
4696///                                                      ...
4697///                                                  }
4698/// ```
4699///
4700/// ## Fence - Atomic
4701///
4702/// A fence on one thread will synchronize with an atomic operation on another thread when:
4703///
4704/// -   on thread:
4705///     -   a fence 'A' with (at least) [`Release`] ordering semantics,
4706///     -   followed by an atomic write 'X' with any ordering on some atomic object 'm',
4707///
4708/// -   is paired on thread 2 with:
4709///     -   an atomic operation 'Y' with (at least) [`Acquire`] ordering semantics.
4710///
4711/// This provides a happens-before dependence between A and Y.
4712///
4713/// ```text
4714///     Thread 1                                          Thread 2
4715///
4716/// fence(Release);      A
4717/// m.store(3, Relaxed); X ---------
4718///                                |
4719///                                |
4720///                                -------------> Y  if m.load(Acquire) == 3 {
4721///                                                      ...
4722///                                                  }
4723/// ```
4724///
4725/// ## Fence - Fence
4726///
4727/// A fence on one thread will synchronize with a fence on another thread when:
4728///
4729/// -   on thread 1:
4730///     -   a fence 'A' which has (at least) [`Release`] ordering semantics,
4731///     -   followed by an atomic write 'X' with any ordering on some atomic object 'm',
4732///
4733/// -   is paired on thread 2 with:
4734///     -   an atomic read 'Y' with any ordering on 'm',
4735///     -   followed by a fence 'B' with (at least) [`Acquire`] ordering semantics.
4736///
4737/// This provides a happens-before dependence between A and B.
4738///
4739/// ```text
4740///     Thread 1                                          Thread 2
4741///
4742/// fence(Release);      A --------------
4743/// m.store(3, Relaxed); X ---------    |
4744///                                |    |
4745///                                |    |
4746///                                -------------> Y  if m.load(Relaxed) == 3 {
4747///                                     |-------> B      fence(Acquire);
4748///                                                      ...
4749///                                                  }
4750/// ```
4751///
4752/// ## Mandatory Atomic
4753///
4754/// Note that in the examples above, it is crucial that the access to `m` are atomic. Fences cannot
4755/// be used to establish synchronization between non-atomic accesses in different threads. However,
4756/// thanks to the happens-before relationship, any non-atomic access that happen-before the atomic
4757/// operation or fence with (at least) [`Release`] ordering semantics are now also properly
4758/// synchronized with any non-atomic accesses that happen-after the atomic operation or fence with
4759/// (at least) [`Acquire`] ordering semantics.
4760///
4761/// ## Memory Ordering
4762///
4763/// A fence which has [`SeqCst`] ordering, in addition to having both [`Acquire`] and [`Release`]
4764/// semantics, participates in the global program order of the other [`SeqCst`] operations and/or
4765/// fences.
4766///
4767/// Accepts [`Acquire`], [`Release`], [`AcqRel`] and [`SeqCst`] orderings.
4768///
4769/// # Panics
4770///
4771/// Panics if `order` is [`Relaxed`].
4772///
4773/// # Examples
4774///
4775/// ```
4776/// use std::sync::atomic::AtomicBool;
4777/// use std::sync::atomic::fence;
4778/// use std::sync::atomic::Ordering;
4779///
4780/// // A mutual exclusion primitive based on spinlock.
4781/// pub struct Mutex {
4782///     flag: AtomicBool,
4783/// }
4784///
4785/// impl Mutex {
4786///     pub fn new() -> Mutex {
4787///         Mutex {
4788///             flag: AtomicBool::new(false),
4789///         }
4790///     }
4791///
4792///     pub fn lock(&self) {
4793///         // Wait until the old value is `false`.
4794///         while self
4795///             .flag
4796///             .compare_exchange_weak(false, true, Ordering::Relaxed, Ordering::Relaxed)
4797///             .is_err()
4798///         {}
4799///         // This fence synchronizes-with store in `unlock`.
4800///         fence(Ordering::Acquire);
4801///     }
4802///
4803///     pub fn unlock(&self) {
4804///         self.flag.store(false, Ordering::Release);
4805///     }
4806/// }
4807/// ```
4808#[inline]
4809#[stable(feature = "rust1", since = "1.0.0")]
4810#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4811#[rustc_diagnostic_item = "fence"]
4812#[doc(alias = "atomic_thread_fence")]
4813#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4814pub const fn fence(order: Ordering) {
4815    // SAFETY: using an atomic fence is safe.
4816    unsafe {
4817        match order {
4818            Acquire => intrinsics::atomic_fence::<{ AO::Acquire }>(),
4819            Release => intrinsics::atomic_fence::<{ AO::Release }>(),
4820            AcqRel => intrinsics::atomic_fence::<{ AO::AcqRel }>(),
4821            SeqCst => intrinsics::atomic_fence::<{ AO::SeqCst }>(),
4822            Relaxed => panic!("there is no such thing as a relaxed fence"),
4823        }
4824    }
4825}
4826
4827/// An atomic fence for synchronization within a single thread.
4828///
4829/// Like [`fence`], this function establishes synchronization with other atomic operations and
4830/// fences. However, unlike [`fence`], `compiler_fence` only establishes synchronization with
4831/// operations *in the same thread*. This may at first sound rather useless, since code within a
4832/// thread is typically already totally ordered and does not need any further synchronization.
4833/// However, there are cases where code can run on the same thread without being synchronized:
4834/// - The most common case is that of a *signal handler*: a signal handler runs in the same thread
4835///   as the code it interrupted, but it is not synchronized with that code. `compiler_fence`
4836///   can be used to establish synchronization between a thread and its signal handler, the same way
4837///   that `fence` can be used to establish synchronization across threads.
4838/// - Similar situations can arise in embedded programming with interrupt handlers, or in custom
4839///   implementations of preemptive green threads. In general, `compiler_fence` can establish
4840///   synchronization with code that is guaranteed to run on the same hardware CPU.
4841///
4842/// See [`fence`] for how a fence can be used to achieve synchronization. Note that just like
4843/// [`fence`], synchronization still requires atomic operations to be used in both threads -- it is
4844/// not possible to perform synchronization entirely with fences and non-atomic operations.
4845///
4846/// `compiler_fence` does not emit any machine code. However, note that `compiler_fence` is also
4847/// *not* a "compiler barrier". It can be helpful to think of a `compiler_fence` as preventing the
4848/// compiler from reordering certain types of memory operations around it, but that is a simplified
4849/// model which fails to capture some of the nuances. The only actual guarantee made by
4850/// `compiler_fence` is establishing synchronization with signal handlers and similar kinds of code,
4851/// under the rules described in the [`fence`] documentation.
4852///
4853/// `compiler_fence` corresponds to [`atomic_signal_fence`] in C and C++.
4854///
4855/// [`atomic_signal_fence`]: https://en.cppreference.com/w/cpp/atomic/atomic_signal_fence
4856///
4857/// # Panics
4858///
4859/// Panics if `order` is [`Relaxed`].
4860///
4861/// # Examples
4862///
4863/// Without the two `compiler_fence` calls, the read of `IMPORTANT_VARIABLE` in `signal_handler`
4864/// is *undefined behavior* due to a data race, despite everything happening in a single thread.
4865/// This is because the signal handler is considered to run concurrently with its associated
4866/// thread, and explicit synchronization is required to pass data between a thread and its
4867/// signal handler. The code below uses two `compiler_fence` calls to establish the usual
4868/// release-acquire synchronization pattern (see [`fence`] for an image).
4869///
4870/// ```
4871/// use std::sync::atomic::AtomicBool;
4872/// use std::sync::atomic::Ordering;
4873/// use std::sync::atomic::compiler_fence;
4874///
4875/// static mut IMPORTANT_VARIABLE: usize = 0;
4876/// static IS_READY: AtomicBool = AtomicBool::new(false);
4877///
4878/// fn main() {
4879///     unsafe { IMPORTANT_VARIABLE = 42 };
4880///     // Marks earlier writes as being released with future relaxed stores.
4881///     compiler_fence(Ordering::Release);
4882///     IS_READY.store(true, Ordering::Relaxed);
4883/// }
4884///
4885/// fn signal_handler() {
4886///     if IS_READY.load(Ordering::Relaxed) {
4887///         // Acquires writes that were released with relaxed stores that we read from.
4888///         compiler_fence(Ordering::Acquire);
4889///         assert_eq!(unsafe { IMPORTANT_VARIABLE }, 42);
4890///     }
4891/// }
4892/// ```
4893#[inline]
4894#[stable(feature = "compiler_fences", since = "1.21.0")]
4895#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4896#[rustc_diagnostic_item = "compiler_fence"]
4897#[doc(alias = "atomic_signal_fence")]
4898#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4899pub const fn compiler_fence(order: Ordering) {
4900    // SAFETY: using an atomic fence is safe.
4901    unsafe {
4902        match order {
4903            Acquire => intrinsics::atomic_singlethreadfence::<{ AO::Acquire }>(),
4904            Release => intrinsics::atomic_singlethreadfence::<{ AO::Release }>(),
4905            AcqRel => intrinsics::atomic_singlethreadfence::<{ AO::AcqRel }>(),
4906            SeqCst => intrinsics::atomic_singlethreadfence::<{ AO::SeqCst }>(),
4907            Relaxed => panic!("there is no such thing as a relaxed fence"),
4908        }
4909    }
4910}
4911
4912#[cfg(target_has_atomic_load_store = "8")]
4913#[stable(feature = "atomic_debug", since = "1.3.0")]
4914impl fmt::Debug for AtomicBool {
4915    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4916        fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
4917    }
4918}
4919
4920#[cfg(target_has_atomic_load_store = "ptr")]
4921#[stable(feature = "atomic_debug", since = "1.3.0")]
4922impl<T> fmt::Debug for AtomicPtr<T> {
4923    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4924        fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
4925    }
4926}
4927
4928#[cfg(target_has_atomic_load_store = "ptr")]
4929#[stable(feature = "atomic_pointer", since = "1.24.0")]
4930impl<T> fmt::Pointer for AtomicPtr<T> {
4931    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4932        fmt::Pointer::fmt(&self.load(Ordering::Relaxed), f)
4933    }
4934}
4935
4936/// Signals the processor that it is inside a busy-wait spin-loop ("spin lock").
4937///
4938/// This function is deprecated in favor of [`hint::spin_loop`].
4939///
4940/// [`hint::spin_loop`]: crate::hint::spin_loop
4941#[inline]
4942#[stable(feature = "spin_loop_hint", since = "1.24.0")]
4943#[deprecated(since = "1.51.0", note = "use hint::spin_loop instead")]
4944pub fn spin_loop_hint() {
4945    spin_loop()
4946}