]> git.lizzy.rs Git - rust.git/blob - library/core/src/sync/atomic.rs
Rollup merge of #106829 - compiler-errors:more-alias-combine, r=spastorino
[rust.git] / library / core / src / 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 //! Rust atomics currently follow the same rules as [C++20 atomics][cpp], specifically `atomic_ref`.
8 //! Basically, creating a *shared reference* to one of the Rust atomic types corresponds to creating
9 //! an `atomic_ref` in C++; the `atomic_ref` is destroyed when the lifetime of the shared reference
10 //! ends. (A Rust atomic type that is exclusively owned or behind a mutable reference does *not*
11 //! correspond to an "atomic object" in C++, since it can be accessed via non-atomic operations.)
12 //!
13 //! This module defines atomic versions of a select number of primitive
14 //! types, including [`AtomicBool`], [`AtomicIsize`], [`AtomicUsize`],
15 //! [`AtomicI8`], [`AtomicU16`], etc.
16 //! Atomic types present operations that, when used correctly, synchronize
17 //! updates between threads.
18 //!
19 //! Each method takes an [`Ordering`] which represents the strength of
20 //! the memory barrier for that operation. These orderings are the
21 //! same as the [C++20 atomic orderings][1]. For more information see the [nomicon][2].
22 //!
23 //! [cpp]: https://en.cppreference.com/w/cpp/atomic
24 //! [1]: https://en.cppreference.com/w/cpp/atomic/memory_order
25 //! [2]: ../../../nomicon/atomics.html
26 //!
27 //! Atomic variables are safe to share between threads (they implement [`Sync`])
28 //! but they do not themselves provide the mechanism for sharing and follow the
29 //! [threading model](../../../std/thread/index.html#the-threading-model) of Rust.
30 //! The most common way to share an atomic variable is to put it into an [`Arc`][arc] (an
31 //! atomically-reference-counted shared pointer).
32 //!
33 //! [arc]: ../../../std/sync/struct.Arc.html
34 //!
35 //! Atomic types may be stored in static variables, initialized using
36 //! the constant initializers like [`AtomicBool::new`]. Atomic statics
37 //! are often used for lazy global initialization.
38 //!
39 //! # Portability
40 //!
41 //! All atomic types in this module are guaranteed to be [lock-free] if they're
42 //! available. This means they don't internally acquire a global mutex. Atomic
43 //! types and operations are not guaranteed to be wait-free. This means that
44 //! operations like `fetch_or` may be implemented with a compare-and-swap loop.
45 //!
46 //! Atomic operations may be implemented at the instruction layer with
47 //! larger-size atomics. For example some platforms use 4-byte atomic
48 //! instructions to implement `AtomicI8`. Note that this emulation should not
49 //! have an impact on correctness of code, it's just something to be aware of.
50 //!
51 //! The atomic types in this module might not be available on all platforms. The
52 //! atomic types here are all widely available, however, and can generally be
53 //! relied upon existing. Some notable exceptions are:
54 //!
55 //! * PowerPC and MIPS platforms with 32-bit pointers do not have `AtomicU64` or
56 //!   `AtomicI64` types.
57 //! * ARM platforms like `armv5te` that aren't for Linux only provide `load`
58 //!   and `store` operations, and do not support Compare and Swap (CAS)
59 //!   operations, such as `swap`, `fetch_add`, etc. Additionally on Linux,
60 //!   these CAS operations are implemented via [operating system support], which
61 //!   may come with a performance penalty.
62 //! * ARM targets with `thumbv6m` only provide `load` and `store` operations,
63 //!   and do not support Compare and Swap (CAS) operations, such as `swap`,
64 //!   `fetch_add`, etc.
65 //!
66 //! [operating system support]: https://www.kernel.org/doc/Documentation/arm/kernel_user_helpers.txt
67 //!
68 //! Note that future platforms may be added that also do not have support for
69 //! some atomic operations. Maximally portable code will want to be careful
70 //! about which atomic types are used. `AtomicUsize` and `AtomicIsize` are
71 //! generally the most portable, but even then they're not available everywhere.
72 //! For reference, the `std` library requires `AtomicBool`s and pointer-sized atomics, although
73 //! `core` does not.
74 //!
75 //! The `#[cfg(target_has_atomic)]` attribute can be used to conditionally
76 //! compile based on the target's supported bit widths. It is a key-value
77 //! option set for each supported size, with values "8", "16", "32", "64",
78 //! "128", and "ptr" for pointer-sized atomics.
79 //!
80 //! [lock-free]: https://en.wikipedia.org/wiki/Non-blocking_algorithm
81 //!
82 //! # Examples
83 //!
84 //! A simple spinlock:
85 //!
86 //! ```
87 //! use std::sync::Arc;
88 //! use std::sync::atomic::{AtomicUsize, Ordering};
89 //! use std::{hint, thread};
90 //!
91 //! fn main() {
92 //!     let spinlock = Arc::new(AtomicUsize::new(1));
93 //!
94 //!     let spinlock_clone = Arc::clone(&spinlock);
95 //!     let thread = thread::spawn(move|| {
96 //!         spinlock_clone.store(0, Ordering::SeqCst);
97 //!     });
98 //!
99 //!     // Wait for the other thread to release the lock
100 //!     while spinlock.load(Ordering::SeqCst) != 0 {
101 //!         hint::spin_loop();
102 //!     }
103 //!
104 //!     if let Err(panic) = thread.join() {
105 //!         println!("Thread had an error: {panic:?}");
106 //!     }
107 //! }
108 //! ```
109 //!
110 //! Keep a global count of live threads:
111 //!
112 //! ```
113 //! use std::sync::atomic::{AtomicUsize, Ordering};
114 //!
115 //! static GLOBAL_THREAD_COUNT: AtomicUsize = AtomicUsize::new(0);
116 //!
117 //! let old_thread_count = GLOBAL_THREAD_COUNT.fetch_add(1, Ordering::SeqCst);
118 //! println!("live threads: {}", old_thread_count + 1);
119 //! ```
120
121 #![stable(feature = "rust1", since = "1.0.0")]
122 #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(dead_code))]
123 #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(unused_imports))]
124 #![rustc_diagnostic_item = "atomic_mod"]
125
126 use self::Ordering::*;
127
128 use crate::cell::UnsafeCell;
129 use crate::fmt;
130 use crate::intrinsics;
131
132 use crate::hint::spin_loop;
133
134 /// A boolean type which can be safely shared between threads.
135 ///
136 /// This type has the same in-memory representation as a [`bool`].
137 ///
138 /// **Note**: This type is only available on platforms that support atomic
139 /// loads and stores of `u8`.
140 #[cfg(target_has_atomic_load_store = "8")]
141 #[stable(feature = "rust1", since = "1.0.0")]
142 #[rustc_diagnostic_item = "AtomicBool"]
143 #[repr(C, align(1))]
144 pub struct AtomicBool {
145     v: UnsafeCell<u8>,
146 }
147
148 #[cfg(target_has_atomic_load_store = "8")]
149 #[stable(feature = "rust1", since = "1.0.0")]
150 #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
151 impl const Default for AtomicBool {
152     /// Creates an `AtomicBool` initialized to `false`.
153     #[inline]
154     fn default() -> Self {
155         Self::new(false)
156     }
157 }
158
159 // Send is implicitly implemented for AtomicBool.
160 #[cfg(target_has_atomic_load_store = "8")]
161 #[stable(feature = "rust1", since = "1.0.0")]
162 unsafe impl Sync for AtomicBool {}
163
164 /// A raw pointer type which can be safely shared between threads.
165 ///
166 /// This type has the same in-memory representation as a `*mut T`.
167 ///
168 /// **Note**: This type is only available on platforms that support atomic
169 /// loads and stores of pointers. Its size depends on the target pointer's size.
170 #[cfg(target_has_atomic_load_store = "ptr")]
171 #[stable(feature = "rust1", since = "1.0.0")]
172 #[cfg_attr(not(test), rustc_diagnostic_item = "AtomicPtr")]
173 #[cfg_attr(target_pointer_width = "16", repr(C, align(2)))]
174 #[cfg_attr(target_pointer_width = "32", repr(C, align(4)))]
175 #[cfg_attr(target_pointer_width = "64", repr(C, align(8)))]
176 pub struct AtomicPtr<T> {
177     p: UnsafeCell<*mut T>,
178 }
179
180 #[cfg(target_has_atomic_load_store = "ptr")]
181 #[stable(feature = "rust1", since = "1.0.0")]
182 #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
183 impl<T> const Default for AtomicPtr<T> {
184     /// Creates a null `AtomicPtr<T>`.
185     fn default() -> AtomicPtr<T> {
186         AtomicPtr::new(crate::ptr::null_mut())
187     }
188 }
189
190 #[cfg(target_has_atomic_load_store = "ptr")]
191 #[stable(feature = "rust1", since = "1.0.0")]
192 unsafe impl<T> Send for AtomicPtr<T> {}
193 #[cfg(target_has_atomic_load_store = "ptr")]
194 #[stable(feature = "rust1", since = "1.0.0")]
195 unsafe impl<T> Sync for AtomicPtr<T> {}
196
197 /// Atomic memory orderings
198 ///
199 /// Memory orderings specify the way atomic operations synchronize memory.
200 /// In its weakest [`Ordering::Relaxed`], only the memory directly touched by the
201 /// operation is synchronized. On the other hand, a store-load pair of [`Ordering::SeqCst`]
202 /// operations synchronize other memory while additionally preserving a total order of such
203 /// operations across all threads.
204 ///
205 /// Rust's memory orderings are [the same as those of
206 /// C++20](https://en.cppreference.com/w/cpp/atomic/memory_order).
207 ///
208 /// For more information see the [nomicon].
209 ///
210 /// [nomicon]: ../../../nomicon/atomics.html
211 #[stable(feature = "rust1", since = "1.0.0")]
212 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
213 #[non_exhaustive]
214 #[rustc_diagnostic_item = "Ordering"]
215 pub enum Ordering {
216     /// No ordering constraints, only atomic operations.
217     ///
218     /// Corresponds to [`memory_order_relaxed`] in C++20.
219     ///
220     /// [`memory_order_relaxed`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Relaxed_ordering
221     #[stable(feature = "rust1", since = "1.0.0")]
222     Relaxed,
223     /// When coupled with a store, all previous operations become ordered
224     /// before any load of this value with [`Acquire`] (or stronger) ordering.
225     /// In particular, all previous writes become visible to all threads
226     /// that perform an [`Acquire`] (or stronger) load of this value.
227     ///
228     /// Notice that using this ordering for an operation that combines loads
229     /// and stores leads to a [`Relaxed`] load operation!
230     ///
231     /// This ordering is only applicable for operations that can perform a store.
232     ///
233     /// Corresponds to [`memory_order_release`] in C++20.
234     ///
235     /// [`memory_order_release`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
236     #[stable(feature = "rust1", since = "1.0.0")]
237     Release,
238     /// When coupled with a load, if the loaded value was written by a store operation with
239     /// [`Release`] (or stronger) ordering, then all subsequent operations
240     /// become ordered after that store. In particular, all subsequent loads will see data
241     /// written before the store.
242     ///
243     /// Notice that using this ordering for an operation that combines loads
244     /// and stores leads to a [`Relaxed`] store operation!
245     ///
246     /// This ordering is only applicable for operations that can perform a load.
247     ///
248     /// Corresponds to [`memory_order_acquire`] in C++20.
249     ///
250     /// [`memory_order_acquire`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
251     #[stable(feature = "rust1", since = "1.0.0")]
252     Acquire,
253     /// Has the effects of both [`Acquire`] and [`Release`] together:
254     /// For loads it uses [`Acquire`] ordering. For stores it uses the [`Release`] ordering.
255     ///
256     /// Notice that in the case of `compare_and_swap`, it is possible that the operation ends up
257     /// not performing any store and hence it has just [`Acquire`] ordering. However,
258     /// `AcqRel` will never perform [`Relaxed`] accesses.
259     ///
260     /// This ordering is only applicable for operations that combine both loads and stores.
261     ///
262     /// Corresponds to [`memory_order_acq_rel`] in C++20.
263     ///
264     /// [`memory_order_acq_rel`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
265     #[stable(feature = "rust1", since = "1.0.0")]
266     AcqRel,
267     /// Like [`Acquire`]/[`Release`]/[`AcqRel`] (for load, store, and load-with-store
268     /// operations, respectively) with the additional guarantee that all threads see all
269     /// sequentially consistent operations in the same order.
270     ///
271     /// Corresponds to [`memory_order_seq_cst`] in C++20.
272     ///
273     /// [`memory_order_seq_cst`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Sequentially-consistent_ordering
274     #[stable(feature = "rust1", since = "1.0.0")]
275     SeqCst,
276 }
277
278 /// An [`AtomicBool`] initialized to `false`.
279 #[cfg(target_has_atomic_load_store = "8")]
280 #[stable(feature = "rust1", since = "1.0.0")]
281 #[deprecated(
282     since = "1.34.0",
283     note = "the `new` function is now preferred",
284     suggestion = "AtomicBool::new(false)"
285 )]
286 pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false);
287
288 #[cfg(target_has_atomic_load_store = "8")]
289 impl AtomicBool {
290     /// Creates a new `AtomicBool`.
291     ///
292     /// # Examples
293     ///
294     /// ```
295     /// use std::sync::atomic::AtomicBool;
296     ///
297     /// let atomic_true = AtomicBool::new(true);
298     /// let atomic_false = AtomicBool::new(false);
299     /// ```
300     #[inline]
301     #[stable(feature = "rust1", since = "1.0.0")]
302     #[rustc_const_stable(feature = "const_atomic_new", since = "1.24.0")]
303     #[must_use]
304     pub const fn new(v: bool) -> AtomicBool {
305         AtomicBool { v: UnsafeCell::new(v as u8) }
306     }
307
308     /// Returns a mutable reference to the underlying [`bool`].
309     ///
310     /// This is safe because the mutable reference guarantees that no other threads are
311     /// concurrently accessing the atomic data.
312     ///
313     /// # Examples
314     ///
315     /// ```
316     /// use std::sync::atomic::{AtomicBool, Ordering};
317     ///
318     /// let mut some_bool = AtomicBool::new(true);
319     /// assert_eq!(*some_bool.get_mut(), true);
320     /// *some_bool.get_mut() = false;
321     /// assert_eq!(some_bool.load(Ordering::SeqCst), false);
322     /// ```
323     #[inline]
324     #[stable(feature = "atomic_access", since = "1.15.0")]
325     pub fn get_mut(&mut self) -> &mut bool {
326         // SAFETY: the mutable reference guarantees unique ownership.
327         unsafe { &mut *(self.v.get() as *mut bool) }
328     }
329
330     /// Get atomic access to a `&mut bool`.
331     ///
332     /// # Examples
333     ///
334     /// ```
335     /// #![feature(atomic_from_mut)]
336     /// use std::sync::atomic::{AtomicBool, Ordering};
337     ///
338     /// let mut some_bool = true;
339     /// let a = AtomicBool::from_mut(&mut some_bool);
340     /// a.store(false, Ordering::Relaxed);
341     /// assert_eq!(some_bool, false);
342     /// ```
343     #[inline]
344     #[cfg(target_has_atomic_equal_alignment = "8")]
345     #[unstable(feature = "atomic_from_mut", issue = "76314")]
346     pub fn from_mut(v: &mut bool) -> &mut Self {
347         // SAFETY: the mutable reference guarantees unique ownership, and
348         // alignment of both `bool` and `Self` is 1.
349         unsafe { &mut *(v as *mut bool as *mut Self) }
350     }
351
352     /// Get non-atomic access to a `&mut [AtomicBool]` slice.
353     ///
354     /// This is safe because the mutable reference guarantees that no other threads are
355     /// concurrently accessing the atomic data.
356     ///
357     /// # Examples
358     ///
359     /// ```
360     /// #![feature(atomic_from_mut, inline_const)]
361     /// use std::sync::atomic::{AtomicBool, Ordering};
362     ///
363     /// let mut some_bools = [const { AtomicBool::new(false) }; 10];
364     ///
365     /// let view: &mut [bool] = AtomicBool::get_mut_slice(&mut some_bools);
366     /// assert_eq!(view, [false; 10]);
367     /// view[..5].copy_from_slice(&[true; 5]);
368     ///
369     /// std::thread::scope(|s| {
370     ///     for t in &some_bools[..5] {
371     ///         s.spawn(move || assert_eq!(t.load(Ordering::Relaxed), true));
372     ///     }
373     ///
374     ///     for f in &some_bools[5..] {
375     ///         s.spawn(move || assert_eq!(f.load(Ordering::Relaxed), false));
376     ///     }
377     /// });
378     /// ```
379     #[inline]
380     #[unstable(feature = "atomic_from_mut", issue = "76314")]
381     pub fn get_mut_slice(this: &mut [Self]) -> &mut [bool] {
382         // SAFETY: the mutable reference guarantees unique ownership.
383         unsafe { &mut *(this as *mut [Self] as *mut [bool]) }
384     }
385
386     /// Get atomic access to a `&mut [bool]` slice.
387     ///
388     /// # Examples
389     ///
390     /// ```
391     /// #![feature(atomic_from_mut)]
392     /// use std::sync::atomic::{AtomicBool, Ordering};
393     ///
394     /// let mut some_bools = [false; 10];
395     /// let a = &*AtomicBool::from_mut_slice(&mut some_bools);
396     /// std::thread::scope(|s| {
397     ///     for i in 0..a.len() {
398     ///         s.spawn(move || a[i].store(true, Ordering::Relaxed));
399     ///     }
400     /// });
401     /// assert_eq!(some_bools, [true; 10]);
402     /// ```
403     #[inline]
404     #[cfg(target_has_atomic_equal_alignment = "8")]
405     #[unstable(feature = "atomic_from_mut", issue = "76314")]
406     pub fn from_mut_slice(v: &mut [bool]) -> &mut [Self] {
407         // SAFETY: the mutable reference guarantees unique ownership, and
408         // alignment of both `bool` and `Self` is 1.
409         unsafe { &mut *(v as *mut [bool] as *mut [Self]) }
410     }
411
412     /// Consumes the atomic and returns the contained value.
413     ///
414     /// This is safe because passing `self` by value guarantees that no other threads are
415     /// concurrently accessing the atomic data.
416     ///
417     /// # Examples
418     ///
419     /// ```
420     /// use std::sync::atomic::AtomicBool;
421     ///
422     /// let some_bool = AtomicBool::new(true);
423     /// assert_eq!(some_bool.into_inner(), true);
424     /// ```
425     #[inline]
426     #[stable(feature = "atomic_access", since = "1.15.0")]
427     #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")]
428     pub const fn into_inner(self) -> bool {
429         self.v.into_inner() != 0
430     }
431
432     /// Loads a value from the bool.
433     ///
434     /// `load` takes an [`Ordering`] argument which describes the memory ordering
435     /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
436     ///
437     /// # Panics
438     ///
439     /// Panics if `order` is [`Release`] or [`AcqRel`].
440     ///
441     /// # Examples
442     ///
443     /// ```
444     /// use std::sync::atomic::{AtomicBool, Ordering};
445     ///
446     /// let some_bool = AtomicBool::new(true);
447     ///
448     /// assert_eq!(some_bool.load(Ordering::Relaxed), true);
449     /// ```
450     #[inline]
451     #[stable(feature = "rust1", since = "1.0.0")]
452     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
453     pub fn load(&self, order: Ordering) -> bool {
454         // SAFETY: any data races are prevented by atomic intrinsics and the raw
455         // pointer passed in is valid because we got it from a reference.
456         unsafe { atomic_load(self.v.get(), order) != 0 }
457     }
458
459     /// Stores a value into the bool.
460     ///
461     /// `store` takes an [`Ordering`] argument which describes the memory ordering
462     /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
463     ///
464     /// # Panics
465     ///
466     /// Panics if `order` is [`Acquire`] or [`AcqRel`].
467     ///
468     /// # Examples
469     ///
470     /// ```
471     /// use std::sync::atomic::{AtomicBool, Ordering};
472     ///
473     /// let some_bool = AtomicBool::new(true);
474     ///
475     /// some_bool.store(false, Ordering::Relaxed);
476     /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
477     /// ```
478     #[inline]
479     #[stable(feature = "rust1", since = "1.0.0")]
480     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
481     pub fn store(&self, val: bool, order: Ordering) {
482         // SAFETY: any data races are prevented by atomic intrinsics and the raw
483         // pointer passed in is valid because we got it from a reference.
484         unsafe {
485             atomic_store(self.v.get(), val as u8, order);
486         }
487     }
488
489     /// Stores a value into the bool, returning the previous value.
490     ///
491     /// `swap` takes an [`Ordering`] argument which describes the memory ordering
492     /// of this operation. All ordering modes are possible. Note that using
493     /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
494     /// using [`Release`] makes the load part [`Relaxed`].
495     ///
496     /// **Note:** This method is only available on platforms that support atomic
497     /// operations on `u8`.
498     ///
499     /// # Examples
500     ///
501     /// ```
502     /// use std::sync::atomic::{AtomicBool, Ordering};
503     ///
504     /// let some_bool = AtomicBool::new(true);
505     ///
506     /// assert_eq!(some_bool.swap(false, Ordering::Relaxed), true);
507     /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
508     /// ```
509     #[inline]
510     #[stable(feature = "rust1", since = "1.0.0")]
511     #[cfg(target_has_atomic = "8")]
512     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
513     pub fn swap(&self, val: bool, order: Ordering) -> bool {
514         // SAFETY: data races are prevented by atomic intrinsics.
515         unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 }
516     }
517
518     /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
519     ///
520     /// The return value is always the previous value. If it is equal to `current`, then the value
521     /// was updated.
522     ///
523     /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
524     /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
525     /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
526     /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
527     /// happens, and using [`Release`] makes the load part [`Relaxed`].
528     ///
529     /// **Note:** This method is only available on platforms that support atomic
530     /// operations on `u8`.
531     ///
532     /// # Migrating to `compare_exchange` and `compare_exchange_weak`
533     ///
534     /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
535     /// memory orderings:
536     ///
537     /// Original | Success | Failure
538     /// -------- | ------- | -------
539     /// Relaxed  | Relaxed | Relaxed
540     /// Acquire  | Acquire | Acquire
541     /// Release  | Release | Relaxed
542     /// AcqRel   | AcqRel  | Acquire
543     /// SeqCst   | SeqCst  | SeqCst
544     ///
545     /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
546     /// which allows the compiler to generate better assembly code when the compare and swap
547     /// is used in a loop.
548     ///
549     /// # Examples
550     ///
551     /// ```
552     /// use std::sync::atomic::{AtomicBool, Ordering};
553     ///
554     /// let some_bool = AtomicBool::new(true);
555     ///
556     /// assert_eq!(some_bool.compare_and_swap(true, false, Ordering::Relaxed), true);
557     /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
558     ///
559     /// assert_eq!(some_bool.compare_and_swap(true, true, Ordering::Relaxed), false);
560     /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
561     /// ```
562     #[inline]
563     #[stable(feature = "rust1", since = "1.0.0")]
564     #[deprecated(
565         since = "1.50.0",
566         note = "Use `compare_exchange` or `compare_exchange_weak` instead"
567     )]
568     #[cfg(target_has_atomic = "8")]
569     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
570     pub fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> bool {
571         match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
572             Ok(x) => x,
573             Err(x) => x,
574         }
575     }
576
577     /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
578     ///
579     /// The return value is a result indicating whether the new value was written and containing
580     /// the previous value. On success this value is guaranteed to be equal to `current`.
581     ///
582     /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
583     /// ordering of this operation. `success` describes the required ordering for the
584     /// read-modify-write operation that takes place if the comparison with `current` succeeds.
585     /// `failure` describes the required ordering for the load operation that takes place when
586     /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
587     /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
588     /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
589     ///
590     /// **Note:** This method is only available on platforms that support atomic
591     /// operations on `u8`.
592     ///
593     /// # Examples
594     ///
595     /// ```
596     /// use std::sync::atomic::{AtomicBool, Ordering};
597     ///
598     /// let some_bool = AtomicBool::new(true);
599     ///
600     /// assert_eq!(some_bool.compare_exchange(true,
601     ///                                       false,
602     ///                                       Ordering::Acquire,
603     ///                                       Ordering::Relaxed),
604     ///            Ok(true));
605     /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
606     ///
607     /// assert_eq!(some_bool.compare_exchange(true, true,
608     ///                                       Ordering::SeqCst,
609     ///                                       Ordering::Acquire),
610     ///            Err(false));
611     /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
612     /// ```
613     #[inline]
614     #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
615     #[doc(alias = "compare_and_swap")]
616     #[cfg(target_has_atomic = "8")]
617     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
618     pub fn compare_exchange(
619         &self,
620         current: bool,
621         new: bool,
622         success: Ordering,
623         failure: Ordering,
624     ) -> Result<bool, bool> {
625         // SAFETY: data races are prevented by atomic intrinsics.
626         match unsafe {
627             atomic_compare_exchange(self.v.get(), current as u8, new as u8, success, failure)
628         } {
629             Ok(x) => Ok(x != 0),
630             Err(x) => Err(x != 0),
631         }
632     }
633
634     /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
635     ///
636     /// Unlike [`AtomicBool::compare_exchange`], this function is allowed to spuriously fail even when the
637     /// comparison succeeds, which can result in more efficient code on some platforms. The
638     /// return value is a result indicating whether the new value was written and containing the
639     /// previous value.
640     ///
641     /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
642     /// ordering of this operation. `success` describes the required ordering for the
643     /// read-modify-write operation that takes place if the comparison with `current` succeeds.
644     /// `failure` describes the required ordering for the load operation that takes place when
645     /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
646     /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
647     /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
648     ///
649     /// **Note:** This method is only available on platforms that support atomic
650     /// operations on `u8`.
651     ///
652     /// # Examples
653     ///
654     /// ```
655     /// use std::sync::atomic::{AtomicBool, Ordering};
656     ///
657     /// let val = AtomicBool::new(false);
658     ///
659     /// let new = true;
660     /// let mut old = val.load(Ordering::Relaxed);
661     /// loop {
662     ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
663     ///         Ok(_) => break,
664     ///         Err(x) => old = x,
665     ///     }
666     /// }
667     /// ```
668     #[inline]
669     #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
670     #[doc(alias = "compare_and_swap")]
671     #[cfg(target_has_atomic = "8")]
672     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
673     pub fn compare_exchange_weak(
674         &self,
675         current: bool,
676         new: bool,
677         success: Ordering,
678         failure: Ordering,
679     ) -> Result<bool, bool> {
680         // SAFETY: data races are prevented by atomic intrinsics.
681         match unsafe {
682             atomic_compare_exchange_weak(self.v.get(), current as u8, new as u8, success, failure)
683         } {
684             Ok(x) => Ok(x != 0),
685             Err(x) => Err(x != 0),
686         }
687     }
688
689     /// Logical "and" with a boolean value.
690     ///
691     /// Performs a logical "and" operation on the current value and the argument `val`, and sets
692     /// the new value to the result.
693     ///
694     /// Returns the previous value.
695     ///
696     /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
697     /// of this operation. All ordering modes are possible. Note that using
698     /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
699     /// using [`Release`] makes the load part [`Relaxed`].
700     ///
701     /// **Note:** This method is only available on platforms that support atomic
702     /// operations on `u8`.
703     ///
704     /// # Examples
705     ///
706     /// ```
707     /// use std::sync::atomic::{AtomicBool, Ordering};
708     ///
709     /// let foo = AtomicBool::new(true);
710     /// assert_eq!(foo.fetch_and(false, Ordering::SeqCst), true);
711     /// assert_eq!(foo.load(Ordering::SeqCst), false);
712     ///
713     /// let foo = AtomicBool::new(true);
714     /// assert_eq!(foo.fetch_and(true, Ordering::SeqCst), true);
715     /// assert_eq!(foo.load(Ordering::SeqCst), true);
716     ///
717     /// let foo = AtomicBool::new(false);
718     /// assert_eq!(foo.fetch_and(false, Ordering::SeqCst), false);
719     /// assert_eq!(foo.load(Ordering::SeqCst), false);
720     /// ```
721     #[inline]
722     #[stable(feature = "rust1", since = "1.0.0")]
723     #[cfg(target_has_atomic = "8")]
724     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
725     pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
726         // SAFETY: data races are prevented by atomic intrinsics.
727         unsafe { atomic_and(self.v.get(), val as u8, order) != 0 }
728     }
729
730     /// Logical "nand" with a boolean value.
731     ///
732     /// Performs a logical "nand" operation on the current value and the argument `val`, and sets
733     /// the new value to the result.
734     ///
735     /// Returns the previous value.
736     ///
737     /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
738     /// of this operation. All ordering modes are possible. Note that using
739     /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
740     /// using [`Release`] makes the load part [`Relaxed`].
741     ///
742     /// **Note:** This method is only available on platforms that support atomic
743     /// operations on `u8`.
744     ///
745     /// # Examples
746     ///
747     /// ```
748     /// use std::sync::atomic::{AtomicBool, Ordering};
749     ///
750     /// let foo = AtomicBool::new(true);
751     /// assert_eq!(foo.fetch_nand(false, Ordering::SeqCst), true);
752     /// assert_eq!(foo.load(Ordering::SeqCst), true);
753     ///
754     /// let foo = AtomicBool::new(true);
755     /// assert_eq!(foo.fetch_nand(true, Ordering::SeqCst), true);
756     /// assert_eq!(foo.load(Ordering::SeqCst) as usize, 0);
757     /// assert_eq!(foo.load(Ordering::SeqCst), false);
758     ///
759     /// let foo = AtomicBool::new(false);
760     /// assert_eq!(foo.fetch_nand(false, Ordering::SeqCst), false);
761     /// assert_eq!(foo.load(Ordering::SeqCst), true);
762     /// ```
763     #[inline]
764     #[stable(feature = "rust1", since = "1.0.0")]
765     #[cfg(target_has_atomic = "8")]
766     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
767     pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
768         // We can't use atomic_nand here because it can result in a bool with
769         // an invalid value. This happens because the atomic operation is done
770         // with an 8-bit integer internally, which would set the upper 7 bits.
771         // So we just use fetch_xor or swap instead.
772         if val {
773             // !(x & true) == !x
774             // We must invert the bool.
775             self.fetch_xor(true, order)
776         } else {
777             // !(x & false) == true
778             // We must set the bool to true.
779             self.swap(true, order)
780         }
781     }
782
783     /// Logical "or" with a boolean value.
784     ///
785     /// Performs a logical "or" operation on the current value and the argument `val`, and sets the
786     /// new value to the result.
787     ///
788     /// Returns the previous value.
789     ///
790     /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
791     /// of this operation. All ordering modes are possible. Note that using
792     /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
793     /// using [`Release`] makes the load part [`Relaxed`].
794     ///
795     /// **Note:** This method is only available on platforms that support atomic
796     /// operations on `u8`.
797     ///
798     /// # Examples
799     ///
800     /// ```
801     /// use std::sync::atomic::{AtomicBool, Ordering};
802     ///
803     /// let foo = AtomicBool::new(true);
804     /// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), true);
805     /// assert_eq!(foo.load(Ordering::SeqCst), true);
806     ///
807     /// let foo = AtomicBool::new(true);
808     /// assert_eq!(foo.fetch_or(true, Ordering::SeqCst), true);
809     /// assert_eq!(foo.load(Ordering::SeqCst), true);
810     ///
811     /// let foo = AtomicBool::new(false);
812     /// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), false);
813     /// assert_eq!(foo.load(Ordering::SeqCst), false);
814     /// ```
815     #[inline]
816     #[stable(feature = "rust1", since = "1.0.0")]
817     #[cfg(target_has_atomic = "8")]
818     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
819     pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
820         // SAFETY: data races are prevented by atomic intrinsics.
821         unsafe { atomic_or(self.v.get(), val as u8, order) != 0 }
822     }
823
824     /// Logical "xor" with a boolean value.
825     ///
826     /// Performs a logical "xor" operation on the current value and the argument `val`, and sets
827     /// the new value to the result.
828     ///
829     /// Returns the previous value.
830     ///
831     /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
832     /// of this operation. All ordering modes are possible. Note that using
833     /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
834     /// using [`Release`] makes the load part [`Relaxed`].
835     ///
836     /// **Note:** This method is only available on platforms that support atomic
837     /// operations on `u8`.
838     ///
839     /// # Examples
840     ///
841     /// ```
842     /// use std::sync::atomic::{AtomicBool, Ordering};
843     ///
844     /// let foo = AtomicBool::new(true);
845     /// assert_eq!(foo.fetch_xor(false, Ordering::SeqCst), true);
846     /// assert_eq!(foo.load(Ordering::SeqCst), true);
847     ///
848     /// let foo = AtomicBool::new(true);
849     /// assert_eq!(foo.fetch_xor(true, Ordering::SeqCst), true);
850     /// assert_eq!(foo.load(Ordering::SeqCst), false);
851     ///
852     /// let foo = AtomicBool::new(false);
853     /// assert_eq!(foo.fetch_xor(false, Ordering::SeqCst), false);
854     /// assert_eq!(foo.load(Ordering::SeqCst), false);
855     /// ```
856     #[inline]
857     #[stable(feature = "rust1", since = "1.0.0")]
858     #[cfg(target_has_atomic = "8")]
859     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
860     pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
861         // SAFETY: data races are prevented by atomic intrinsics.
862         unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 }
863     }
864
865     /// Logical "not" with a boolean value.
866     ///
867     /// Performs a logical "not" operation on the current value, and sets
868     /// the new value to the result.
869     ///
870     /// Returns the previous value.
871     ///
872     /// `fetch_not` takes an [`Ordering`] argument which describes the memory ordering
873     /// of this operation. All ordering modes are possible. Note that using
874     /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
875     /// using [`Release`] makes the load part [`Relaxed`].
876     ///
877     /// **Note:** This method is only available on platforms that support atomic
878     /// operations on `u8`.
879     ///
880     /// # Examples
881     ///
882     /// ```
883     /// #![feature(atomic_bool_fetch_not)]
884     /// use std::sync::atomic::{AtomicBool, Ordering};
885     ///
886     /// let foo = AtomicBool::new(true);
887     /// assert_eq!(foo.fetch_not(Ordering::SeqCst), true);
888     /// assert_eq!(foo.load(Ordering::SeqCst), false);
889     ///
890     /// let foo = AtomicBool::new(false);
891     /// assert_eq!(foo.fetch_not(Ordering::SeqCst), false);
892     /// assert_eq!(foo.load(Ordering::SeqCst), true);
893     /// ```
894     #[inline]
895     #[unstable(feature = "atomic_bool_fetch_not", issue = "98485")]
896     #[cfg(target_has_atomic = "8")]
897     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
898     pub fn fetch_not(&self, order: Ordering) -> bool {
899         self.fetch_xor(true, order)
900     }
901
902     /// Returns a mutable pointer to the underlying [`bool`].
903     ///
904     /// Doing non-atomic reads and writes on the resulting integer can be a data race.
905     /// This method is mostly useful for FFI, where the function signature may use
906     /// `*mut bool` instead of `&AtomicBool`.
907     ///
908     /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
909     /// atomic types work with interior mutability. All modifications of an atomic change the value
910     /// through a shared reference, and can do so safely as long as they use atomic operations. Any
911     /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the same
912     /// restriction: operations on it must be atomic.
913     ///
914     /// # Examples
915     ///
916     /// ```ignore (extern-declaration)
917     /// # fn main() {
918     /// use std::sync::atomic::AtomicBool;
919     /// extern "C" {
920     ///     fn my_atomic_op(arg: *mut bool);
921     /// }
922     ///
923     /// let mut atomic = AtomicBool::new(true);
924     /// unsafe {
925     ///     my_atomic_op(atomic.as_mut_ptr());
926     /// }
927     /// # }
928     /// ```
929     #[inline]
930     #[unstable(feature = "atomic_mut_ptr", reason = "recently added", issue = "66893")]
931     pub fn as_mut_ptr(&self) -> *mut bool {
932         self.v.get() as *mut bool
933     }
934
935     /// Fetches the value, and applies a function to it that returns an optional
936     /// new value. Returns a `Result` of `Ok(previous_value)` if the function
937     /// returned `Some(_)`, else `Err(previous_value)`.
938     ///
939     /// Note: This may call the function multiple times if the value has been
940     /// changed from other threads in the meantime, as long as the function
941     /// returns `Some(_)`, but the function will have been applied only once to
942     /// the stored value.
943     ///
944     /// `fetch_update` takes two [`Ordering`] arguments to describe the memory
945     /// ordering of this operation. The first describes the required ordering for
946     /// when the operation finally succeeds while the second describes the
947     /// required ordering for loads. These correspond to the success and failure
948     /// orderings of [`AtomicBool::compare_exchange`] respectively.
949     ///
950     /// Using [`Acquire`] as success ordering makes the store part of this
951     /// operation [`Relaxed`], and using [`Release`] makes the final successful
952     /// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`],
953     /// [`Acquire`] or [`Relaxed`].
954     ///
955     /// **Note:** This method is only available on platforms that support atomic
956     /// operations on `u8`.
957     ///
958     /// # Considerations
959     ///
960     /// This method is not magic;  it is not provided by the hardware.
961     /// It is implemented in terms of [`AtomicBool::compare_exchange_weak`], and suffers from the same drawbacks.
962     /// In particular, this method will not circumvent the [ABA Problem].
963     ///
964     /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
965     ///
966     /// # Examples
967     ///
968     /// ```rust
969     /// use std::sync::atomic::{AtomicBool, Ordering};
970     ///
971     /// let x = AtomicBool::new(false);
972     /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(false));
973     /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(!x)), Ok(false));
974     /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(!x)), Ok(true));
975     /// assert_eq!(x.load(Ordering::SeqCst), false);
976     /// ```
977     #[inline]
978     #[stable(feature = "atomic_fetch_update", since = "1.53.0")]
979     #[cfg(target_has_atomic = "8")]
980     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
981     pub fn fetch_update<F>(
982         &self,
983         set_order: Ordering,
984         fetch_order: Ordering,
985         mut f: F,
986     ) -> Result<bool, bool>
987     where
988         F: FnMut(bool) -> Option<bool>,
989     {
990         let mut prev = self.load(fetch_order);
991         while let Some(next) = f(prev) {
992             match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
993                 x @ Ok(_) => return x,
994                 Err(next_prev) => prev = next_prev,
995             }
996         }
997         Err(prev)
998     }
999 }
1000
1001 #[cfg(target_has_atomic_load_store = "ptr")]
1002 impl<T> AtomicPtr<T> {
1003     /// Creates a new `AtomicPtr`.
1004     ///
1005     /// # Examples
1006     ///
1007     /// ```
1008     /// use std::sync::atomic::AtomicPtr;
1009     ///
1010     /// let ptr = &mut 5;
1011     /// let atomic_ptr = AtomicPtr::new(ptr);
1012     /// ```
1013     #[inline]
1014     #[stable(feature = "rust1", since = "1.0.0")]
1015     #[rustc_const_stable(feature = "const_atomic_new", since = "1.24.0")]
1016     pub const fn new(p: *mut T) -> AtomicPtr<T> {
1017         AtomicPtr { p: UnsafeCell::new(p) }
1018     }
1019
1020     /// Returns a mutable reference to the underlying pointer.
1021     ///
1022     /// This is safe because the mutable reference guarantees that no other threads are
1023     /// concurrently accessing the atomic data.
1024     ///
1025     /// # Examples
1026     ///
1027     /// ```
1028     /// use std::sync::atomic::{AtomicPtr, Ordering};
1029     ///
1030     /// let mut data = 10;
1031     /// let mut atomic_ptr = AtomicPtr::new(&mut data);
1032     /// let mut other_data = 5;
1033     /// *atomic_ptr.get_mut() = &mut other_data;
1034     /// assert_eq!(unsafe { *atomic_ptr.load(Ordering::SeqCst) }, 5);
1035     /// ```
1036     #[inline]
1037     #[stable(feature = "atomic_access", since = "1.15.0")]
1038     pub fn get_mut(&mut self) -> &mut *mut T {
1039         self.p.get_mut()
1040     }
1041
1042     /// Get atomic access to a pointer.
1043     ///
1044     /// # Examples
1045     ///
1046     /// ```
1047     /// #![feature(atomic_from_mut)]
1048     /// use std::sync::atomic::{AtomicPtr, Ordering};
1049     ///
1050     /// let mut data = 123;
1051     /// let mut some_ptr = &mut data as *mut i32;
1052     /// let a = AtomicPtr::from_mut(&mut some_ptr);
1053     /// let mut other_data = 456;
1054     /// a.store(&mut other_data, Ordering::Relaxed);
1055     /// assert_eq!(unsafe { *some_ptr }, 456);
1056     /// ```
1057     #[inline]
1058     #[cfg(target_has_atomic_equal_alignment = "ptr")]
1059     #[unstable(feature = "atomic_from_mut", issue = "76314")]
1060     pub fn from_mut(v: &mut *mut T) -> &mut Self {
1061         use crate::mem::align_of;
1062         let [] = [(); align_of::<AtomicPtr<()>>() - align_of::<*mut ()>()];
1063         // SAFETY:
1064         //  - the mutable reference guarantees unique ownership.
1065         //  - the alignment of `*mut T` and `Self` is the same on all platforms
1066         //    supported by rust, as verified above.
1067         unsafe { &mut *(v as *mut *mut T as *mut Self) }
1068     }
1069
1070     /// Get non-atomic access to a `&mut [AtomicPtr]` slice.
1071     ///
1072     /// This is safe because the mutable reference guarantees that no other threads are
1073     /// concurrently accessing the atomic data.
1074     ///
1075     /// # Examples
1076     ///
1077     /// ```
1078     /// #![feature(atomic_from_mut, inline_const)]
1079     /// use std::ptr::null_mut;
1080     /// use std::sync::atomic::{AtomicPtr, Ordering};
1081     ///
1082     /// let mut some_ptrs = [const { AtomicPtr::new(null_mut::<String>()) }; 10];
1083     ///
1084     /// let view: &mut [*mut String] = AtomicPtr::get_mut_slice(&mut some_ptrs);
1085     /// assert_eq!(view, [null_mut::<String>(); 10]);
1086     /// view
1087     ///     .iter_mut()
1088     ///     .enumerate()
1089     ///     .for_each(|(i, ptr)| *ptr = Box::into_raw(Box::new(format!("iteration#{i}"))));
1090     ///
1091     /// std::thread::scope(|s| {
1092     ///     for ptr in &some_ptrs {
1093     ///         s.spawn(move || {
1094     ///             let ptr = ptr.load(Ordering::Relaxed);
1095     ///             assert!(!ptr.is_null());
1096     ///
1097     ///             let name = unsafe { Box::from_raw(ptr) };
1098     ///             println!("Hello, {name}!");
1099     ///         });
1100     ///     }
1101     /// });
1102     /// ```
1103     #[inline]
1104     #[unstable(feature = "atomic_from_mut", issue = "76314")]
1105     pub fn get_mut_slice(this: &mut [Self]) -> &mut [*mut T] {
1106         // SAFETY: the mutable reference guarantees unique ownership.
1107         unsafe { &mut *(this as *mut [Self] as *mut [*mut T]) }
1108     }
1109
1110     /// Get atomic access to a slice of pointers.
1111     ///
1112     /// # Examples
1113     ///
1114     /// ```
1115     /// #![feature(atomic_from_mut)]
1116     /// use std::ptr::null_mut;
1117     /// use std::sync::atomic::{AtomicPtr, Ordering};
1118     ///
1119     /// let mut some_ptrs = [null_mut::<String>(); 10];
1120     /// let a = &*AtomicPtr::from_mut_slice(&mut some_ptrs);
1121     /// std::thread::scope(|s| {
1122     ///     for i in 0..a.len() {
1123     ///         s.spawn(move || {
1124     ///             let name = Box::new(format!("thread{i}"));
1125     ///             a[i].store(Box::into_raw(name), Ordering::Relaxed);
1126     ///         });
1127     ///     }
1128     /// });
1129     /// for p in some_ptrs {
1130     ///     assert!(!p.is_null());
1131     ///     let name = unsafe { Box::from_raw(p) };
1132     ///     println!("Hello, {name}!");
1133     /// }
1134     /// ```
1135     #[inline]
1136     #[cfg(target_has_atomic_equal_alignment = "ptr")]
1137     #[unstable(feature = "atomic_from_mut", issue = "76314")]
1138     pub fn from_mut_slice(v: &mut [*mut T]) -> &mut [Self] {
1139         // SAFETY:
1140         //  - the mutable reference guarantees unique ownership.
1141         //  - the alignment of `*mut T` and `Self` is the same on all platforms
1142         //    supported by rust, as verified above.
1143         unsafe { &mut *(v as *mut [*mut T] as *mut [Self]) }
1144     }
1145
1146     /// Consumes the atomic and returns the contained value.
1147     ///
1148     /// This is safe because passing `self` by value guarantees that no other threads are
1149     /// concurrently accessing the atomic data.
1150     ///
1151     /// # Examples
1152     ///
1153     /// ```
1154     /// use std::sync::atomic::AtomicPtr;
1155     ///
1156     /// let mut data = 5;
1157     /// let atomic_ptr = AtomicPtr::new(&mut data);
1158     /// assert_eq!(unsafe { *atomic_ptr.into_inner() }, 5);
1159     /// ```
1160     #[inline]
1161     #[stable(feature = "atomic_access", since = "1.15.0")]
1162     #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")]
1163     pub const fn into_inner(self) -> *mut T {
1164         self.p.into_inner()
1165     }
1166
1167     /// Loads a value from the pointer.
1168     ///
1169     /// `load` takes an [`Ordering`] argument which describes the memory ordering
1170     /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
1171     ///
1172     /// # Panics
1173     ///
1174     /// Panics if `order` is [`Release`] or [`AcqRel`].
1175     ///
1176     /// # Examples
1177     ///
1178     /// ```
1179     /// use std::sync::atomic::{AtomicPtr, Ordering};
1180     ///
1181     /// let ptr = &mut 5;
1182     /// let some_ptr = AtomicPtr::new(ptr);
1183     ///
1184     /// let value = some_ptr.load(Ordering::Relaxed);
1185     /// ```
1186     #[inline]
1187     #[stable(feature = "rust1", since = "1.0.0")]
1188     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1189     pub fn load(&self, order: Ordering) -> *mut T {
1190         // SAFETY: data races are prevented by atomic intrinsics.
1191         unsafe { atomic_load(self.p.get(), order) }
1192     }
1193
1194     /// Stores a value into the pointer.
1195     ///
1196     /// `store` takes an [`Ordering`] argument which describes the memory ordering
1197     /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
1198     ///
1199     /// # Panics
1200     ///
1201     /// Panics if `order` is [`Acquire`] or [`AcqRel`].
1202     ///
1203     /// # Examples
1204     ///
1205     /// ```
1206     /// use std::sync::atomic::{AtomicPtr, Ordering};
1207     ///
1208     /// let ptr = &mut 5;
1209     /// let some_ptr = AtomicPtr::new(ptr);
1210     ///
1211     /// let other_ptr = &mut 10;
1212     ///
1213     /// some_ptr.store(other_ptr, Ordering::Relaxed);
1214     /// ```
1215     #[inline]
1216     #[stable(feature = "rust1", since = "1.0.0")]
1217     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1218     pub fn store(&self, ptr: *mut T, order: Ordering) {
1219         // SAFETY: data races are prevented by atomic intrinsics.
1220         unsafe {
1221             atomic_store(self.p.get(), ptr, order);
1222         }
1223     }
1224
1225     /// Stores a value into the pointer, returning the previous value.
1226     ///
1227     /// `swap` takes an [`Ordering`] argument which describes the memory ordering
1228     /// of this operation. All ordering modes are possible. Note that using
1229     /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
1230     /// using [`Release`] makes the load part [`Relaxed`].
1231     ///
1232     /// **Note:** This method is only available on platforms that support atomic
1233     /// operations on pointers.
1234     ///
1235     /// # Examples
1236     ///
1237     /// ```
1238     /// use std::sync::atomic::{AtomicPtr, Ordering};
1239     ///
1240     /// let ptr = &mut 5;
1241     /// let some_ptr = AtomicPtr::new(ptr);
1242     ///
1243     /// let other_ptr = &mut 10;
1244     ///
1245     /// let value = some_ptr.swap(other_ptr, Ordering::Relaxed);
1246     /// ```
1247     #[inline]
1248     #[stable(feature = "rust1", since = "1.0.0")]
1249     #[cfg(target_has_atomic = "ptr")]
1250     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1251     pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
1252         // SAFETY: data races are prevented by atomic intrinsics.
1253         unsafe { atomic_swap(self.p.get(), ptr, order) }
1254     }
1255
1256     /// Stores a value into the pointer if the current value is the same as the `current` value.
1257     ///
1258     /// The return value is always the previous value. If it is equal to `current`, then the value
1259     /// was updated.
1260     ///
1261     /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
1262     /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
1263     /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
1264     /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
1265     /// happens, and using [`Release`] makes the load part [`Relaxed`].
1266     ///
1267     /// **Note:** This method is only available on platforms that support atomic
1268     /// operations on pointers.
1269     ///
1270     /// # Migrating to `compare_exchange` and `compare_exchange_weak`
1271     ///
1272     /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
1273     /// memory orderings:
1274     ///
1275     /// Original | Success | Failure
1276     /// -------- | ------- | -------
1277     /// Relaxed  | Relaxed | Relaxed
1278     /// Acquire  | Acquire | Acquire
1279     /// Release  | Release | Relaxed
1280     /// AcqRel   | AcqRel  | Acquire
1281     /// SeqCst   | SeqCst  | SeqCst
1282     ///
1283     /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
1284     /// which allows the compiler to generate better assembly code when the compare and swap
1285     /// is used in a loop.
1286     ///
1287     /// # Examples
1288     ///
1289     /// ```
1290     /// use std::sync::atomic::{AtomicPtr, Ordering};
1291     ///
1292     /// let ptr = &mut 5;
1293     /// let some_ptr = AtomicPtr::new(ptr);
1294     ///
1295     /// let other_ptr = &mut 10;
1296     ///
1297     /// let value = some_ptr.compare_and_swap(ptr, other_ptr, Ordering::Relaxed);
1298     /// ```
1299     #[inline]
1300     #[stable(feature = "rust1", since = "1.0.0")]
1301     #[deprecated(
1302         since = "1.50.0",
1303         note = "Use `compare_exchange` or `compare_exchange_weak` instead"
1304     )]
1305     #[cfg(target_has_atomic = "ptr")]
1306     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1307     pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) -> *mut T {
1308         match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
1309             Ok(x) => x,
1310             Err(x) => x,
1311         }
1312     }
1313
1314     /// Stores a value into the pointer if the current value is the same as the `current` value.
1315     ///
1316     /// The return value is a result indicating whether the new value was written and containing
1317     /// the previous value. On success this value is guaranteed to be equal to `current`.
1318     ///
1319     /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
1320     /// ordering of this operation. `success` describes the required ordering for the
1321     /// read-modify-write operation that takes place if the comparison with `current` succeeds.
1322     /// `failure` describes the required ordering for the load operation that takes place when
1323     /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
1324     /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
1325     /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
1326     ///
1327     /// **Note:** This method is only available on platforms that support atomic
1328     /// operations on pointers.
1329     ///
1330     /// # Examples
1331     ///
1332     /// ```
1333     /// use std::sync::atomic::{AtomicPtr, Ordering};
1334     ///
1335     /// let ptr = &mut 5;
1336     /// let some_ptr = AtomicPtr::new(ptr);
1337     ///
1338     /// let other_ptr = &mut 10;
1339     ///
1340     /// let value = some_ptr.compare_exchange(ptr, other_ptr,
1341     ///                                       Ordering::SeqCst, Ordering::Relaxed);
1342     /// ```
1343     #[inline]
1344     #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
1345     #[cfg(target_has_atomic = "ptr")]
1346     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1347     pub fn compare_exchange(
1348         &self,
1349         current: *mut T,
1350         new: *mut T,
1351         success: Ordering,
1352         failure: Ordering,
1353     ) -> Result<*mut T, *mut T> {
1354         // SAFETY: data races are prevented by atomic intrinsics.
1355         unsafe { atomic_compare_exchange(self.p.get(), current, new, success, failure) }
1356     }
1357
1358     /// Stores a value into the pointer if the current value is the same as the `current` value.
1359     ///
1360     /// Unlike [`AtomicPtr::compare_exchange`], this function is allowed to spuriously fail even when the
1361     /// comparison succeeds, which can result in more efficient code on some platforms. The
1362     /// return value is a result indicating whether the new value was written and containing the
1363     /// previous value.
1364     ///
1365     /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
1366     /// ordering of this operation. `success` describes the required ordering for the
1367     /// read-modify-write operation that takes place if the comparison with `current` succeeds.
1368     /// `failure` describes the required ordering for the load operation that takes place when
1369     /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
1370     /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
1371     /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
1372     ///
1373     /// **Note:** This method is only available on platforms that support atomic
1374     /// operations on pointers.
1375     ///
1376     /// # Examples
1377     ///
1378     /// ```
1379     /// use std::sync::atomic::{AtomicPtr, Ordering};
1380     ///
1381     /// let some_ptr = AtomicPtr::new(&mut 5);
1382     ///
1383     /// let new = &mut 10;
1384     /// let mut old = some_ptr.load(Ordering::Relaxed);
1385     /// loop {
1386     ///     match some_ptr.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
1387     ///         Ok(_) => break,
1388     ///         Err(x) => old = x,
1389     ///     }
1390     /// }
1391     /// ```
1392     #[inline]
1393     #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
1394     #[cfg(target_has_atomic = "ptr")]
1395     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1396     pub fn compare_exchange_weak(
1397         &self,
1398         current: *mut T,
1399         new: *mut T,
1400         success: Ordering,
1401         failure: Ordering,
1402     ) -> Result<*mut T, *mut T> {
1403         // SAFETY: This intrinsic is unsafe because it operates on a raw pointer
1404         // but we know for sure that the pointer is valid (we just got it from
1405         // an `UnsafeCell` that we have by reference) and the atomic operation
1406         // itself allows us to safely mutate the `UnsafeCell` contents.
1407         unsafe { atomic_compare_exchange_weak(self.p.get(), current, new, success, failure) }
1408     }
1409
1410     /// Fetches the value, and applies a function to it that returns an optional
1411     /// new value. Returns a `Result` of `Ok(previous_value)` if the function
1412     /// returned `Some(_)`, else `Err(previous_value)`.
1413     ///
1414     /// Note: This may call the function multiple times if the value has been
1415     /// changed from other threads in the meantime, as long as the function
1416     /// returns `Some(_)`, but the function will have been applied only once to
1417     /// the stored value.
1418     ///
1419     /// `fetch_update` takes two [`Ordering`] arguments to describe the memory
1420     /// ordering of this operation. The first describes the required ordering for
1421     /// when the operation finally succeeds while the second describes the
1422     /// required ordering for loads. These correspond to the success and failure
1423     /// orderings of [`AtomicPtr::compare_exchange`] respectively.
1424     ///
1425     /// Using [`Acquire`] as success ordering makes the store part of this
1426     /// operation [`Relaxed`], and using [`Release`] makes the final successful
1427     /// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`],
1428     /// [`Acquire`] or [`Relaxed`].
1429     ///
1430     /// **Note:** This method is only available on platforms that support atomic
1431     /// operations on pointers.
1432     ///
1433     /// # Considerations
1434     ///
1435     /// This method is not magic;  it is not provided by the hardware.
1436     /// It is implemented in terms of [`AtomicPtr::compare_exchange_weak`], and suffers from the same drawbacks.
1437     /// In particular, this method will not circumvent the [ABA Problem].
1438     ///
1439     /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1440     ///
1441     /// # Examples
1442     ///
1443     /// ```rust
1444     /// use std::sync::atomic::{AtomicPtr, Ordering};
1445     ///
1446     /// let ptr: *mut _ = &mut 5;
1447     /// let some_ptr = AtomicPtr::new(ptr);
1448     ///
1449     /// let new: *mut _ = &mut 10;
1450     /// assert_eq!(some_ptr.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(ptr));
1451     /// let result = some_ptr.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| {
1452     ///     if x == ptr {
1453     ///         Some(new)
1454     ///     } else {
1455     ///         None
1456     ///     }
1457     /// });
1458     /// assert_eq!(result, Ok(ptr));
1459     /// assert_eq!(some_ptr.load(Ordering::SeqCst), new);
1460     /// ```
1461     #[inline]
1462     #[stable(feature = "atomic_fetch_update", since = "1.53.0")]
1463     #[cfg(target_has_atomic = "ptr")]
1464     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1465     pub fn fetch_update<F>(
1466         &self,
1467         set_order: Ordering,
1468         fetch_order: Ordering,
1469         mut f: F,
1470     ) -> Result<*mut T, *mut T>
1471     where
1472         F: FnMut(*mut T) -> Option<*mut T>,
1473     {
1474         let mut prev = self.load(fetch_order);
1475         while let Some(next) = f(prev) {
1476             match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
1477                 x @ Ok(_) => return x,
1478                 Err(next_prev) => prev = next_prev,
1479             }
1480         }
1481         Err(prev)
1482     }
1483
1484     /// Offsets the pointer's address by adding `val` (in units of `T`),
1485     /// returning the previous pointer.
1486     ///
1487     /// This is equivalent to using [`wrapping_add`] to atomically perform the
1488     /// equivalent of `ptr = ptr.wrapping_add(val);`.
1489     ///
1490     /// This method operates in units of `T`, which means that it cannot be used
1491     /// to offset the pointer by an amount which is not a multiple of
1492     /// `size_of::<T>()`. This can sometimes be inconvenient, as you may want to
1493     /// work with a deliberately misaligned pointer. In such cases, you may use
1494     /// the [`fetch_byte_add`](Self::fetch_byte_add) method instead.
1495     ///
1496     /// `fetch_ptr_add` takes an [`Ordering`] argument which describes the
1497     /// memory ordering of this operation. All ordering modes are possible. Note
1498     /// that using [`Acquire`] makes the store part of this operation
1499     /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].
1500     ///
1501     /// **Note**: This method is only available on platforms that support atomic
1502     /// operations on [`AtomicPtr`].
1503     ///
1504     /// [`wrapping_add`]: pointer::wrapping_add
1505     ///
1506     /// # Examples
1507     ///
1508     /// ```
1509     /// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
1510     /// use core::sync::atomic::{AtomicPtr, Ordering};
1511     ///
1512     /// let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());
1513     /// assert_eq!(atom.fetch_ptr_add(1, Ordering::Relaxed).addr(), 0);
1514     /// // Note: units of `size_of::<i64>()`.
1515     /// assert_eq!(atom.load(Ordering::Relaxed).addr(), 8);
1516     /// ```
1517     #[inline]
1518     #[cfg(target_has_atomic = "ptr")]
1519     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
1520     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1521     pub fn fetch_ptr_add(&self, val: usize, order: Ordering) -> *mut T {
1522         self.fetch_byte_add(val.wrapping_mul(core::mem::size_of::<T>()), order)
1523     }
1524
1525     /// Offsets the pointer's address by subtracting `val` (in units of `T`),
1526     /// returning the previous pointer.
1527     ///
1528     /// This is equivalent to using [`wrapping_sub`] to atomically perform the
1529     /// equivalent of `ptr = ptr.wrapping_sub(val);`.
1530     ///
1531     /// This method operates in units of `T`, which means that it cannot be used
1532     /// to offset the pointer by an amount which is not a multiple of
1533     /// `size_of::<T>()`. This can sometimes be inconvenient, as you may want to
1534     /// work with a deliberately misaligned pointer. In such cases, you may use
1535     /// the [`fetch_byte_sub`](Self::fetch_byte_sub) method instead.
1536     ///
1537     /// `fetch_ptr_sub` takes an [`Ordering`] argument which describes the memory
1538     /// ordering of this operation. All ordering modes are possible. Note that
1539     /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
1540     /// and using [`Release`] makes the load part [`Relaxed`].
1541     ///
1542     /// **Note**: This method is only available on platforms that support atomic
1543     /// operations on [`AtomicPtr`].
1544     ///
1545     /// [`wrapping_sub`]: pointer::wrapping_sub
1546     ///
1547     /// # Examples
1548     ///
1549     /// ```
1550     /// #![feature(strict_provenance_atomic_ptr)]
1551     /// use core::sync::atomic::{AtomicPtr, Ordering};
1552     ///
1553     /// let array = [1i32, 2i32];
1554     /// let atom = AtomicPtr::new(array.as_ptr().wrapping_add(1) as *mut _);
1555     ///
1556     /// assert!(core::ptr::eq(
1557     ///     atom.fetch_ptr_sub(1, Ordering::Relaxed),
1558     ///     &array[1],
1559     /// ));
1560     /// assert!(core::ptr::eq(atom.load(Ordering::Relaxed), &array[0]));
1561     /// ```
1562     #[inline]
1563     #[cfg(target_has_atomic = "ptr")]
1564     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
1565     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1566     pub fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T {
1567         self.fetch_byte_sub(val.wrapping_mul(core::mem::size_of::<T>()), order)
1568     }
1569
1570     /// Offsets the pointer's address by adding `val` *bytes*, returning the
1571     /// previous pointer.
1572     ///
1573     /// This is equivalent to using [`wrapping_byte_add`] to atomically
1574     /// perform `ptr = ptr.wrapping_byte_add(val)`.
1575     ///
1576     /// `fetch_byte_add` takes an [`Ordering`] argument which describes the
1577     /// memory ordering of this operation. All ordering modes are possible. Note
1578     /// that using [`Acquire`] makes the store part of this operation
1579     /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].
1580     ///
1581     /// **Note**: This method is only available on platforms that support atomic
1582     /// operations on [`AtomicPtr`].
1583     ///
1584     /// [`wrapping_byte_add`]: pointer::wrapping_byte_add
1585     ///
1586     /// # Examples
1587     ///
1588     /// ```
1589     /// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
1590     /// use core::sync::atomic::{AtomicPtr, Ordering};
1591     ///
1592     /// let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());
1593     /// assert_eq!(atom.fetch_byte_add(1, Ordering::Relaxed).addr(), 0);
1594     /// // Note: in units of bytes, not `size_of::<i64>()`.
1595     /// assert_eq!(atom.load(Ordering::Relaxed).addr(), 1);
1596     /// ```
1597     #[inline]
1598     #[cfg(target_has_atomic = "ptr")]
1599     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
1600     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1601     pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T {
1602         // SAFETY: data races are prevented by atomic intrinsics.
1603         unsafe { atomic_add(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
1604     }
1605
1606     /// Offsets the pointer's address by subtracting `val` *bytes*, returning the
1607     /// previous pointer.
1608     ///
1609     /// This is equivalent to using [`wrapping_byte_sub`] to atomically
1610     /// perform `ptr = ptr.wrapping_byte_sub(val)`.
1611     ///
1612     /// `fetch_byte_sub` takes an [`Ordering`] argument which describes the
1613     /// memory ordering of this operation. All ordering modes are possible. Note
1614     /// that using [`Acquire`] makes the store part of this operation
1615     /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].
1616     ///
1617     /// **Note**: This method is only available on platforms that support atomic
1618     /// operations on [`AtomicPtr`].
1619     ///
1620     /// [`wrapping_byte_sub`]: pointer::wrapping_byte_sub
1621     ///
1622     /// # Examples
1623     ///
1624     /// ```
1625     /// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
1626     /// use core::sync::atomic::{AtomicPtr, Ordering};
1627     ///
1628     /// let atom = AtomicPtr::<i64>::new(core::ptr::invalid_mut(1));
1629     /// assert_eq!(atom.fetch_byte_sub(1, Ordering::Relaxed).addr(), 1);
1630     /// assert_eq!(atom.load(Ordering::Relaxed).addr(), 0);
1631     /// ```
1632     #[inline]
1633     #[cfg(target_has_atomic = "ptr")]
1634     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
1635     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1636     pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T {
1637         // SAFETY: data races are prevented by atomic intrinsics.
1638         unsafe { atomic_sub(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
1639     }
1640
1641     /// Performs a bitwise "or" operation on the address of the current pointer,
1642     /// and the argument `val`, and stores a pointer with provenance of the
1643     /// current pointer and the resulting address.
1644     ///
1645     /// This is equivalent to using [`map_addr`] to atomically perform
1646     /// `ptr = ptr.map_addr(|a| a | val)`. This can be used in tagged
1647     /// pointer schemes to atomically set tag bits.
1648     ///
1649     /// **Caveat**: This operation returns the previous value. To compute the
1650     /// stored value without losing provenance, you may use [`map_addr`]. For
1651     /// example: `a.fetch_or(val).map_addr(|a| a | val)`.
1652     ///
1653     /// `fetch_or` takes an [`Ordering`] argument which describes the memory
1654     /// ordering of this operation. All ordering modes are possible. Note that
1655     /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
1656     /// and using [`Release`] makes the load part [`Relaxed`].
1657     ///
1658     /// **Note**: This method is only available on platforms that support atomic
1659     /// operations on [`AtomicPtr`].
1660     ///
1661     /// This API and its claimed semantics are part of the Strict Provenance
1662     /// experiment, see the [module documentation for `ptr`][crate::ptr] for
1663     /// details.
1664     ///
1665     /// [`map_addr`]: pointer::map_addr
1666     ///
1667     /// # Examples
1668     ///
1669     /// ```
1670     /// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
1671     /// use core::sync::atomic::{AtomicPtr, Ordering};
1672     ///
1673     /// let pointer = &mut 3i64 as *mut i64;
1674     ///
1675     /// let atom = AtomicPtr::<i64>::new(pointer);
1676     /// // Tag the bottom bit of the pointer.
1677     /// assert_eq!(atom.fetch_or(1, Ordering::Relaxed).addr() & 1, 0);
1678     /// // Extract and untag.
1679     /// let tagged = atom.load(Ordering::Relaxed);
1680     /// assert_eq!(tagged.addr() & 1, 1);
1681     /// assert_eq!(tagged.map_addr(|p| p & !1), pointer);
1682     /// ```
1683     #[inline]
1684     #[cfg(target_has_atomic = "ptr")]
1685     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
1686     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1687     pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T {
1688         // SAFETY: data races are prevented by atomic intrinsics.
1689         unsafe { atomic_or(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
1690     }
1691
1692     /// Performs a bitwise "and" operation on the address of the current
1693     /// pointer, and the argument `val`, and stores a pointer with provenance of
1694     /// the current pointer and the resulting address.
1695     ///
1696     /// This is equivalent to using [`map_addr`] to atomically perform
1697     /// `ptr = ptr.map_addr(|a| a & val)`. This can be used in tagged
1698     /// pointer schemes to atomically unset tag bits.
1699     ///
1700     /// **Caveat**: This operation returns the previous value. To compute the
1701     /// stored value without losing provenance, you may use [`map_addr`]. For
1702     /// example: `a.fetch_and(val).map_addr(|a| a & val)`.
1703     ///
1704     /// `fetch_and` takes an [`Ordering`] argument which describes the memory
1705     /// ordering of this operation. All ordering modes are possible. Note that
1706     /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
1707     /// and using [`Release`] makes the load part [`Relaxed`].
1708     ///
1709     /// **Note**: This method is only available on platforms that support atomic
1710     /// operations on [`AtomicPtr`].
1711     ///
1712     /// This API and its claimed semantics are part of the Strict Provenance
1713     /// experiment, see the [module documentation for `ptr`][crate::ptr] for
1714     /// details.
1715     ///
1716     /// [`map_addr`]: pointer::map_addr
1717     ///
1718     /// # Examples
1719     ///
1720     /// ```
1721     /// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
1722     /// use core::sync::atomic::{AtomicPtr, Ordering};
1723     ///
1724     /// let pointer = &mut 3i64 as *mut i64;
1725     /// // A tagged pointer
1726     /// let atom = AtomicPtr::<i64>::new(pointer.map_addr(|a| a | 1));
1727     /// assert_eq!(atom.fetch_or(1, Ordering::Relaxed).addr() & 1, 1);
1728     /// // Untag, and extract the previously tagged pointer.
1729     /// let untagged = atom.fetch_and(!1, Ordering::Relaxed)
1730     ///     .map_addr(|a| a & !1);
1731     /// assert_eq!(untagged, pointer);
1732     /// ```
1733     #[inline]
1734     #[cfg(target_has_atomic = "ptr")]
1735     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
1736     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1737     pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T {
1738         // SAFETY: data races are prevented by atomic intrinsics.
1739         unsafe { atomic_and(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
1740     }
1741
1742     /// Performs a bitwise "xor" operation on the address of the current
1743     /// pointer, and the argument `val`, and stores a pointer with provenance of
1744     /// the current pointer and the resulting address.
1745     ///
1746     /// This is equivalent to using [`map_addr`] to atomically perform
1747     /// `ptr = ptr.map_addr(|a| a ^ val)`. This can be used in tagged
1748     /// pointer schemes to atomically toggle tag bits.
1749     ///
1750     /// **Caveat**: This operation returns the previous value. To compute the
1751     /// stored value without losing provenance, you may use [`map_addr`]. For
1752     /// example: `a.fetch_xor(val).map_addr(|a| a ^ val)`.
1753     ///
1754     /// `fetch_xor` takes an [`Ordering`] argument which describes the memory
1755     /// ordering of this operation. All ordering modes are possible. Note that
1756     /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
1757     /// and using [`Release`] makes the load part [`Relaxed`].
1758     ///
1759     /// **Note**: This method is only available on platforms that support atomic
1760     /// operations on [`AtomicPtr`].
1761     ///
1762     /// This API and its claimed semantics are part of the Strict Provenance
1763     /// experiment, see the [module documentation for `ptr`][crate::ptr] for
1764     /// details.
1765     ///
1766     /// [`map_addr`]: pointer::map_addr
1767     ///
1768     /// # Examples
1769     ///
1770     /// ```
1771     /// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
1772     /// use core::sync::atomic::{AtomicPtr, Ordering};
1773     ///
1774     /// let pointer = &mut 3i64 as *mut i64;
1775     /// let atom = AtomicPtr::<i64>::new(pointer);
1776     ///
1777     /// // Toggle a tag bit on the pointer.
1778     /// atom.fetch_xor(1, Ordering::Relaxed);
1779     /// assert_eq!(atom.load(Ordering::Relaxed).addr() & 1, 1);
1780     /// ```
1781     #[inline]
1782     #[cfg(target_has_atomic = "ptr")]
1783     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
1784     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1785     pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T {
1786         // SAFETY: data races are prevented by atomic intrinsics.
1787         unsafe { atomic_xor(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
1788     }
1789
1790     /// Returns a mutable pointer to the underlying pointer.
1791     ///
1792     /// Doing non-atomic reads and writes on the resulting integer can be a data race.
1793     /// This method is mostly useful for FFI, where the function signature may use
1794     /// `*mut *mut T` instead of `&AtomicPtr<T>`.
1795     ///
1796     /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
1797     /// atomic types work with interior mutability. All modifications of an atomic change the value
1798     /// through a shared reference, and can do so safely as long as they use atomic operations. Any
1799     /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the same
1800     /// restriction: operations on it must be atomic.
1801     ///
1802     /// # Examples
1803     ///
1804     /// ```ignore (extern-declaration)
1805     /// #![feature(atomic_mut_ptr)]
1806     //// use std::sync::atomic::AtomicPtr;
1807     ///
1808     /// extern "C" {
1809     ///     fn my_atomic_op(arg: *mut *mut u32);
1810     /// }
1811     ///
1812     /// let mut value = 17;
1813     /// let atomic = AtomicPtr::new(&mut value);
1814     ///
1815     /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
1816     /// unsafe {
1817     ///     my_atomic_op(atomic.as_mut_ptr());
1818     /// }
1819     /// ```
1820     #[inline]
1821     #[unstable(feature = "atomic_mut_ptr", reason = "recently added", issue = "66893")]
1822     pub fn as_mut_ptr(&self) -> *mut *mut T {
1823         self.p.get()
1824     }
1825 }
1826
1827 #[cfg(target_has_atomic_load_store = "8")]
1828 #[stable(feature = "atomic_bool_from", since = "1.24.0")]
1829 #[rustc_const_unstable(feature = "const_convert", issue = "88674")]
1830 impl const From<bool> for AtomicBool {
1831     /// Converts a `bool` into an `AtomicBool`.
1832     ///
1833     /// # Examples
1834     ///
1835     /// ```
1836     /// use std::sync::atomic::AtomicBool;
1837     /// let atomic_bool = AtomicBool::from(true);
1838     /// assert_eq!(format!("{atomic_bool:?}"), "true")
1839     /// ```
1840     #[inline]
1841     fn from(b: bool) -> Self {
1842         Self::new(b)
1843     }
1844 }
1845
1846 #[cfg(target_has_atomic_load_store = "ptr")]
1847 #[stable(feature = "atomic_from", since = "1.23.0")]
1848 #[rustc_const_unstable(feature = "const_convert", issue = "88674")]
1849 impl<T> const From<*mut T> for AtomicPtr<T> {
1850     /// Converts a `*mut T` into an `AtomicPtr<T>`.
1851     #[inline]
1852     fn from(p: *mut T) -> Self {
1853         Self::new(p)
1854     }
1855 }
1856
1857 #[allow(unused_macros)] // This macro ends up being unused on some architectures.
1858 macro_rules! if_not_8_bit {
1859     (u8, $($tt:tt)*) => { "" };
1860     (i8, $($tt:tt)*) => { "" };
1861     ($_:ident, $($tt:tt)*) => { $($tt)* };
1862 }
1863
1864 #[cfg(target_has_atomic_load_store = "8")]
1865 macro_rules! atomic_int {
1866     ($cfg_cas:meta,
1867      $cfg_align:meta,
1868      $stable:meta,
1869      $stable_cxchg:meta,
1870      $stable_debug:meta,
1871      $stable_access:meta,
1872      $stable_from:meta,
1873      $stable_nand:meta,
1874      $const_stable:meta,
1875      $stable_init_const:meta,
1876      $diagnostic_item:meta,
1877      $s_int_type:literal,
1878      $extra_feature:expr,
1879      $min_fn:ident, $max_fn:ident,
1880      $align:expr,
1881      $atomic_new:expr,
1882      $int_type:ident $atomic_type:ident $atomic_init:ident) => {
1883         /// An integer type which can be safely shared between threads.
1884         ///
1885         /// This type has the same in-memory representation as the underlying
1886         /// integer type, [`
1887         #[doc = $s_int_type]
1888         /// `]. For more about the differences between atomic types and
1889         /// non-atomic types as well as information about the portability of
1890         /// this type, please see the [module-level documentation].
1891         ///
1892         /// **Note:** This type is only available on platforms that support
1893         /// atomic loads and stores of [`
1894         #[doc = $s_int_type]
1895         /// `].
1896         ///
1897         /// [module-level documentation]: crate::sync::atomic
1898         #[$stable]
1899         #[$diagnostic_item]
1900         #[repr(C, align($align))]
1901         pub struct $atomic_type {
1902             v: UnsafeCell<$int_type>,
1903         }
1904
1905         /// An atomic integer initialized to `0`.
1906         #[$stable_init_const]
1907         #[deprecated(
1908             since = "1.34.0",
1909             note = "the `new` function is now preferred",
1910             suggestion = $atomic_new,
1911         )]
1912         pub const $atomic_init: $atomic_type = $atomic_type::new(0);
1913
1914         #[$stable]
1915         #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
1916         impl const Default for $atomic_type {
1917             #[inline]
1918             fn default() -> Self {
1919                 Self::new(Default::default())
1920             }
1921         }
1922
1923         #[$stable_from]
1924         #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
1925         impl const From<$int_type> for $atomic_type {
1926             #[doc = concat!("Converts an `", stringify!($int_type), "` into an `", stringify!($atomic_type), "`.")]
1927             #[inline]
1928             fn from(v: $int_type) -> Self { Self::new(v) }
1929         }
1930
1931         #[$stable_debug]
1932         impl fmt::Debug for $atomic_type {
1933             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1934                 fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
1935             }
1936         }
1937
1938         // Send is implicitly implemented.
1939         #[$stable]
1940         unsafe impl Sync for $atomic_type {}
1941
1942         impl $atomic_type {
1943             /// Creates a new atomic integer.
1944             ///
1945             /// # Examples
1946             ///
1947             /// ```
1948             #[doc = concat!($extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";")]
1949             ///
1950             #[doc = concat!("let atomic_forty_two = ", stringify!($atomic_type), "::new(42);")]
1951             /// ```
1952             #[inline]
1953             #[$stable]
1954             #[$const_stable]
1955             #[must_use]
1956             pub const fn new(v: $int_type) -> Self {
1957                 Self {v: UnsafeCell::new(v)}
1958             }
1959
1960             /// Returns a mutable reference to the underlying integer.
1961             ///
1962             /// This is safe because the mutable reference guarantees that no other threads are
1963             /// concurrently accessing the atomic data.
1964             ///
1965             /// # Examples
1966             ///
1967             /// ```
1968             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
1969             ///
1970             #[doc = concat!("let mut some_var = ", stringify!($atomic_type), "::new(10);")]
1971             /// assert_eq!(*some_var.get_mut(), 10);
1972             /// *some_var.get_mut() = 5;
1973             /// assert_eq!(some_var.load(Ordering::SeqCst), 5);
1974             /// ```
1975             #[inline]
1976             #[$stable_access]
1977             pub fn get_mut(&mut self) -> &mut $int_type {
1978                 self.v.get_mut()
1979             }
1980
1981             #[doc = concat!("Get atomic access to a `&mut ", stringify!($int_type), "`.")]
1982             ///
1983             #[doc = if_not_8_bit! {
1984                 $int_type,
1985                 concat!(
1986                     "**Note:** This function is only available on targets where `",
1987                     stringify!($int_type), "` has an alignment of ", $align, " bytes."
1988                 )
1989             }]
1990             ///
1991             /// # Examples
1992             ///
1993             /// ```
1994             /// #![feature(atomic_from_mut)]
1995             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
1996             ///
1997             /// let mut some_int = 123;
1998             #[doc = concat!("let a = ", stringify!($atomic_type), "::from_mut(&mut some_int);")]
1999             /// a.store(100, Ordering::Relaxed);
2000             /// assert_eq!(some_int, 100);
2001             /// ```
2002             ///
2003             #[inline]
2004             #[$cfg_align]
2005             #[unstable(feature = "atomic_from_mut", issue = "76314")]
2006             pub fn from_mut(v: &mut $int_type) -> &mut Self {
2007                 use crate::mem::align_of;
2008                 let [] = [(); align_of::<Self>() - align_of::<$int_type>()];
2009                 // SAFETY:
2010                 //  - the mutable reference guarantees unique ownership.
2011                 //  - the alignment of `$int_type` and `Self` is the
2012                 //    same, as promised by $cfg_align and verified above.
2013                 unsafe { &mut *(v as *mut $int_type as *mut Self) }
2014             }
2015
2016             #[doc = concat!("Get non-atomic access to a `&mut [", stringify!($atomic_type), "]` slice")]
2017             ///
2018             /// This is safe because the mutable reference guarantees that no other threads are
2019             /// concurrently accessing the atomic data.
2020             ///
2021             /// # Examples
2022             ///
2023             /// ```
2024             /// #![feature(atomic_from_mut, inline_const)]
2025             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2026             ///
2027             #[doc = concat!("let mut some_ints = [const { ", stringify!($atomic_type), "::new(0) }; 10];")]
2028             ///
2029             #[doc = concat!("let view: &mut [", stringify!($int_type), "] = ", stringify!($atomic_type), "::get_mut_slice(&mut some_ints);")]
2030             /// assert_eq!(view, [0; 10]);
2031             /// view
2032             ///     .iter_mut()
2033             ///     .enumerate()
2034             ///     .for_each(|(idx, int)| *int = idx as _);
2035             ///
2036             /// std::thread::scope(|s| {
2037             ///     some_ints
2038             ///         .iter()
2039             ///         .enumerate()
2040             ///         .for_each(|(idx, int)| {
2041             ///             s.spawn(move || assert_eq!(int.load(Ordering::Relaxed), idx as _));
2042             ///         })
2043             /// });
2044             /// ```
2045             #[inline]
2046             #[unstable(feature = "atomic_from_mut", issue = "76314")]
2047             pub fn get_mut_slice(this: &mut [Self]) -> &mut [$int_type] {
2048                 // SAFETY: the mutable reference guarantees unique ownership.
2049                 unsafe { &mut *(this as *mut [Self] as *mut [$int_type]) }
2050             }
2051
2052             #[doc = concat!("Get atomic access to a `&mut [", stringify!($int_type), "]` slice.")]
2053             ///
2054             /// # Examples
2055             ///
2056             /// ```
2057             /// #![feature(atomic_from_mut)]
2058             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2059             ///
2060             /// let mut some_ints = [0; 10];
2061             #[doc = concat!("let a = &*", stringify!($atomic_type), "::from_mut_slice(&mut some_ints);")]
2062             /// std::thread::scope(|s| {
2063             ///     for i in 0..a.len() {
2064             ///         s.spawn(move || a[i].store(i as _, Ordering::Relaxed));
2065             ///     }
2066             /// });
2067             /// for (i, n) in some_ints.into_iter().enumerate() {
2068             ///     assert_eq!(i, n as usize);
2069             /// }
2070             /// ```
2071             #[inline]
2072             #[$cfg_align]
2073             #[unstable(feature = "atomic_from_mut", issue = "76314")]
2074             pub fn from_mut_slice(v: &mut [$int_type]) -> &mut [Self] {
2075                 use crate::mem::align_of;
2076                 let [] = [(); align_of::<Self>() - align_of::<$int_type>()];
2077                 // SAFETY:
2078                 //  - the mutable reference guarantees unique ownership.
2079                 //  - the alignment of `$int_type` and `Self` is the
2080                 //    same, as promised by $cfg_align and verified above.
2081                 unsafe { &mut *(v as *mut [$int_type] as *mut [Self]) }
2082             }
2083
2084             /// Consumes the atomic and returns the contained value.
2085             ///
2086             /// This is safe because passing `self` by value guarantees that no other threads are
2087             /// concurrently accessing the atomic data.
2088             ///
2089             /// # Examples
2090             ///
2091             /// ```
2092             #[doc = concat!($extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";")]
2093             ///
2094             #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
2095             /// assert_eq!(some_var.into_inner(), 5);
2096             /// ```
2097             #[inline]
2098             #[$stable_access]
2099             #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")]
2100             pub const fn into_inner(self) -> $int_type {
2101                 self.v.into_inner()
2102             }
2103
2104             /// Loads a value from the atomic integer.
2105             ///
2106             /// `load` takes an [`Ordering`] argument which describes the memory ordering of this operation.
2107             /// Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
2108             ///
2109             /// # Panics
2110             ///
2111             /// Panics if `order` is [`Release`] or [`AcqRel`].
2112             ///
2113             /// # Examples
2114             ///
2115             /// ```
2116             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2117             ///
2118             #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
2119             ///
2120             /// assert_eq!(some_var.load(Ordering::Relaxed), 5);
2121             /// ```
2122             #[inline]
2123             #[$stable]
2124             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2125             pub fn load(&self, order: Ordering) -> $int_type {
2126                 // SAFETY: data races are prevented by atomic intrinsics.
2127                 unsafe { atomic_load(self.v.get(), order) }
2128             }
2129
2130             /// Stores a value into the atomic integer.
2131             ///
2132             /// `store` takes an [`Ordering`] argument which describes the memory ordering of this operation.
2133             ///  Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
2134             ///
2135             /// # Panics
2136             ///
2137             /// Panics if `order` is [`Acquire`] or [`AcqRel`].
2138             ///
2139             /// # Examples
2140             ///
2141             /// ```
2142             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2143             ///
2144             #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
2145             ///
2146             /// some_var.store(10, Ordering::Relaxed);
2147             /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
2148             /// ```
2149             #[inline]
2150             #[$stable]
2151             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2152             pub fn store(&self, val: $int_type, order: Ordering) {
2153                 // SAFETY: data races are prevented by atomic intrinsics.
2154                 unsafe { atomic_store(self.v.get(), val, order); }
2155             }
2156
2157             /// Stores a value into the atomic integer, returning the previous value.
2158             ///
2159             /// `swap` takes an [`Ordering`] argument which describes the memory ordering
2160             /// of this operation. All ordering modes are possible. Note that using
2161             /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2162             /// using [`Release`] makes the load part [`Relaxed`].
2163             ///
2164             /// **Note**: This method is only available on platforms that support atomic operations on
2165             #[doc = concat!("[`", $s_int_type, "`].")]
2166             ///
2167             /// # Examples
2168             ///
2169             /// ```
2170             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2171             ///
2172             #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
2173             ///
2174             /// assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
2175             /// ```
2176             #[inline]
2177             #[$stable]
2178             #[$cfg_cas]
2179             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2180             pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
2181                 // SAFETY: data races are prevented by atomic intrinsics.
2182                 unsafe { atomic_swap(self.v.get(), val, order) }
2183             }
2184
2185             /// Stores a value into the atomic integer if the current value is the same as
2186             /// the `current` value.
2187             ///
2188             /// The return value is always the previous value. If it is equal to `current`, then the
2189             /// value was updated.
2190             ///
2191             /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
2192             /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
2193             /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
2194             /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
2195             /// happens, and using [`Release`] makes the load part [`Relaxed`].
2196             ///
2197             /// **Note**: This method is only available on platforms that support atomic operations on
2198             #[doc = concat!("[`", $s_int_type, "`].")]
2199             ///
2200             /// # Migrating to `compare_exchange` and `compare_exchange_weak`
2201             ///
2202             /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
2203             /// memory orderings:
2204             ///
2205             /// Original | Success | Failure
2206             /// -------- | ------- | -------
2207             /// Relaxed  | Relaxed | Relaxed
2208             /// Acquire  | Acquire | Acquire
2209             /// Release  | Release | Relaxed
2210             /// AcqRel   | AcqRel  | Acquire
2211             /// SeqCst   | SeqCst  | SeqCst
2212             ///
2213             /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
2214             /// which allows the compiler to generate better assembly code when the compare and swap
2215             /// is used in a loop.
2216             ///
2217             /// # Examples
2218             ///
2219             /// ```
2220             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2221             ///
2222             #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
2223             ///
2224             /// assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5);
2225             /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
2226             ///
2227             /// assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10);
2228             /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
2229             /// ```
2230             #[inline]
2231             #[$stable]
2232             #[deprecated(
2233                 since = "1.50.0",
2234                 note = "Use `compare_exchange` or `compare_exchange_weak` instead")
2235             ]
2236             #[$cfg_cas]
2237             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2238             pub fn compare_and_swap(&self,
2239                                     current: $int_type,
2240                                     new: $int_type,
2241                                     order: Ordering) -> $int_type {
2242                 match self.compare_exchange(current,
2243                                             new,
2244                                             order,
2245                                             strongest_failure_ordering(order)) {
2246                     Ok(x) => x,
2247                     Err(x) => x,
2248                 }
2249             }
2250
2251             /// Stores a value into the atomic integer if the current value is the same as
2252             /// the `current` value.
2253             ///
2254             /// The return value is a result indicating whether the new value was written and
2255             /// containing the previous value. On success this value is guaranteed to be equal to
2256             /// `current`.
2257             ///
2258             /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
2259             /// ordering of this operation. `success` describes the required ordering for the
2260             /// read-modify-write operation that takes place if the comparison with `current` succeeds.
2261             /// `failure` describes the required ordering for the load operation that takes place when
2262             /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
2263             /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
2264             /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
2265             ///
2266             /// **Note**: This method is only available on platforms that support atomic operations on
2267             #[doc = concat!("[`", $s_int_type, "`].")]
2268             ///
2269             /// # Examples
2270             ///
2271             /// ```
2272             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2273             ///
2274             #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
2275             ///
2276             /// assert_eq!(some_var.compare_exchange(5, 10,
2277             ///                                      Ordering::Acquire,
2278             ///                                      Ordering::Relaxed),
2279             ///            Ok(5));
2280             /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
2281             ///
2282             /// assert_eq!(some_var.compare_exchange(6, 12,
2283             ///                                      Ordering::SeqCst,
2284             ///                                      Ordering::Acquire),
2285             ///            Err(10));
2286             /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
2287             /// ```
2288             #[inline]
2289             #[$stable_cxchg]
2290             #[$cfg_cas]
2291             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2292             pub fn compare_exchange(&self,
2293                                     current: $int_type,
2294                                     new: $int_type,
2295                                     success: Ordering,
2296                                     failure: Ordering) -> Result<$int_type, $int_type> {
2297                 // SAFETY: data races are prevented by atomic intrinsics.
2298                 unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) }
2299             }
2300
2301             /// Stores a value into the atomic integer if the current value is the same as
2302             /// the `current` value.
2303             ///
2304             #[doc = concat!("Unlike [`", stringify!($atomic_type), "::compare_exchange`],")]
2305             /// this function is allowed to spuriously fail even
2306             /// when the comparison succeeds, which can result in more efficient code on some
2307             /// platforms. The return value is a result indicating whether the new value was
2308             /// written and containing the previous value.
2309             ///
2310             /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
2311             /// ordering of this operation. `success` describes the required ordering for the
2312             /// read-modify-write operation that takes place if the comparison with `current` succeeds.
2313             /// `failure` describes the required ordering for the load operation that takes place when
2314             /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
2315             /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
2316             /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
2317             ///
2318             /// **Note**: This method is only available on platforms that support atomic operations on
2319             #[doc = concat!("[`", $s_int_type, "`].")]
2320             ///
2321             /// # Examples
2322             ///
2323             /// ```
2324             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2325             ///
2326             #[doc = concat!("let val = ", stringify!($atomic_type), "::new(4);")]
2327             ///
2328             /// let mut old = val.load(Ordering::Relaxed);
2329             /// loop {
2330             ///     let new = old * 2;
2331             ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
2332             ///         Ok(_) => break,
2333             ///         Err(x) => old = x,
2334             ///     }
2335             /// }
2336             /// ```
2337             #[inline]
2338             #[$stable_cxchg]
2339             #[$cfg_cas]
2340             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2341             pub fn compare_exchange_weak(&self,
2342                                          current: $int_type,
2343                                          new: $int_type,
2344                                          success: Ordering,
2345                                          failure: Ordering) -> Result<$int_type, $int_type> {
2346                 // SAFETY: data races are prevented by atomic intrinsics.
2347                 unsafe {
2348                     atomic_compare_exchange_weak(self.v.get(), current, new, success, failure)
2349                 }
2350             }
2351
2352             /// Adds to the current value, returning the previous value.
2353             ///
2354             /// This operation wraps around on overflow.
2355             ///
2356             /// `fetch_add` takes an [`Ordering`] argument which describes the memory ordering
2357             /// of this operation. All ordering modes are possible. Note that using
2358             /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2359             /// using [`Release`] makes the load part [`Relaxed`].
2360             ///
2361             /// **Note**: This method is only available on platforms that support atomic operations on
2362             #[doc = concat!("[`", $s_int_type, "`].")]
2363             ///
2364             /// # Examples
2365             ///
2366             /// ```
2367             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2368             ///
2369             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0);")]
2370             /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
2371             /// assert_eq!(foo.load(Ordering::SeqCst), 10);
2372             /// ```
2373             #[inline]
2374             #[$stable]
2375             #[$cfg_cas]
2376             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2377             pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
2378                 // SAFETY: data races are prevented by atomic intrinsics.
2379                 unsafe { atomic_add(self.v.get(), val, order) }
2380             }
2381
2382             /// Subtracts from the current value, returning the previous value.
2383             ///
2384             /// This operation wraps around on overflow.
2385             ///
2386             /// `fetch_sub` takes an [`Ordering`] argument which describes the memory ordering
2387             /// of this operation. All ordering modes are possible. Note that using
2388             /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2389             /// using [`Release`] makes the load part [`Relaxed`].
2390             ///
2391             /// **Note**: This method is only available on platforms that support atomic operations on
2392             #[doc = concat!("[`", $s_int_type, "`].")]
2393             ///
2394             /// # Examples
2395             ///
2396             /// ```
2397             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2398             ///
2399             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(20);")]
2400             /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);
2401             /// assert_eq!(foo.load(Ordering::SeqCst), 10);
2402             /// ```
2403             #[inline]
2404             #[$stable]
2405             #[$cfg_cas]
2406             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2407             pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
2408                 // SAFETY: data races are prevented by atomic intrinsics.
2409                 unsafe { atomic_sub(self.v.get(), val, order) }
2410             }
2411
2412             /// Bitwise "and" with the current value.
2413             ///
2414             /// Performs a bitwise "and" operation on the current value and the argument `val`, and
2415             /// sets the new value to the result.
2416             ///
2417             /// Returns the previous value.
2418             ///
2419             /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
2420             /// of this operation. All ordering modes are possible. Note that using
2421             /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2422             /// using [`Release`] makes the load part [`Relaxed`].
2423             ///
2424             /// **Note**: This method is only available on platforms that support atomic operations on
2425             #[doc = concat!("[`", $s_int_type, "`].")]
2426             ///
2427             /// # Examples
2428             ///
2429             /// ```
2430             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2431             ///
2432             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0b101101);")]
2433             /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
2434             /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
2435             /// ```
2436             #[inline]
2437             #[$stable]
2438             #[$cfg_cas]
2439             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2440             pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
2441                 // SAFETY: data races are prevented by atomic intrinsics.
2442                 unsafe { atomic_and(self.v.get(), val, order) }
2443             }
2444
2445             /// Bitwise "nand" with the current value.
2446             ///
2447             /// Performs a bitwise "nand" operation on the current value and the argument `val`, and
2448             /// sets the new value to the result.
2449             ///
2450             /// Returns the previous value.
2451             ///
2452             /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
2453             /// of this operation. All ordering modes are possible. Note that using
2454             /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2455             /// using [`Release`] makes the load part [`Relaxed`].
2456             ///
2457             /// **Note**: This method is only available on platforms that support atomic operations on
2458             #[doc = concat!("[`", $s_int_type, "`].")]
2459             ///
2460             /// # Examples
2461             ///
2462             /// ```
2463             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2464             ///
2465             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0x13);")]
2466             /// assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);
2467             /// assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
2468             /// ```
2469             #[inline]
2470             #[$stable_nand]
2471             #[$cfg_cas]
2472             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2473             pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
2474                 // SAFETY: data races are prevented by atomic intrinsics.
2475                 unsafe { atomic_nand(self.v.get(), val, order) }
2476             }
2477
2478             /// Bitwise "or" with the current value.
2479             ///
2480             /// Performs a bitwise "or" operation on the current value and the argument `val`, and
2481             /// sets the new value to the result.
2482             ///
2483             /// Returns the previous value.
2484             ///
2485             /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
2486             /// of this operation. All ordering modes are possible. Note that using
2487             /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2488             /// using [`Release`] makes the load part [`Relaxed`].
2489             ///
2490             /// **Note**: This method is only available on platforms that support atomic operations on
2491             #[doc = concat!("[`", $s_int_type, "`].")]
2492             ///
2493             /// # Examples
2494             ///
2495             /// ```
2496             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2497             ///
2498             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0b101101);")]
2499             /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
2500             /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
2501             /// ```
2502             #[inline]
2503             #[$stable]
2504             #[$cfg_cas]
2505             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2506             pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
2507                 // SAFETY: data races are prevented by atomic intrinsics.
2508                 unsafe { atomic_or(self.v.get(), val, order) }
2509             }
2510
2511             /// Bitwise "xor" with the current value.
2512             ///
2513             /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
2514             /// sets the new value to the result.
2515             ///
2516             /// Returns the previous value.
2517             ///
2518             /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
2519             /// of this operation. All ordering modes are possible. Note that using
2520             /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2521             /// using [`Release`] makes the load part [`Relaxed`].
2522             ///
2523             /// **Note**: This method is only available on platforms that support atomic operations on
2524             #[doc = concat!("[`", $s_int_type, "`].")]
2525             ///
2526             /// # Examples
2527             ///
2528             /// ```
2529             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2530             ///
2531             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0b101101);")]
2532             /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
2533             /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
2534             /// ```
2535             #[inline]
2536             #[$stable]
2537             #[$cfg_cas]
2538             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2539             pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
2540                 // SAFETY: data races are prevented by atomic intrinsics.
2541                 unsafe { atomic_xor(self.v.get(), val, order) }
2542             }
2543
2544             /// Fetches the value, and applies a function to it that returns an optional
2545             /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else
2546             /// `Err(previous_value)`.
2547             ///
2548             /// Note: This may call the function multiple times if the value has been changed from other threads in
2549             /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied
2550             /// only once to the stored value.
2551             ///
2552             /// `fetch_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
2553             /// The first describes the required ordering for when the operation finally succeeds while the second
2554             /// describes the required ordering for loads. These correspond to the success and failure orderings of
2555             #[doc = concat!("[`", stringify!($atomic_type), "::compare_exchange`]")]
2556             /// respectively.
2557             ///
2558             /// Using [`Acquire`] as success ordering makes the store part
2559             /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
2560             /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
2561             ///
2562             /// **Note**: This method is only available on platforms that support atomic operations on
2563             #[doc = concat!("[`", $s_int_type, "`].")]
2564             ///
2565             /// # Considerations
2566             ///
2567             /// This method is not magic;  it is not provided by the hardware.
2568             /// It is implemented in terms of
2569             #[doc = concat!("[`", stringify!($atomic_type), "::compare_exchange_weak`],")]
2570             /// and suffers from the same drawbacks.
2571             /// In particular, this method will not circumvent the [ABA Problem].
2572             ///
2573             /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
2574             ///
2575             /// # Examples
2576             ///
2577             /// ```rust
2578             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2579             ///
2580             #[doc = concat!("let x = ", stringify!($atomic_type), "::new(7);")]
2581             /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));
2582             /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7));
2583             /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8));
2584             /// assert_eq!(x.load(Ordering::SeqCst), 9);
2585             /// ```
2586             #[inline]
2587             #[stable(feature = "no_more_cas", since = "1.45.0")]
2588             #[$cfg_cas]
2589             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2590             pub fn fetch_update<F>(&self,
2591                                    set_order: Ordering,
2592                                    fetch_order: Ordering,
2593                                    mut f: F) -> Result<$int_type, $int_type>
2594             where F: FnMut($int_type) -> Option<$int_type> {
2595                 let mut prev = self.load(fetch_order);
2596                 while let Some(next) = f(prev) {
2597                     match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
2598                         x @ Ok(_) => return x,
2599                         Err(next_prev) => prev = next_prev
2600                     }
2601                 }
2602                 Err(prev)
2603             }
2604
2605             /// Maximum with the current value.
2606             ///
2607             /// Finds the maximum of the current value and the argument `val`, and
2608             /// sets the new value to the result.
2609             ///
2610             /// Returns the previous value.
2611             ///
2612             /// `fetch_max` takes an [`Ordering`] argument which describes the memory ordering
2613             /// of this operation. All ordering modes are possible. Note that using
2614             /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2615             /// using [`Release`] makes the load part [`Relaxed`].
2616             ///
2617             /// **Note**: This method is only available on platforms that support atomic operations on
2618             #[doc = concat!("[`", $s_int_type, "`].")]
2619             ///
2620             /// # Examples
2621             ///
2622             /// ```
2623             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2624             ///
2625             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
2626             /// assert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23);
2627             /// assert_eq!(foo.load(Ordering::SeqCst), 42);
2628             /// ```
2629             ///
2630             /// If you want to obtain the maximum value in one step, you can use the following:
2631             ///
2632             /// ```
2633             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2634             ///
2635             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
2636             /// let bar = 42;
2637             /// let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar);
2638             /// assert!(max_foo == 42);
2639             /// ```
2640             #[inline]
2641             #[stable(feature = "atomic_min_max", since = "1.45.0")]
2642             #[$cfg_cas]
2643             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2644             pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {
2645                 // SAFETY: data races are prevented by atomic intrinsics.
2646                 unsafe { $max_fn(self.v.get(), val, order) }
2647             }
2648
2649             /// Minimum with the current value.
2650             ///
2651             /// Finds the minimum of the current value and the argument `val`, and
2652             /// sets the new value to the result.
2653             ///
2654             /// Returns the previous value.
2655             ///
2656             /// `fetch_min` takes an [`Ordering`] argument which describes the memory ordering
2657             /// of this operation. All ordering modes are possible. Note that using
2658             /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2659             /// using [`Release`] makes the load part [`Relaxed`].
2660             ///
2661             /// **Note**: This method is only available on platforms that support atomic operations on
2662             #[doc = concat!("[`", $s_int_type, "`].")]
2663             ///
2664             /// # Examples
2665             ///
2666             /// ```
2667             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2668             ///
2669             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
2670             /// assert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23);
2671             /// assert_eq!(foo.load(Ordering::Relaxed), 23);
2672             /// assert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23);
2673             /// assert_eq!(foo.load(Ordering::Relaxed), 22);
2674             /// ```
2675             ///
2676             /// If you want to obtain the minimum value in one step, you can use the following:
2677             ///
2678             /// ```
2679             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2680             ///
2681             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
2682             /// let bar = 12;
2683             /// let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar);
2684             /// assert_eq!(min_foo, 12);
2685             /// ```
2686             #[inline]
2687             #[stable(feature = "atomic_min_max", since = "1.45.0")]
2688             #[$cfg_cas]
2689             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2690             pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {
2691                 // SAFETY: data races are prevented by atomic intrinsics.
2692                 unsafe { $min_fn(self.v.get(), val, order) }
2693             }
2694
2695             /// Returns a mutable pointer to the underlying integer.
2696             ///
2697             /// Doing non-atomic reads and writes on the resulting integer can be a data race.
2698             /// This method is mostly useful for FFI, where the function signature may use
2699             #[doc = concat!("`*mut ", stringify!($int_type), "` instead of `&", stringify!($atomic_type), "`.")]
2700             ///
2701             /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
2702             /// atomic types work with interior mutability. All modifications of an atomic change the value
2703             /// through a shared reference, and can do so safely as long as they use atomic operations. Any
2704             /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the same
2705             /// restriction: operations on it must be atomic.
2706             ///
2707             /// # Examples
2708             ///
2709             /// ```ignore (extern-declaration)
2710             /// # fn main() {
2711             #[doc = concat!($extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";")]
2712             ///
2713             /// extern "C" {
2714             #[doc = concat!("    fn my_atomic_op(arg: *mut ", stringify!($int_type), ");")]
2715             /// }
2716             ///
2717             #[doc = concat!("let atomic = ", stringify!($atomic_type), "::new(1);")]
2718             ///
2719             /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
2720             /// unsafe {
2721             ///     my_atomic_op(atomic.as_mut_ptr());
2722             /// }
2723             /// # }
2724             /// ```
2725             #[inline]
2726             #[unstable(feature = "atomic_mut_ptr",
2727                    reason = "recently added",
2728                    issue = "66893")]
2729             pub fn as_mut_ptr(&self) -> *mut $int_type {
2730                 self.v.get()
2731             }
2732         }
2733     }
2734 }
2735
2736 #[cfg(target_has_atomic_load_store = "8")]
2737 atomic_int! {
2738     cfg(target_has_atomic = "8"),
2739     cfg(target_has_atomic_equal_alignment = "8"),
2740     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2741     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2742     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2743     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2744     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2745     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2746     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2747     unstable(feature = "integer_atomics", issue = "99069"),
2748     cfg_attr(not(test), rustc_diagnostic_item = "AtomicI8"),
2749     "i8",
2750     "",
2751     atomic_min, atomic_max,
2752     1,
2753     "AtomicI8::new(0)",
2754     i8 AtomicI8 ATOMIC_I8_INIT
2755 }
2756 #[cfg(target_has_atomic_load_store = "8")]
2757 atomic_int! {
2758     cfg(target_has_atomic = "8"),
2759     cfg(target_has_atomic_equal_alignment = "8"),
2760     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2761     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2762     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2763     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2764     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2765     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2766     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2767     unstable(feature = "integer_atomics", issue = "99069"),
2768     cfg_attr(not(test), rustc_diagnostic_item = "AtomicU8"),
2769     "u8",
2770     "",
2771     atomic_umin, atomic_umax,
2772     1,
2773     "AtomicU8::new(0)",
2774     u8 AtomicU8 ATOMIC_U8_INIT
2775 }
2776 #[cfg(target_has_atomic_load_store = "16")]
2777 atomic_int! {
2778     cfg(target_has_atomic = "16"),
2779     cfg(target_has_atomic_equal_alignment = "16"),
2780     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2781     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2782     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2783     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2784     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2785     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2786     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2787     unstable(feature = "integer_atomics", issue = "99069"),
2788     cfg_attr(not(test), rustc_diagnostic_item = "AtomicI16"),
2789     "i16",
2790     "",
2791     atomic_min, atomic_max,
2792     2,
2793     "AtomicI16::new(0)",
2794     i16 AtomicI16 ATOMIC_I16_INIT
2795 }
2796 #[cfg(target_has_atomic_load_store = "16")]
2797 atomic_int! {
2798     cfg(target_has_atomic = "16"),
2799     cfg(target_has_atomic_equal_alignment = "16"),
2800     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2801     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2802     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2803     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2804     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2805     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2806     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2807     unstable(feature = "integer_atomics", issue = "99069"),
2808     cfg_attr(not(test), rustc_diagnostic_item = "AtomicU16"),
2809     "u16",
2810     "",
2811     atomic_umin, atomic_umax,
2812     2,
2813     "AtomicU16::new(0)",
2814     u16 AtomicU16 ATOMIC_U16_INIT
2815 }
2816 #[cfg(target_has_atomic_load_store = "32")]
2817 atomic_int! {
2818     cfg(target_has_atomic = "32"),
2819     cfg(target_has_atomic_equal_alignment = "32"),
2820     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2821     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2822     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2823     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2824     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2825     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2826     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2827     unstable(feature = "integer_atomics", issue = "99069"),
2828     cfg_attr(not(test), rustc_diagnostic_item = "AtomicI32"),
2829     "i32",
2830     "",
2831     atomic_min, atomic_max,
2832     4,
2833     "AtomicI32::new(0)",
2834     i32 AtomicI32 ATOMIC_I32_INIT
2835 }
2836 #[cfg(target_has_atomic_load_store = "32")]
2837 atomic_int! {
2838     cfg(target_has_atomic = "32"),
2839     cfg(target_has_atomic_equal_alignment = "32"),
2840     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2841     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2842     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2843     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2844     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2845     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2846     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2847     unstable(feature = "integer_atomics", issue = "99069"),
2848     cfg_attr(not(test), rustc_diagnostic_item = "AtomicU32"),
2849     "u32",
2850     "",
2851     atomic_umin, atomic_umax,
2852     4,
2853     "AtomicU32::new(0)",
2854     u32 AtomicU32 ATOMIC_U32_INIT
2855 }
2856 #[cfg(target_has_atomic_load_store = "64")]
2857 atomic_int! {
2858     cfg(target_has_atomic = "64"),
2859     cfg(target_has_atomic_equal_alignment = "64"),
2860     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2861     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2862     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2863     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2864     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2865     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2866     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2867     unstable(feature = "integer_atomics", issue = "99069"),
2868     cfg_attr(not(test), rustc_diagnostic_item = "AtomicI64"),
2869     "i64",
2870     "",
2871     atomic_min, atomic_max,
2872     8,
2873     "AtomicI64::new(0)",
2874     i64 AtomicI64 ATOMIC_I64_INIT
2875 }
2876 #[cfg(target_has_atomic_load_store = "64")]
2877 atomic_int! {
2878     cfg(target_has_atomic = "64"),
2879     cfg(target_has_atomic_equal_alignment = "64"),
2880     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2881     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2882     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2883     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2884     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2885     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2886     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2887     unstable(feature = "integer_atomics", issue = "99069"),
2888     cfg_attr(not(test), rustc_diagnostic_item = "AtomicU64"),
2889     "u64",
2890     "",
2891     atomic_umin, atomic_umax,
2892     8,
2893     "AtomicU64::new(0)",
2894     u64 AtomicU64 ATOMIC_U64_INIT
2895 }
2896 #[cfg(target_has_atomic_load_store = "128")]
2897 atomic_int! {
2898     cfg(target_has_atomic = "128"),
2899     cfg(target_has_atomic_equal_alignment = "128"),
2900     unstable(feature = "integer_atomics", issue = "99069"),
2901     unstable(feature = "integer_atomics", issue = "99069"),
2902     unstable(feature = "integer_atomics", issue = "99069"),
2903     unstable(feature = "integer_atomics", issue = "99069"),
2904     unstable(feature = "integer_atomics", issue = "99069"),
2905     unstable(feature = "integer_atomics", issue = "99069"),
2906     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2907     unstable(feature = "integer_atomics", issue = "99069"),
2908     cfg_attr(not(test), rustc_diagnostic_item = "AtomicI128"),
2909     "i128",
2910     "#![feature(integer_atomics)]\n\n",
2911     atomic_min, atomic_max,
2912     16,
2913     "AtomicI128::new(0)",
2914     i128 AtomicI128 ATOMIC_I128_INIT
2915 }
2916 #[cfg(target_has_atomic_load_store = "128")]
2917 atomic_int! {
2918     cfg(target_has_atomic = "128"),
2919     cfg(target_has_atomic_equal_alignment = "128"),
2920     unstable(feature = "integer_atomics", issue = "99069"),
2921     unstable(feature = "integer_atomics", issue = "99069"),
2922     unstable(feature = "integer_atomics", issue = "99069"),
2923     unstable(feature = "integer_atomics", issue = "99069"),
2924     unstable(feature = "integer_atomics", issue = "99069"),
2925     unstable(feature = "integer_atomics", issue = "99069"),
2926     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2927     unstable(feature = "integer_atomics", issue = "99069"),
2928     cfg_attr(not(test), rustc_diagnostic_item = "AtomicU128"),
2929     "u128",
2930     "#![feature(integer_atomics)]\n\n",
2931     atomic_umin, atomic_umax,
2932     16,
2933     "AtomicU128::new(0)",
2934     u128 AtomicU128 ATOMIC_U128_INIT
2935 }
2936
2937 macro_rules! atomic_int_ptr_sized {
2938     ( $($target_pointer_width:literal $align:literal)* ) => { $(
2939         #[cfg(target_has_atomic_load_store = "ptr")]
2940         #[cfg(target_pointer_width = $target_pointer_width)]
2941         atomic_int! {
2942             cfg(target_has_atomic = "ptr"),
2943             cfg(target_has_atomic_equal_alignment = "ptr"),
2944             stable(feature = "rust1", since = "1.0.0"),
2945             stable(feature = "extended_compare_and_swap", since = "1.10.0"),
2946             stable(feature = "atomic_debug", since = "1.3.0"),
2947             stable(feature = "atomic_access", since = "1.15.0"),
2948             stable(feature = "atomic_from", since = "1.23.0"),
2949             stable(feature = "atomic_nand", since = "1.27.0"),
2950             rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"),
2951             stable(feature = "rust1", since = "1.0.0"),
2952             cfg_attr(not(test), rustc_diagnostic_item = "AtomicIsize"),
2953             "isize",
2954             "",
2955             atomic_min, atomic_max,
2956             $align,
2957             "AtomicIsize::new(0)",
2958             isize AtomicIsize ATOMIC_ISIZE_INIT
2959         }
2960         #[cfg(target_has_atomic_load_store = "ptr")]
2961         #[cfg(target_pointer_width = $target_pointer_width)]
2962         atomic_int! {
2963             cfg(target_has_atomic = "ptr"),
2964             cfg(target_has_atomic_equal_alignment = "ptr"),
2965             stable(feature = "rust1", since = "1.0.0"),
2966             stable(feature = "extended_compare_and_swap", since = "1.10.0"),
2967             stable(feature = "atomic_debug", since = "1.3.0"),
2968             stable(feature = "atomic_access", since = "1.15.0"),
2969             stable(feature = "atomic_from", since = "1.23.0"),
2970             stable(feature = "atomic_nand", since = "1.27.0"),
2971             rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"),
2972             stable(feature = "rust1", since = "1.0.0"),
2973             cfg_attr(not(test), rustc_diagnostic_item = "AtomicUsize"),
2974             "usize",
2975             "",
2976             atomic_umin, atomic_umax,
2977             $align,
2978             "AtomicUsize::new(0)",
2979             usize AtomicUsize ATOMIC_USIZE_INIT
2980         }
2981     )* };
2982 }
2983
2984 atomic_int_ptr_sized! {
2985     "16" 2
2986     "32" 4
2987     "64" 8
2988 }
2989
2990 #[inline]
2991 #[cfg(target_has_atomic = "8")]
2992 fn strongest_failure_ordering(order: Ordering) -> Ordering {
2993     match order {
2994         Release => Relaxed,
2995         Relaxed => Relaxed,
2996         SeqCst => SeqCst,
2997         Acquire => Acquire,
2998         AcqRel => Acquire,
2999     }
3000 }
3001
3002 #[inline]
3003 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3004 unsafe fn atomic_store<T: Copy>(dst: *mut T, val: T, order: Ordering) {
3005     // SAFETY: the caller must uphold the safety contract for `atomic_store`.
3006     unsafe {
3007         match order {
3008             Relaxed => intrinsics::atomic_store_relaxed(dst, val),
3009             Release => intrinsics::atomic_store_release(dst, val),
3010             SeqCst => intrinsics::atomic_store_seqcst(dst, val),
3011             Acquire => panic!("there is no such thing as an acquire store"),
3012             AcqRel => panic!("there is no such thing as an acquire-release store"),
3013         }
3014     }
3015 }
3016
3017 #[inline]
3018 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3019 unsafe fn atomic_load<T: Copy>(dst: *const T, order: Ordering) -> T {
3020     // SAFETY: the caller must uphold the safety contract for `atomic_load`.
3021     unsafe {
3022         match order {
3023             Relaxed => intrinsics::atomic_load_relaxed(dst),
3024             Acquire => intrinsics::atomic_load_acquire(dst),
3025             SeqCst => intrinsics::atomic_load_seqcst(dst),
3026             Release => panic!("there is no such thing as a release load"),
3027             AcqRel => panic!("there is no such thing as an acquire-release load"),
3028         }
3029     }
3030 }
3031
3032 #[inline]
3033 #[cfg(target_has_atomic = "8")]
3034 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3035 unsafe fn atomic_swap<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3036     // SAFETY: the caller must uphold the safety contract for `atomic_swap`.
3037     unsafe {
3038         match order {
3039             Relaxed => intrinsics::atomic_xchg_relaxed(dst, val),
3040             Acquire => intrinsics::atomic_xchg_acquire(dst, val),
3041             Release => intrinsics::atomic_xchg_release(dst, val),
3042             AcqRel => intrinsics::atomic_xchg_acqrel(dst, val),
3043             SeqCst => intrinsics::atomic_xchg_seqcst(dst, val),
3044         }
3045     }
3046 }
3047
3048 /// Returns the previous value (like __sync_fetch_and_add).
3049 #[inline]
3050 #[cfg(target_has_atomic = "8")]
3051 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3052 unsafe fn atomic_add<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3053     // SAFETY: the caller must uphold the safety contract for `atomic_add`.
3054     unsafe {
3055         match order {
3056             Relaxed => intrinsics::atomic_xadd_relaxed(dst, val),
3057             Acquire => intrinsics::atomic_xadd_acquire(dst, val),
3058             Release => intrinsics::atomic_xadd_release(dst, val),
3059             AcqRel => intrinsics::atomic_xadd_acqrel(dst, val),
3060             SeqCst => intrinsics::atomic_xadd_seqcst(dst, val),
3061         }
3062     }
3063 }
3064
3065 /// Returns the previous value (like __sync_fetch_and_sub).
3066 #[inline]
3067 #[cfg(target_has_atomic = "8")]
3068 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3069 unsafe fn atomic_sub<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3070     // SAFETY: the caller must uphold the safety contract for `atomic_sub`.
3071     unsafe {
3072         match order {
3073             Relaxed => intrinsics::atomic_xsub_relaxed(dst, val),
3074             Acquire => intrinsics::atomic_xsub_acquire(dst, val),
3075             Release => intrinsics::atomic_xsub_release(dst, val),
3076             AcqRel => intrinsics::atomic_xsub_acqrel(dst, val),
3077             SeqCst => intrinsics::atomic_xsub_seqcst(dst, val),
3078         }
3079     }
3080 }
3081
3082 #[inline]
3083 #[cfg(target_has_atomic = "8")]
3084 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3085 unsafe fn atomic_compare_exchange<T: Copy>(
3086     dst: *mut T,
3087     old: T,
3088     new: T,
3089     success: Ordering,
3090     failure: Ordering,
3091 ) -> Result<T, T> {
3092     // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange`.
3093     let (val, ok) = unsafe {
3094         match (success, failure) {
3095             (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed_relaxed(dst, old, new),
3096             (Relaxed, Acquire) => intrinsics::atomic_cxchg_relaxed_acquire(dst, old, new),
3097             (Relaxed, SeqCst) => intrinsics::atomic_cxchg_relaxed_seqcst(dst, old, new),
3098             (Acquire, Relaxed) => intrinsics::atomic_cxchg_acquire_relaxed(dst, old, new),
3099             (Acquire, Acquire) => intrinsics::atomic_cxchg_acquire_acquire(dst, old, new),
3100             (Acquire, SeqCst) => intrinsics::atomic_cxchg_acquire_seqcst(dst, old, new),
3101             (Release, Relaxed) => intrinsics::atomic_cxchg_release_relaxed(dst, old, new),
3102             (Release, Acquire) => intrinsics::atomic_cxchg_release_acquire(dst, old, new),
3103             (Release, SeqCst) => intrinsics::atomic_cxchg_release_seqcst(dst, old, new),
3104             (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_relaxed(dst, old, new),
3105             (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel_acquire(dst, old, new),
3106             (AcqRel, SeqCst) => intrinsics::atomic_cxchg_acqrel_seqcst(dst, old, new),
3107             (SeqCst, Relaxed) => intrinsics::atomic_cxchg_seqcst_relaxed(dst, old, new),
3108             (SeqCst, Acquire) => intrinsics::atomic_cxchg_seqcst_acquire(dst, old, new),
3109             (SeqCst, SeqCst) => intrinsics::atomic_cxchg_seqcst_seqcst(dst, old, new),
3110             (_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"),
3111             (_, Release) => panic!("there is no such thing as a release failure ordering"),
3112         }
3113     };
3114     if ok { Ok(val) } else { Err(val) }
3115 }
3116
3117 #[inline]
3118 #[cfg(target_has_atomic = "8")]
3119 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3120 unsafe fn atomic_compare_exchange_weak<T: Copy>(
3121     dst: *mut T,
3122     old: T,
3123     new: T,
3124     success: Ordering,
3125     failure: Ordering,
3126 ) -> Result<T, T> {
3127     // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange_weak`.
3128     let (val, ok) = unsafe {
3129         match (success, failure) {
3130             (Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed_relaxed(dst, old, new),
3131             (Relaxed, Acquire) => intrinsics::atomic_cxchgweak_relaxed_acquire(dst, old, new),
3132             (Relaxed, SeqCst) => intrinsics::atomic_cxchgweak_relaxed_seqcst(dst, old, new),
3133             (Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acquire_relaxed(dst, old, new),
3134             (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acquire_acquire(dst, old, new),
3135             (Acquire, SeqCst) => intrinsics::atomic_cxchgweak_acquire_seqcst(dst, old, new),
3136             (Release, Relaxed) => intrinsics::atomic_cxchgweak_release_relaxed(dst, old, new),
3137             (Release, Acquire) => intrinsics::atomic_cxchgweak_release_acquire(dst, old, new),
3138             (Release, SeqCst) => intrinsics::atomic_cxchgweak_release_seqcst(dst, old, new),
3139             (AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_relaxed(dst, old, new),
3140             (AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel_acquire(dst, old, new),
3141             (AcqRel, SeqCst) => intrinsics::atomic_cxchgweak_acqrel_seqcst(dst, old, new),
3142             (SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_seqcst_relaxed(dst, old, new),
3143             (SeqCst, Acquire) => intrinsics::atomic_cxchgweak_seqcst_acquire(dst, old, new),
3144             (SeqCst, SeqCst) => intrinsics::atomic_cxchgweak_seqcst_seqcst(dst, old, new),
3145             (_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"),
3146             (_, Release) => panic!("there is no such thing as a release failure ordering"),
3147         }
3148     };
3149     if ok { Ok(val) } else { Err(val) }
3150 }
3151
3152 #[inline]
3153 #[cfg(target_has_atomic = "8")]
3154 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3155 unsafe fn atomic_and<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3156     // SAFETY: the caller must uphold the safety contract for `atomic_and`
3157     unsafe {
3158         match order {
3159             Relaxed => intrinsics::atomic_and_relaxed(dst, val),
3160             Acquire => intrinsics::atomic_and_acquire(dst, val),
3161             Release => intrinsics::atomic_and_release(dst, val),
3162             AcqRel => intrinsics::atomic_and_acqrel(dst, val),
3163             SeqCst => intrinsics::atomic_and_seqcst(dst, val),
3164         }
3165     }
3166 }
3167
3168 #[inline]
3169 #[cfg(target_has_atomic = "8")]
3170 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3171 unsafe fn atomic_nand<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3172     // SAFETY: the caller must uphold the safety contract for `atomic_nand`
3173     unsafe {
3174         match order {
3175             Relaxed => intrinsics::atomic_nand_relaxed(dst, val),
3176             Acquire => intrinsics::atomic_nand_acquire(dst, val),
3177             Release => intrinsics::atomic_nand_release(dst, val),
3178             AcqRel => intrinsics::atomic_nand_acqrel(dst, val),
3179             SeqCst => intrinsics::atomic_nand_seqcst(dst, val),
3180         }
3181     }
3182 }
3183
3184 #[inline]
3185 #[cfg(target_has_atomic = "8")]
3186 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3187 unsafe fn atomic_or<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3188     // SAFETY: the caller must uphold the safety contract for `atomic_or`
3189     unsafe {
3190         match order {
3191             SeqCst => intrinsics::atomic_or_seqcst(dst, val),
3192             Acquire => intrinsics::atomic_or_acquire(dst, val),
3193             Release => intrinsics::atomic_or_release(dst, val),
3194             AcqRel => intrinsics::atomic_or_acqrel(dst, val),
3195             Relaxed => intrinsics::atomic_or_relaxed(dst, val),
3196         }
3197     }
3198 }
3199
3200 #[inline]
3201 #[cfg(target_has_atomic = "8")]
3202 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3203 unsafe fn atomic_xor<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3204     // SAFETY: the caller must uphold the safety contract for `atomic_xor`
3205     unsafe {
3206         match order {
3207             SeqCst => intrinsics::atomic_xor_seqcst(dst, val),
3208             Acquire => intrinsics::atomic_xor_acquire(dst, val),
3209             Release => intrinsics::atomic_xor_release(dst, val),
3210             AcqRel => intrinsics::atomic_xor_acqrel(dst, val),
3211             Relaxed => intrinsics::atomic_xor_relaxed(dst, val),
3212         }
3213     }
3214 }
3215
3216 /// returns the max value (signed comparison)
3217 #[inline]
3218 #[cfg(target_has_atomic = "8")]
3219 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3220 unsafe fn atomic_max<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3221     // SAFETY: the caller must uphold the safety contract for `atomic_max`
3222     unsafe {
3223         match order {
3224             Relaxed => intrinsics::atomic_max_relaxed(dst, val),
3225             Acquire => intrinsics::atomic_max_acquire(dst, val),
3226             Release => intrinsics::atomic_max_release(dst, val),
3227             AcqRel => intrinsics::atomic_max_acqrel(dst, val),
3228             SeqCst => intrinsics::atomic_max_seqcst(dst, val),
3229         }
3230     }
3231 }
3232
3233 /// returns the min value (signed comparison)
3234 #[inline]
3235 #[cfg(target_has_atomic = "8")]
3236 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3237 unsafe fn atomic_min<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3238     // SAFETY: the caller must uphold the safety contract for `atomic_min`
3239     unsafe {
3240         match order {
3241             Relaxed => intrinsics::atomic_min_relaxed(dst, val),
3242             Acquire => intrinsics::atomic_min_acquire(dst, val),
3243             Release => intrinsics::atomic_min_release(dst, val),
3244             AcqRel => intrinsics::atomic_min_acqrel(dst, val),
3245             SeqCst => intrinsics::atomic_min_seqcst(dst, val),
3246         }
3247     }
3248 }
3249
3250 /// returns the max value (unsigned comparison)
3251 #[inline]
3252 #[cfg(target_has_atomic = "8")]
3253 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3254 unsafe fn atomic_umax<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3255     // SAFETY: the caller must uphold the safety contract for `atomic_umax`
3256     unsafe {
3257         match order {
3258             Relaxed => intrinsics::atomic_umax_relaxed(dst, val),
3259             Acquire => intrinsics::atomic_umax_acquire(dst, val),
3260             Release => intrinsics::atomic_umax_release(dst, val),
3261             AcqRel => intrinsics::atomic_umax_acqrel(dst, val),
3262             SeqCst => intrinsics::atomic_umax_seqcst(dst, val),
3263         }
3264     }
3265 }
3266
3267 /// returns the min value (unsigned comparison)
3268 #[inline]
3269 #[cfg(target_has_atomic = "8")]
3270 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3271 unsafe fn atomic_umin<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3272     // SAFETY: the caller must uphold the safety contract for `atomic_umin`
3273     unsafe {
3274         match order {
3275             Relaxed => intrinsics::atomic_umin_relaxed(dst, val),
3276             Acquire => intrinsics::atomic_umin_acquire(dst, val),
3277             Release => intrinsics::atomic_umin_release(dst, val),
3278             AcqRel => intrinsics::atomic_umin_acqrel(dst, val),
3279             SeqCst => intrinsics::atomic_umin_seqcst(dst, val),
3280         }
3281     }
3282 }
3283
3284 /// An atomic fence.
3285 ///
3286 /// Depending on the specified order, a fence prevents the compiler and CPU from
3287 /// reordering certain types of memory operations around it.
3288 /// That creates synchronizes-with relationships between it and atomic operations
3289 /// or fences in other threads.
3290 ///
3291 /// A fence 'A' which has (at least) [`Release`] ordering semantics, synchronizes
3292 /// with a fence 'B' with (at least) [`Acquire`] semantics, if and only if there
3293 /// exist operations X and Y, both operating on some atomic object 'M' such
3294 /// that A is sequenced before X, Y is sequenced before B and Y observes
3295 /// the change to M. This provides a happens-before dependence between A and B.
3296 ///
3297 /// ```text
3298 ///     Thread 1                                          Thread 2
3299 ///
3300 /// fence(Release);      A --------------
3301 /// x.store(3, Relaxed); X ---------    |
3302 ///                                |    |
3303 ///                                |    |
3304 ///                                -------------> Y  if x.load(Relaxed) == 3 {
3305 ///                                     |-------> B      fence(Acquire);
3306 ///                                                      ...
3307 ///                                                  }
3308 /// ```
3309 ///
3310 /// Atomic operations with [`Release`] or [`Acquire`] semantics can also synchronize
3311 /// with a fence.
3312 ///
3313 /// A fence which has [`SeqCst`] ordering, in addition to having both [`Acquire`]
3314 /// and [`Release`] semantics, participates in the global program order of the
3315 /// other [`SeqCst`] operations and/or fences.
3316 ///
3317 /// Accepts [`Acquire`], [`Release`], [`AcqRel`] and [`SeqCst`] orderings.
3318 ///
3319 /// # Panics
3320 ///
3321 /// Panics if `order` is [`Relaxed`].
3322 ///
3323 /// # Examples
3324 ///
3325 /// ```
3326 /// use std::sync::atomic::AtomicBool;
3327 /// use std::sync::atomic::fence;
3328 /// use std::sync::atomic::Ordering;
3329 ///
3330 /// // A mutual exclusion primitive based on spinlock.
3331 /// pub struct Mutex {
3332 ///     flag: AtomicBool,
3333 /// }
3334 ///
3335 /// impl Mutex {
3336 ///     pub fn new() -> Mutex {
3337 ///         Mutex {
3338 ///             flag: AtomicBool::new(false),
3339 ///         }
3340 ///     }
3341 ///
3342 ///     pub fn lock(&self) {
3343 ///         // Wait until the old value is `false`.
3344 ///         while self
3345 ///             .flag
3346 ///             .compare_exchange_weak(false, true, Ordering::Relaxed, Ordering::Relaxed)
3347 ///             .is_err()
3348 ///         {}
3349 ///         // This fence synchronizes-with store in `unlock`.
3350 ///         fence(Ordering::Acquire);
3351 ///     }
3352 ///
3353 ///     pub fn unlock(&self) {
3354 ///         self.flag.store(false, Ordering::Release);
3355 ///     }
3356 /// }
3357 /// ```
3358 #[inline]
3359 #[stable(feature = "rust1", since = "1.0.0")]
3360 #[rustc_diagnostic_item = "fence"]
3361 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3362 pub fn fence(order: Ordering) {
3363     // SAFETY: using an atomic fence is safe.
3364     unsafe {
3365         match order {
3366             Acquire => intrinsics::atomic_fence_acquire(),
3367             Release => intrinsics::atomic_fence_release(),
3368             AcqRel => intrinsics::atomic_fence_acqrel(),
3369             SeqCst => intrinsics::atomic_fence_seqcst(),
3370             Relaxed => panic!("there is no such thing as a relaxed fence"),
3371         }
3372     }
3373 }
3374
3375 /// A compiler memory fence.
3376 ///
3377 /// `compiler_fence` does not emit any machine code, but restricts the kinds
3378 /// of memory re-ordering the compiler is allowed to do. Specifically, depending on
3379 /// the given [`Ordering`] semantics, the compiler may be disallowed from moving reads
3380 /// or writes from before or after the call to the other side of the call to
3381 /// `compiler_fence`. Note that it does **not** prevent the *hardware*
3382 /// from doing such re-ordering. This is not a problem in a single-threaded,
3383 /// execution context, but when other threads may modify memory at the same
3384 /// time, stronger synchronization primitives such as [`fence`] are required.
3385 ///
3386 /// The re-ordering prevented by the different ordering semantics are:
3387 ///
3388 ///  - with [`SeqCst`], no re-ordering of reads and writes across this point is allowed.
3389 ///  - with [`Release`], preceding reads and writes cannot be moved past subsequent writes.
3390 ///  - with [`Acquire`], subsequent reads and writes cannot be moved ahead of preceding reads.
3391 ///  - with [`AcqRel`], both of the above rules are enforced.
3392 ///
3393 /// `compiler_fence` is generally only useful for preventing a thread from
3394 /// racing *with itself*. That is, if a given thread is executing one piece
3395 /// of code, and is then interrupted, and starts executing code elsewhere
3396 /// (while still in the same thread, and conceptually still on the same
3397 /// core). In traditional programs, this can only occur when a signal
3398 /// handler is registered. In more low-level code, such situations can also
3399 /// arise when handling interrupts, when implementing green threads with
3400 /// pre-emption, etc. Curious readers are encouraged to read the Linux kernel's
3401 /// discussion of [memory barriers].
3402 ///
3403 /// # Panics
3404 ///
3405 /// Panics if `order` is [`Relaxed`].
3406 ///
3407 /// # Examples
3408 ///
3409 /// Without `compiler_fence`, the `assert_eq!` in following code
3410 /// is *not* guaranteed to succeed, despite everything happening in a single thread.
3411 /// To see why, remember that the compiler is free to swap the stores to
3412 /// `IMPORTANT_VARIABLE` and `IS_READY` since they are both
3413 /// `Ordering::Relaxed`. If it does, and the signal handler is invoked right
3414 /// after `IS_READY` is updated, then the signal handler will see
3415 /// `IS_READY=1`, but `IMPORTANT_VARIABLE=0`.
3416 /// Using a `compiler_fence` remedies this situation.
3417 ///
3418 /// ```
3419 /// use std::sync::atomic::{AtomicBool, AtomicUsize};
3420 /// use std::sync::atomic::Ordering;
3421 /// use std::sync::atomic::compiler_fence;
3422 ///
3423 /// static IMPORTANT_VARIABLE: AtomicUsize = AtomicUsize::new(0);
3424 /// static IS_READY: AtomicBool = AtomicBool::new(false);
3425 ///
3426 /// fn main() {
3427 ///     IMPORTANT_VARIABLE.store(42, Ordering::Relaxed);
3428 ///     // prevent earlier writes from being moved beyond this point
3429 ///     compiler_fence(Ordering::Release);
3430 ///     IS_READY.store(true, Ordering::Relaxed);
3431 /// }
3432 ///
3433 /// fn signal_handler() {
3434 ///     if IS_READY.load(Ordering::Relaxed) {
3435 ///         assert_eq!(IMPORTANT_VARIABLE.load(Ordering::Relaxed), 42);
3436 ///     }
3437 /// }
3438 /// ```
3439 ///
3440 /// [memory barriers]: https://www.kernel.org/doc/Documentation/memory-barriers.txt
3441 #[inline]
3442 #[stable(feature = "compiler_fences", since = "1.21.0")]
3443 #[rustc_diagnostic_item = "compiler_fence"]
3444 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3445 pub fn compiler_fence(order: Ordering) {
3446     // SAFETY: using an atomic fence is safe.
3447     unsafe {
3448         match order {
3449             Acquire => intrinsics::atomic_singlethreadfence_acquire(),
3450             Release => intrinsics::atomic_singlethreadfence_release(),
3451             AcqRel => intrinsics::atomic_singlethreadfence_acqrel(),
3452             SeqCst => intrinsics::atomic_singlethreadfence_seqcst(),
3453             Relaxed => panic!("there is no such thing as a relaxed compiler fence"),
3454         }
3455     }
3456 }
3457
3458 #[cfg(target_has_atomic_load_store = "8")]
3459 #[stable(feature = "atomic_debug", since = "1.3.0")]
3460 impl fmt::Debug for AtomicBool {
3461     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3462         fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
3463     }
3464 }
3465
3466 #[cfg(target_has_atomic_load_store = "ptr")]
3467 #[stable(feature = "atomic_debug", since = "1.3.0")]
3468 impl<T> fmt::Debug for AtomicPtr<T> {
3469     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3470         fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
3471     }
3472 }
3473
3474 #[cfg(target_has_atomic_load_store = "ptr")]
3475 #[stable(feature = "atomic_pointer", since = "1.24.0")]
3476 impl<T> fmt::Pointer for AtomicPtr<T> {
3477     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3478         fmt::Pointer::fmt(&self.load(Ordering::SeqCst), f)
3479     }
3480 }
3481
3482 /// Signals the processor that it is inside a busy-wait spin-loop ("spin lock").
3483 ///
3484 /// This function is deprecated in favor of [`hint::spin_loop`].
3485 ///
3486 /// [`hint::spin_loop`]: crate::hint::spin_loop
3487 #[inline]
3488 #[stable(feature = "spin_loop_hint", since = "1.24.0")]
3489 #[deprecated(since = "1.51.0", note = "use hint::spin_loop instead")]
3490 pub fn spin_loop_hint() {
3491     spin_loop()
3492 }