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