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