]> git.lizzy.rs Git - rust.git/blob - library/core/src/sync/atomic.rs
Auto merge of #100251 - compiler-errors:tuple-trait-2, r=jackh726
[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     /// # Examples
959     ///
960     /// ```rust
961     /// use std::sync::atomic::{AtomicBool, Ordering};
962     ///
963     /// let x = AtomicBool::new(false);
964     /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(false));
965     /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(!x)), Ok(false));
966     /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(!x)), Ok(true));
967     /// assert_eq!(x.load(Ordering::SeqCst), false);
968     /// ```
969     #[inline]
970     #[stable(feature = "atomic_fetch_update", since = "1.53.0")]
971     #[cfg(target_has_atomic = "8")]
972     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
973     pub fn fetch_update<F>(
974         &self,
975         set_order: Ordering,
976         fetch_order: Ordering,
977         mut f: F,
978     ) -> Result<bool, bool>
979     where
980         F: FnMut(bool) -> Option<bool>,
981     {
982         let mut prev = self.load(fetch_order);
983         while let Some(next) = f(prev) {
984             match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
985                 x @ Ok(_) => return x,
986                 Err(next_prev) => prev = next_prev,
987             }
988         }
989         Err(prev)
990     }
991 }
992
993 #[cfg(target_has_atomic_load_store = "ptr")]
994 impl<T> AtomicPtr<T> {
995     /// Creates a new `AtomicPtr`.
996     ///
997     /// # Examples
998     ///
999     /// ```
1000     /// use std::sync::atomic::AtomicPtr;
1001     ///
1002     /// let ptr = &mut 5;
1003     /// let atomic_ptr = AtomicPtr::new(ptr);
1004     /// ```
1005     #[inline]
1006     #[stable(feature = "rust1", since = "1.0.0")]
1007     #[rustc_const_stable(feature = "const_atomic_new", since = "1.24.0")]
1008     pub const fn new(p: *mut T) -> AtomicPtr<T> {
1009         AtomicPtr { p: UnsafeCell::new(p) }
1010     }
1011
1012     /// Returns a mutable reference to the underlying pointer.
1013     ///
1014     /// This is safe because the mutable reference guarantees that no other threads are
1015     /// concurrently accessing the atomic data.
1016     ///
1017     /// # Examples
1018     ///
1019     /// ```
1020     /// use std::sync::atomic::{AtomicPtr, Ordering};
1021     ///
1022     /// let mut data = 10;
1023     /// let mut atomic_ptr = AtomicPtr::new(&mut data);
1024     /// let mut other_data = 5;
1025     /// *atomic_ptr.get_mut() = &mut other_data;
1026     /// assert_eq!(unsafe { *atomic_ptr.load(Ordering::SeqCst) }, 5);
1027     /// ```
1028     #[inline]
1029     #[stable(feature = "atomic_access", since = "1.15.0")]
1030     pub fn get_mut(&mut self) -> &mut *mut T {
1031         self.p.get_mut()
1032     }
1033
1034     /// Get atomic access to a pointer.
1035     ///
1036     /// # Examples
1037     ///
1038     /// ```
1039     /// #![feature(atomic_from_mut)]
1040     /// use std::sync::atomic::{AtomicPtr, Ordering};
1041     ///
1042     /// let mut data = 123;
1043     /// let mut some_ptr = &mut data as *mut i32;
1044     /// let a = AtomicPtr::from_mut(&mut some_ptr);
1045     /// let mut other_data = 456;
1046     /// a.store(&mut other_data, Ordering::Relaxed);
1047     /// assert_eq!(unsafe { *some_ptr }, 456);
1048     /// ```
1049     #[inline]
1050     #[cfg(target_has_atomic_equal_alignment = "ptr")]
1051     #[unstable(feature = "atomic_from_mut", issue = "76314")]
1052     pub fn from_mut(v: &mut *mut T) -> &mut Self {
1053         use crate::mem::align_of;
1054         let [] = [(); align_of::<AtomicPtr<()>>() - align_of::<*mut ()>()];
1055         // SAFETY:
1056         //  - the mutable reference guarantees unique ownership.
1057         //  - the alignment of `*mut T` and `Self` is the same on all platforms
1058         //    supported by rust, as verified above.
1059         unsafe { &mut *(v as *mut *mut T as *mut Self) }
1060     }
1061
1062     /// Get non-atomic access to a `&mut [AtomicPtr]` slice.
1063     ///
1064     /// This is safe because the mutable reference guarantees that no other threads are
1065     /// concurrently accessing the atomic data.
1066     ///
1067     /// # Examples
1068     ///
1069     /// ```
1070     /// #![feature(atomic_from_mut, inline_const)]
1071     /// use std::ptr::null_mut;
1072     /// use std::sync::atomic::{AtomicPtr, Ordering};
1073     ///
1074     /// let mut some_ptrs = [const { AtomicPtr::new(null_mut::<String>()) }; 10];
1075     ///
1076     /// let view: &mut [*mut String] = AtomicPtr::get_mut_slice(&mut some_ptrs);
1077     /// assert_eq!(view, [null_mut::<String>(); 10]);
1078     /// view
1079     ///     .iter_mut()
1080     ///     .enumerate()
1081     ///     .for_each(|(i, ptr)| *ptr = Box::into_raw(Box::new(format!("iteration#{i}"))));
1082     ///
1083     /// std::thread::scope(|s| {
1084     ///     for ptr in &some_ptrs {
1085     ///         s.spawn(move || {
1086     ///             let ptr = ptr.load(Ordering::Relaxed);
1087     ///             assert!(!ptr.is_null());
1088     ///
1089     ///             let name = unsafe { Box::from_raw(ptr) };
1090     ///             println!("Hello, {name}!");
1091     ///         });
1092     ///     }
1093     /// });
1094     /// ```
1095     #[inline]
1096     #[unstable(feature = "atomic_from_mut", issue = "76314")]
1097     pub fn get_mut_slice(this: &mut [Self]) -> &mut [*mut T] {
1098         // SAFETY: the mutable reference guarantees unique ownership.
1099         unsafe { &mut *(this as *mut [Self] as *mut [*mut T]) }
1100     }
1101
1102     /// Get atomic access to a slice of pointers.
1103     ///
1104     /// # Examples
1105     ///
1106     /// ```
1107     /// #![feature(atomic_from_mut)]
1108     /// use std::ptr::null_mut;
1109     /// use std::sync::atomic::{AtomicPtr, Ordering};
1110     ///
1111     /// let mut some_ptrs = [null_mut::<String>(); 10];
1112     /// let a = &*AtomicPtr::from_mut_slice(&mut some_ptrs);
1113     /// std::thread::scope(|s| {
1114     ///     for i in 0..a.len() {
1115     ///         s.spawn(move || {
1116     ///             let name = Box::new(format!("thread{i}"));
1117     ///             a[i].store(Box::into_raw(name), Ordering::Relaxed);
1118     ///         });
1119     ///     }
1120     /// });
1121     /// for p in some_ptrs {
1122     ///     assert!(!p.is_null());
1123     ///     let name = unsafe { Box::from_raw(p) };
1124     ///     println!("Hello, {name}!");
1125     /// }
1126     /// ```
1127     #[inline]
1128     #[cfg(target_has_atomic_equal_alignment = "ptr")]
1129     #[unstable(feature = "atomic_from_mut", issue = "76314")]
1130     pub fn from_mut_slice(v: &mut [*mut T]) -> &mut [Self] {
1131         // SAFETY:
1132         //  - the mutable reference guarantees unique ownership.
1133         //  - the alignment of `*mut T` and `Self` is the same on all platforms
1134         //    supported by rust, as verified above.
1135         unsafe { &mut *(v as *mut [*mut T] as *mut [Self]) }
1136     }
1137
1138     /// Consumes the atomic and returns the contained value.
1139     ///
1140     /// This is safe because passing `self` by value guarantees that no other threads are
1141     /// concurrently accessing the atomic data.
1142     ///
1143     /// # Examples
1144     ///
1145     /// ```
1146     /// use std::sync::atomic::AtomicPtr;
1147     ///
1148     /// let mut data = 5;
1149     /// let atomic_ptr = AtomicPtr::new(&mut data);
1150     /// assert_eq!(unsafe { *atomic_ptr.into_inner() }, 5);
1151     /// ```
1152     #[inline]
1153     #[stable(feature = "atomic_access", since = "1.15.0")]
1154     #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")]
1155     pub const fn into_inner(self) -> *mut T {
1156         self.p.into_inner()
1157     }
1158
1159     /// Loads a value from the pointer.
1160     ///
1161     /// `load` takes an [`Ordering`] argument which describes the memory ordering
1162     /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
1163     ///
1164     /// # Panics
1165     ///
1166     /// Panics if `order` is [`Release`] or [`AcqRel`].
1167     ///
1168     /// # Examples
1169     ///
1170     /// ```
1171     /// use std::sync::atomic::{AtomicPtr, Ordering};
1172     ///
1173     /// let ptr = &mut 5;
1174     /// let some_ptr  = AtomicPtr::new(ptr);
1175     ///
1176     /// let value = some_ptr.load(Ordering::Relaxed);
1177     /// ```
1178     #[inline]
1179     #[stable(feature = "rust1", since = "1.0.0")]
1180     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1181     pub fn load(&self, order: Ordering) -> *mut T {
1182         // SAFETY: data races are prevented by atomic intrinsics.
1183         unsafe { atomic_load(self.p.get(), order) }
1184     }
1185
1186     /// Stores a value into the pointer.
1187     ///
1188     /// `store` takes an [`Ordering`] argument which describes the memory ordering
1189     /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
1190     ///
1191     /// # Panics
1192     ///
1193     /// Panics if `order` is [`Acquire`] or [`AcqRel`].
1194     ///
1195     /// # Examples
1196     ///
1197     /// ```
1198     /// use std::sync::atomic::{AtomicPtr, Ordering};
1199     ///
1200     /// let ptr = &mut 5;
1201     /// let some_ptr  = AtomicPtr::new(ptr);
1202     ///
1203     /// let other_ptr = &mut 10;
1204     ///
1205     /// some_ptr.store(other_ptr, Ordering::Relaxed);
1206     /// ```
1207     #[inline]
1208     #[stable(feature = "rust1", since = "1.0.0")]
1209     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1210     pub fn store(&self, ptr: *mut T, order: Ordering) {
1211         // SAFETY: data races are prevented by atomic intrinsics.
1212         unsafe {
1213             atomic_store(self.p.get(), ptr, order);
1214         }
1215     }
1216
1217     /// Stores a value into the pointer, returning the previous value.
1218     ///
1219     /// `swap` takes an [`Ordering`] argument which describes the memory ordering
1220     /// of this operation. All ordering modes are possible. Note that using
1221     /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
1222     /// using [`Release`] makes the load part [`Relaxed`].
1223     ///
1224     /// **Note:** This method is only available on platforms that support atomic
1225     /// operations on pointers.
1226     ///
1227     /// # Examples
1228     ///
1229     /// ```
1230     /// use std::sync::atomic::{AtomicPtr, Ordering};
1231     ///
1232     /// let ptr = &mut 5;
1233     /// let some_ptr  = AtomicPtr::new(ptr);
1234     ///
1235     /// let other_ptr = &mut 10;
1236     ///
1237     /// let value = some_ptr.swap(other_ptr, Ordering::Relaxed);
1238     /// ```
1239     #[inline]
1240     #[stable(feature = "rust1", since = "1.0.0")]
1241     #[cfg(target_has_atomic = "ptr")]
1242     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1243     pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
1244         // SAFETY: data races are prevented by atomic intrinsics.
1245         unsafe { atomic_swap(self.p.get(), ptr, order) }
1246     }
1247
1248     /// Stores a value into the pointer if the current value is the same as the `current` value.
1249     ///
1250     /// The return value is always the previous value. If it is equal to `current`, then the value
1251     /// was updated.
1252     ///
1253     /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
1254     /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
1255     /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
1256     /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
1257     /// happens, and using [`Release`] makes the load part [`Relaxed`].
1258     ///
1259     /// **Note:** This method is only available on platforms that support atomic
1260     /// operations on pointers.
1261     ///
1262     /// # Migrating to `compare_exchange` and `compare_exchange_weak`
1263     ///
1264     /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
1265     /// memory orderings:
1266     ///
1267     /// Original | Success | Failure
1268     /// -------- | ------- | -------
1269     /// Relaxed  | Relaxed | Relaxed
1270     /// Acquire  | Acquire | Acquire
1271     /// Release  | Release | Relaxed
1272     /// AcqRel   | AcqRel  | Acquire
1273     /// SeqCst   | SeqCst  | SeqCst
1274     ///
1275     /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
1276     /// which allows the compiler to generate better assembly code when the compare and swap
1277     /// is used in a loop.
1278     ///
1279     /// # Examples
1280     ///
1281     /// ```
1282     /// use std::sync::atomic::{AtomicPtr, Ordering};
1283     ///
1284     /// let ptr = &mut 5;
1285     /// let some_ptr  = AtomicPtr::new(ptr);
1286     ///
1287     /// let other_ptr   = &mut 10;
1288     ///
1289     /// let value = some_ptr.compare_and_swap(ptr, other_ptr, Ordering::Relaxed);
1290     /// ```
1291     #[inline]
1292     #[stable(feature = "rust1", since = "1.0.0")]
1293     #[deprecated(
1294         since = "1.50.0",
1295         note = "Use `compare_exchange` or `compare_exchange_weak` instead"
1296     )]
1297     #[cfg(target_has_atomic = "ptr")]
1298     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1299     pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) -> *mut T {
1300         match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
1301             Ok(x) => x,
1302             Err(x) => x,
1303         }
1304     }
1305
1306     /// Stores a value into the pointer if the current value is the same as the `current` value.
1307     ///
1308     /// The return value is a result indicating whether the new value was written and containing
1309     /// the previous value. On success this value is guaranteed to be equal to `current`.
1310     ///
1311     /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
1312     /// ordering of this operation. `success` describes the required ordering for the
1313     /// read-modify-write operation that takes place if the comparison with `current` succeeds.
1314     /// `failure` describes the required ordering for the load operation that takes place when
1315     /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
1316     /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
1317     /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
1318     ///
1319     /// **Note:** This method is only available on platforms that support atomic
1320     /// operations on pointers.
1321     ///
1322     /// # Examples
1323     ///
1324     /// ```
1325     /// use std::sync::atomic::{AtomicPtr, Ordering};
1326     ///
1327     /// let ptr = &mut 5;
1328     /// let some_ptr  = AtomicPtr::new(ptr);
1329     ///
1330     /// let other_ptr   = &mut 10;
1331     ///
1332     /// let value = some_ptr.compare_exchange(ptr, other_ptr,
1333     ///                                       Ordering::SeqCst, Ordering::Relaxed);
1334     /// ```
1335     #[inline]
1336     #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
1337     #[cfg(target_has_atomic = "ptr")]
1338     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1339     pub fn compare_exchange(
1340         &self,
1341         current: *mut T,
1342         new: *mut T,
1343         success: Ordering,
1344         failure: Ordering,
1345     ) -> Result<*mut T, *mut T> {
1346         // SAFETY: data races are prevented by atomic intrinsics.
1347         unsafe { atomic_compare_exchange(self.p.get(), current, new, success, failure) }
1348     }
1349
1350     /// Stores a value into the pointer if the current value is the same as the `current` value.
1351     ///
1352     /// Unlike [`AtomicPtr::compare_exchange`], this function is allowed to spuriously fail even when the
1353     /// comparison succeeds, which can result in more efficient code on some platforms. The
1354     /// return value is a result indicating whether the new value was written and containing the
1355     /// previous value.
1356     ///
1357     /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
1358     /// ordering of this operation. `success` describes the required ordering for the
1359     /// read-modify-write operation that takes place if the comparison with `current` succeeds.
1360     /// `failure` describes the required ordering for the load operation that takes place when
1361     /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
1362     /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
1363     /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
1364     ///
1365     /// **Note:** This method is only available on platforms that support atomic
1366     /// operations on pointers.
1367     ///
1368     /// # Examples
1369     ///
1370     /// ```
1371     /// use std::sync::atomic::{AtomicPtr, Ordering};
1372     ///
1373     /// let some_ptr = AtomicPtr::new(&mut 5);
1374     ///
1375     /// let new = &mut 10;
1376     /// let mut old = some_ptr.load(Ordering::Relaxed);
1377     /// loop {
1378     ///     match some_ptr.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
1379     ///         Ok(_) => break,
1380     ///         Err(x) => old = x,
1381     ///     }
1382     /// }
1383     /// ```
1384     #[inline]
1385     #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
1386     #[cfg(target_has_atomic = "ptr")]
1387     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1388     pub fn compare_exchange_weak(
1389         &self,
1390         current: *mut T,
1391         new: *mut T,
1392         success: Ordering,
1393         failure: Ordering,
1394     ) -> Result<*mut T, *mut T> {
1395         // SAFETY: This intrinsic is unsafe because it operates on a raw pointer
1396         // but we know for sure that the pointer is valid (we just got it from
1397         // an `UnsafeCell` that we have by reference) and the atomic operation
1398         // itself allows us to safely mutate the `UnsafeCell` contents.
1399         unsafe { atomic_compare_exchange_weak(self.p.get(), current, new, success, failure) }
1400     }
1401
1402     /// Fetches the value, and applies a function to it that returns an optional
1403     /// new value. Returns a `Result` of `Ok(previous_value)` if the function
1404     /// returned `Some(_)`, else `Err(previous_value)`.
1405     ///
1406     /// Note: This may call the function multiple times if the value has been
1407     /// changed from other threads in the meantime, as long as the function
1408     /// returns `Some(_)`, but the function will have been applied only once to
1409     /// the stored value.
1410     ///
1411     /// `fetch_update` takes two [`Ordering`] arguments to describe the memory
1412     /// ordering of this operation. The first describes the required ordering for
1413     /// when the operation finally succeeds while the second describes the
1414     /// required ordering for loads. These correspond to the success and failure
1415     /// orderings of [`AtomicPtr::compare_exchange`] respectively.
1416     ///
1417     /// Using [`Acquire`] as success ordering makes the store part of this
1418     /// operation [`Relaxed`], and using [`Release`] makes the final successful
1419     /// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`],
1420     /// [`Acquire`] or [`Relaxed`].
1421     ///
1422     /// **Note:** This method is only available on platforms that support atomic
1423     /// operations on pointers.
1424     ///
1425     /// # Examples
1426     ///
1427     /// ```rust
1428     /// use std::sync::atomic::{AtomicPtr, Ordering};
1429     ///
1430     /// let ptr: *mut _ = &mut 5;
1431     /// let some_ptr = AtomicPtr::new(ptr);
1432     ///
1433     /// let new: *mut _ = &mut 10;
1434     /// assert_eq!(some_ptr.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(ptr));
1435     /// let result = some_ptr.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| {
1436     ///     if x == ptr {
1437     ///         Some(new)
1438     ///     } else {
1439     ///         None
1440     ///     }
1441     /// });
1442     /// assert_eq!(result, Ok(ptr));
1443     /// assert_eq!(some_ptr.load(Ordering::SeqCst), new);
1444     /// ```
1445     #[inline]
1446     #[stable(feature = "atomic_fetch_update", since = "1.53.0")]
1447     #[cfg(target_has_atomic = "ptr")]
1448     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1449     pub fn fetch_update<F>(
1450         &self,
1451         set_order: Ordering,
1452         fetch_order: Ordering,
1453         mut f: F,
1454     ) -> Result<*mut T, *mut T>
1455     where
1456         F: FnMut(*mut T) -> Option<*mut T>,
1457     {
1458         let mut prev = self.load(fetch_order);
1459         while let Some(next) = f(prev) {
1460             match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
1461                 x @ Ok(_) => return x,
1462                 Err(next_prev) => prev = next_prev,
1463             }
1464         }
1465         Err(prev)
1466     }
1467
1468     /// Offsets the pointer's address by adding `val` (in units of `T`),
1469     /// returning the previous pointer.
1470     ///
1471     /// This is equivalent to using [`wrapping_add`] to atomically perform the
1472     /// equivalent of `ptr = ptr.wrapping_add(val);`.
1473     ///
1474     /// This method operates in units of `T`, which means that it cannot be used
1475     /// to offset the pointer by an amount which is not a multiple of
1476     /// `size_of::<T>()`. This can sometimes be inconvenient, as you may want to
1477     /// work with a deliberately misaligned pointer. In such cases, you may use
1478     /// the [`fetch_byte_add`](Self::fetch_byte_add) method instead.
1479     ///
1480     /// `fetch_ptr_add` takes an [`Ordering`] argument which describes the
1481     /// memory ordering of this operation. All ordering modes are possible. Note
1482     /// that using [`Acquire`] makes the store part of this operation
1483     /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].
1484     ///
1485     /// **Note**: This method is only available on platforms that support atomic
1486     /// operations on [`AtomicPtr`].
1487     ///
1488     /// [`wrapping_add`]: pointer::wrapping_add
1489     ///
1490     /// # Examples
1491     ///
1492     /// ```
1493     /// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
1494     /// use core::sync::atomic::{AtomicPtr, Ordering};
1495     ///
1496     /// let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());
1497     /// assert_eq!(atom.fetch_ptr_add(1, Ordering::Relaxed).addr(), 0);
1498     /// // Note: units of `size_of::<i64>()`.
1499     /// assert_eq!(atom.load(Ordering::Relaxed).addr(), 8);
1500     /// ```
1501     #[inline]
1502     #[cfg(target_has_atomic = "ptr")]
1503     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
1504     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1505     pub fn fetch_ptr_add(&self, val: usize, order: Ordering) -> *mut T {
1506         self.fetch_byte_add(val.wrapping_mul(core::mem::size_of::<T>()), order)
1507     }
1508
1509     /// Offsets the pointer's address by subtracting `val` (in units of `T`),
1510     /// returning the previous pointer.
1511     ///
1512     /// This is equivalent to using [`wrapping_sub`] to atomically perform the
1513     /// equivalent of `ptr = ptr.wrapping_sub(val);`.
1514     ///
1515     /// This method operates in units of `T`, which means that it cannot be used
1516     /// to offset the pointer by an amount which is not a multiple of
1517     /// `size_of::<T>()`. This can sometimes be inconvenient, as you may want to
1518     /// work with a deliberately misaligned pointer. In such cases, you may use
1519     /// the [`fetch_byte_sub`](Self::fetch_byte_sub) method instead.
1520     ///
1521     /// `fetch_ptr_sub` takes an [`Ordering`] argument which describes the memory
1522     /// ordering of this operation. All ordering modes are possible. Note that
1523     /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
1524     /// and using [`Release`] makes the load part [`Relaxed`].
1525     ///
1526     /// **Note**: This method is only available on platforms that support atomic
1527     /// operations on [`AtomicPtr`].
1528     ///
1529     /// [`wrapping_sub`]: pointer::wrapping_sub
1530     ///
1531     /// # Examples
1532     ///
1533     /// ```
1534     /// #![feature(strict_provenance_atomic_ptr)]
1535     /// use core::sync::atomic::{AtomicPtr, Ordering};
1536     ///
1537     /// let array = [1i32, 2i32];
1538     /// let atom = AtomicPtr::new(array.as_ptr().wrapping_add(1) as *mut _);
1539     ///
1540     /// assert!(core::ptr::eq(
1541     ///     atom.fetch_ptr_sub(1, Ordering::Relaxed),
1542     ///     &array[1],
1543     /// ));
1544     /// assert!(core::ptr::eq(atom.load(Ordering::Relaxed), &array[0]));
1545     /// ```
1546     #[inline]
1547     #[cfg(target_has_atomic = "ptr")]
1548     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
1549     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1550     pub fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T {
1551         self.fetch_byte_sub(val.wrapping_mul(core::mem::size_of::<T>()), order)
1552     }
1553
1554     /// Offsets the pointer's address by adding `val` *bytes*, returning the
1555     /// previous pointer.
1556     ///
1557     /// This is equivalent to using [`wrapping_byte_add`] to atomically
1558     /// perform `ptr = ptr.wrapping_byte_add(val)`.
1559     ///
1560     /// `fetch_byte_add` takes an [`Ordering`] argument which describes the
1561     /// memory ordering of this operation. All ordering modes are possible. Note
1562     /// that using [`Acquire`] makes the store part of this operation
1563     /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].
1564     ///
1565     /// **Note**: This method is only available on platforms that support atomic
1566     /// operations on [`AtomicPtr`].
1567     ///
1568     /// [`wrapping_byte_add`]: pointer::wrapping_byte_add
1569     ///
1570     /// # Examples
1571     ///
1572     /// ```
1573     /// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
1574     /// use core::sync::atomic::{AtomicPtr, Ordering};
1575     ///
1576     /// let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());
1577     /// assert_eq!(atom.fetch_byte_add(1, Ordering::Relaxed).addr(), 0);
1578     /// // Note: in units of bytes, not `size_of::<i64>()`.
1579     /// assert_eq!(atom.load(Ordering::Relaxed).addr(), 1);
1580     /// ```
1581     #[inline]
1582     #[cfg(target_has_atomic = "ptr")]
1583     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
1584     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1585     pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T {
1586         // SAFETY: data races are prevented by atomic intrinsics.
1587         unsafe { atomic_add(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
1588     }
1589
1590     /// Offsets the pointer's address by subtracting `val` *bytes*, returning the
1591     /// previous pointer.
1592     ///
1593     /// This is equivalent to using [`wrapping_byte_sub`] to atomically
1594     /// perform `ptr = ptr.wrapping_byte_sub(val)`.
1595     ///
1596     /// `fetch_byte_sub` takes an [`Ordering`] argument which describes the
1597     /// memory ordering of this operation. All ordering modes are possible. Note
1598     /// that using [`Acquire`] makes the store part of this operation
1599     /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].
1600     ///
1601     /// **Note**: This method is only available on platforms that support atomic
1602     /// operations on [`AtomicPtr`].
1603     ///
1604     /// [`wrapping_byte_sub`]: pointer::wrapping_byte_sub
1605     ///
1606     /// # Examples
1607     ///
1608     /// ```
1609     /// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
1610     /// use core::sync::atomic::{AtomicPtr, Ordering};
1611     ///
1612     /// let atom = AtomicPtr::<i64>::new(core::ptr::invalid_mut(1));
1613     /// assert_eq!(atom.fetch_byte_sub(1, Ordering::Relaxed).addr(), 1);
1614     /// assert_eq!(atom.load(Ordering::Relaxed).addr(), 0);
1615     /// ```
1616     #[inline]
1617     #[cfg(target_has_atomic = "ptr")]
1618     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
1619     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1620     pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T {
1621         // SAFETY: data races are prevented by atomic intrinsics.
1622         unsafe { atomic_sub(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
1623     }
1624
1625     /// Performs a bitwise "or" operation on the address of the current pointer,
1626     /// and the argument `val`, and stores a pointer with provenance of the
1627     /// current pointer and the resulting address.
1628     ///
1629     /// This is equivalent equivalent to using [`map_addr`] to atomically
1630     /// perform `ptr = ptr.map_addr(|a| a | val)`. This can be used in tagged
1631     /// pointer schemes to atomically set tag bits.
1632     ///
1633     /// **Caveat**: This operation returns the previous value. To compute the
1634     /// stored value without losing provenance, you may use [`map_addr`]. For
1635     /// example: `a.fetch_or(val).map_addr(|a| a | val)`.
1636     ///
1637     /// `fetch_or` takes an [`Ordering`] argument which describes the memory
1638     /// ordering of this operation. All ordering modes are possible. Note that
1639     /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
1640     /// and using [`Release`] makes the load part [`Relaxed`].
1641     ///
1642     /// **Note**: This method is only available on platforms that support atomic
1643     /// operations on [`AtomicPtr`].
1644     ///
1645     /// This API and its claimed semantics are part of the Strict Provenance
1646     /// experiment, see the [module documentation for `ptr`][crate::ptr] for
1647     /// details.
1648     ///
1649     /// [`map_addr`]: pointer::map_addr
1650     ///
1651     /// # Examples
1652     ///
1653     /// ```
1654     /// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
1655     /// use core::sync::atomic::{AtomicPtr, Ordering};
1656     ///
1657     /// let pointer = &mut 3i64 as *mut i64;
1658     ///
1659     /// let atom = AtomicPtr::<i64>::new(pointer);
1660     /// // Tag the bottom bit of the pointer.
1661     /// assert_eq!(atom.fetch_or(1, Ordering::Relaxed).addr() & 1, 0);
1662     /// // Extract and untag.
1663     /// let tagged = atom.load(Ordering::Relaxed);
1664     /// assert_eq!(tagged.addr() & 1, 1);
1665     /// assert_eq!(tagged.map_addr(|p| p & !1), pointer);
1666     /// ```
1667     #[inline]
1668     #[cfg(target_has_atomic = "ptr")]
1669     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
1670     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1671     pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T {
1672         // SAFETY: data races are prevented by atomic intrinsics.
1673         unsafe { atomic_or(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
1674     }
1675
1676     /// Performs a bitwise "and" operation on the address of the current
1677     /// pointer, and the argument `val`, and stores a pointer with provenance of
1678     /// the current pointer and the resulting address.
1679     ///
1680     /// This is equivalent equivalent to using [`map_addr`] to atomically
1681     /// perform `ptr = ptr.map_addr(|a| a & val)`. This can be used in tagged
1682     /// pointer schemes to atomically unset tag bits.
1683     ///
1684     /// **Caveat**: This operation returns the previous value. To compute the
1685     /// stored value without losing provenance, you may use [`map_addr`]. For
1686     /// example: `a.fetch_and(val).map_addr(|a| a & val)`.
1687     ///
1688     /// `fetch_and` takes an [`Ordering`] argument which describes the memory
1689     /// ordering of this operation. All ordering modes are possible. Note that
1690     /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
1691     /// and using [`Release`] makes the load part [`Relaxed`].
1692     ///
1693     /// **Note**: This method is only available on platforms that support atomic
1694     /// operations on [`AtomicPtr`].
1695     ///
1696     /// This API and its claimed semantics are part of the Strict Provenance
1697     /// experiment, see the [module documentation for `ptr`][crate::ptr] for
1698     /// details.
1699     ///
1700     /// [`map_addr`]: pointer::map_addr
1701     ///
1702     /// # Examples
1703     ///
1704     /// ```
1705     /// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
1706     /// use core::sync::atomic::{AtomicPtr, Ordering};
1707     ///
1708     /// let pointer = &mut 3i64 as *mut i64;
1709     /// // A tagged pointer
1710     /// let atom = AtomicPtr::<i64>::new(pointer.map_addr(|a| a | 1));
1711     /// assert_eq!(atom.fetch_or(1, Ordering::Relaxed).addr() & 1, 1);
1712     /// // Untag, and extract the previously tagged pointer.
1713     /// let untagged = atom.fetch_and(!1, Ordering::Relaxed)
1714     ///     .map_addr(|a| a & !1);
1715     /// assert_eq!(untagged, pointer);
1716     /// ```
1717     #[inline]
1718     #[cfg(target_has_atomic = "ptr")]
1719     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
1720     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1721     pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T {
1722         // SAFETY: data races are prevented by atomic intrinsics.
1723         unsafe { atomic_and(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
1724     }
1725
1726     /// Performs a bitwise "xor" operation on the address of the current
1727     /// pointer, and the argument `val`, and stores a pointer with provenance of
1728     /// the current pointer and the resulting address.
1729     ///
1730     /// This is equivalent equivalent to using [`map_addr`] to atomically
1731     /// perform `ptr = ptr.map_addr(|a| a ^ val)`. This can be used in tagged
1732     /// pointer schemes to atomically toggle tag bits.
1733     ///
1734     /// **Caveat**: This operation returns the previous value. To compute the
1735     /// stored value without losing provenance, you may use [`map_addr`]. For
1736     /// example: `a.fetch_xor(val).map_addr(|a| a ^ val)`.
1737     ///
1738     /// `fetch_xor` takes an [`Ordering`] argument which describes the memory
1739     /// ordering of this operation. All ordering modes are possible. Note that
1740     /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
1741     /// and using [`Release`] makes the load part [`Relaxed`].
1742     ///
1743     /// **Note**: This method is only available on platforms that support atomic
1744     /// operations on [`AtomicPtr`].
1745     ///
1746     /// This API and its claimed semantics are part of the Strict Provenance
1747     /// experiment, see the [module documentation for `ptr`][crate::ptr] for
1748     /// details.
1749     ///
1750     /// [`map_addr`]: pointer::map_addr
1751     ///
1752     /// # Examples
1753     ///
1754     /// ```
1755     /// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
1756     /// use core::sync::atomic::{AtomicPtr, Ordering};
1757     ///
1758     /// let pointer = &mut 3i64 as *mut i64;
1759     /// let atom = AtomicPtr::<i64>::new(pointer);
1760     ///
1761     /// // Toggle a tag bit on the pointer.
1762     /// atom.fetch_xor(1, Ordering::Relaxed);
1763     /// assert_eq!(atom.load(Ordering::Relaxed).addr() & 1, 1);
1764     /// ```
1765     #[inline]
1766     #[cfg(target_has_atomic = "ptr")]
1767     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
1768     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1769     pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T {
1770         // SAFETY: data races are prevented by atomic intrinsics.
1771         unsafe { atomic_xor(self.p.get(), core::ptr::invalid_mut(val), order).cast() }
1772     }
1773 }
1774
1775 #[cfg(target_has_atomic_load_store = "8")]
1776 #[stable(feature = "atomic_bool_from", since = "1.24.0")]
1777 #[rustc_const_unstable(feature = "const_convert", issue = "88674")]
1778 impl const From<bool> for AtomicBool {
1779     /// Converts a `bool` into an `AtomicBool`.
1780     ///
1781     /// # Examples
1782     ///
1783     /// ```
1784     /// use std::sync::atomic::AtomicBool;
1785     /// let atomic_bool = AtomicBool::from(true);
1786     /// assert_eq!(format!("{atomic_bool:?}"), "true")
1787     /// ```
1788     #[inline]
1789     fn from(b: bool) -> Self {
1790         Self::new(b)
1791     }
1792 }
1793
1794 #[cfg(target_has_atomic_load_store = "ptr")]
1795 #[stable(feature = "atomic_from", since = "1.23.0")]
1796 #[rustc_const_unstable(feature = "const_convert", issue = "88674")]
1797 impl<T> const From<*mut T> for AtomicPtr<T> {
1798     /// Converts a `*mut T` into an `AtomicPtr<T>`.
1799     #[inline]
1800     fn from(p: *mut T) -> Self {
1801         Self::new(p)
1802     }
1803 }
1804
1805 #[allow(unused_macros)] // This macro ends up being unused on some architectures.
1806 macro_rules! if_not_8_bit {
1807     (u8, $($tt:tt)*) => { "" };
1808     (i8, $($tt:tt)*) => { "" };
1809     ($_:ident, $($tt:tt)*) => { $($tt)* };
1810 }
1811
1812 #[cfg(target_has_atomic_load_store = "8")]
1813 macro_rules! atomic_int {
1814     ($cfg_cas:meta,
1815      $cfg_align:meta,
1816      $stable:meta,
1817      $stable_cxchg:meta,
1818      $stable_debug:meta,
1819      $stable_access:meta,
1820      $stable_from:meta,
1821      $stable_nand:meta,
1822      $const_stable:meta,
1823      $stable_init_const:meta,
1824      $diagnostic_item:meta,
1825      $s_int_type:literal,
1826      $extra_feature:expr,
1827      $min_fn:ident, $max_fn:ident,
1828      $align:expr,
1829      $atomic_new:expr,
1830      $int_type:ident $atomic_type:ident $atomic_init:ident) => {
1831         /// An integer type which can be safely shared between threads.
1832         ///
1833         /// This type has the same in-memory representation as the underlying
1834         /// integer type, [`
1835         #[doc = $s_int_type]
1836         /// `]. For more about the differences between atomic types and
1837         /// non-atomic types as well as information about the portability of
1838         /// this type, please see the [module-level documentation].
1839         ///
1840         /// **Note:** This type is only available on platforms that support
1841         /// atomic loads and stores of [`
1842         #[doc = $s_int_type]
1843         /// `].
1844         ///
1845         /// [module-level documentation]: crate::sync::atomic
1846         #[$stable]
1847         #[$diagnostic_item]
1848         #[repr(C, align($align))]
1849         pub struct $atomic_type {
1850             v: UnsafeCell<$int_type>,
1851         }
1852
1853         /// An atomic integer initialized to `0`.
1854         #[$stable_init_const]
1855         #[deprecated(
1856             since = "1.34.0",
1857             note = "the `new` function is now preferred",
1858             suggestion = $atomic_new,
1859         )]
1860         pub const $atomic_init: $atomic_type = $atomic_type::new(0);
1861
1862         #[$stable]
1863         #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
1864         impl const Default for $atomic_type {
1865             #[inline]
1866             fn default() -> Self {
1867                 Self::new(Default::default())
1868             }
1869         }
1870
1871         #[$stable_from]
1872         #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
1873         impl const From<$int_type> for $atomic_type {
1874             #[doc = concat!("Converts an `", stringify!($int_type), "` into an `", stringify!($atomic_type), "`.")]
1875             #[inline]
1876             fn from(v: $int_type) -> Self { Self::new(v) }
1877         }
1878
1879         #[$stable_debug]
1880         impl fmt::Debug for $atomic_type {
1881             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1882                 fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
1883             }
1884         }
1885
1886         // Send is implicitly implemented.
1887         #[$stable]
1888         unsafe impl Sync for $atomic_type {}
1889
1890         impl $atomic_type {
1891             /// Creates a new atomic integer.
1892             ///
1893             /// # Examples
1894             ///
1895             /// ```
1896             #[doc = concat!($extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";")]
1897             ///
1898             #[doc = concat!("let atomic_forty_two = ", stringify!($atomic_type), "::new(42);")]
1899             /// ```
1900             #[inline]
1901             #[$stable]
1902             #[$const_stable]
1903             #[must_use]
1904             pub const fn new(v: $int_type) -> Self {
1905                 Self {v: UnsafeCell::new(v)}
1906             }
1907
1908             /// Returns a mutable reference to the underlying integer.
1909             ///
1910             /// This is safe because the mutable reference guarantees that no other threads are
1911             /// concurrently accessing the atomic data.
1912             ///
1913             /// # Examples
1914             ///
1915             /// ```
1916             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
1917             ///
1918             #[doc = concat!("let mut some_var = ", stringify!($atomic_type), "::new(10);")]
1919             /// assert_eq!(*some_var.get_mut(), 10);
1920             /// *some_var.get_mut() = 5;
1921             /// assert_eq!(some_var.load(Ordering::SeqCst), 5);
1922             /// ```
1923             #[inline]
1924             #[$stable_access]
1925             pub fn get_mut(&mut self) -> &mut $int_type {
1926                 self.v.get_mut()
1927             }
1928
1929             #[doc = concat!("Get atomic access to a `&mut ", stringify!($int_type), "`.")]
1930             ///
1931             #[doc = if_not_8_bit! {
1932                 $int_type,
1933                 concat!(
1934                     "**Note:** This function is only available on targets where `",
1935                     stringify!($int_type), "` has an alignment of ", $align, " bytes."
1936                 )
1937             }]
1938             ///
1939             /// # Examples
1940             ///
1941             /// ```
1942             /// #![feature(atomic_from_mut)]
1943             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
1944             ///
1945             /// let mut some_int = 123;
1946             #[doc = concat!("let a = ", stringify!($atomic_type), "::from_mut(&mut some_int);")]
1947             /// a.store(100, Ordering::Relaxed);
1948             /// assert_eq!(some_int, 100);
1949             /// ```
1950             ///
1951             #[inline]
1952             #[$cfg_align]
1953             #[unstable(feature = "atomic_from_mut", issue = "76314")]
1954             pub fn from_mut(v: &mut $int_type) -> &mut Self {
1955                 use crate::mem::align_of;
1956                 let [] = [(); align_of::<Self>() - align_of::<$int_type>()];
1957                 // SAFETY:
1958                 //  - the mutable reference guarantees unique ownership.
1959                 //  - the alignment of `$int_type` and `Self` is the
1960                 //    same, as promised by $cfg_align and verified above.
1961                 unsafe { &mut *(v as *mut $int_type as *mut Self) }
1962             }
1963
1964             #[doc = concat!("Get non-atomic access to a `&mut [", stringify!($atomic_type), "]` slice")]
1965             ///
1966             /// This is safe because the mutable reference guarantees that no other threads are
1967             /// concurrently accessing the atomic data.
1968             ///
1969             /// # Examples
1970             ///
1971             /// ```
1972             /// #![feature(atomic_from_mut, inline_const)]
1973             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
1974             ///
1975             #[doc = concat!("let mut some_ints = [const { ", stringify!($atomic_type), "::new(0) }; 10];")]
1976             ///
1977             #[doc = concat!("let view: &mut [", stringify!($int_type), "] = ", stringify!($atomic_type), "::get_mut_slice(&mut some_ints);")]
1978             /// assert_eq!(view, [0; 10]);
1979             /// view
1980             ///     .iter_mut()
1981             ///     .enumerate()
1982             ///     .for_each(|(idx, int)| *int = idx as _);
1983             ///
1984             /// std::thread::scope(|s| {
1985             ///     some_ints
1986             ///         .iter()
1987             ///         .enumerate()
1988             ///         .for_each(|(idx, int)| {
1989             ///             s.spawn(move || assert_eq!(int.load(Ordering::Relaxed), idx as _));
1990             ///         })
1991             /// });
1992             /// ```
1993             #[inline]
1994             #[unstable(feature = "atomic_from_mut", issue = "76314")]
1995             pub fn get_mut_slice(this: &mut [Self]) -> &mut [$int_type] {
1996                 // SAFETY: the mutable reference guarantees unique ownership.
1997                 unsafe { &mut *(this as *mut [Self] as *mut [$int_type]) }
1998             }
1999
2000             #[doc = concat!("Get atomic access to a `&mut [", stringify!($int_type), "]` slice.")]
2001             ///
2002             /// # Examples
2003             ///
2004             /// ```
2005             /// #![feature(atomic_from_mut)]
2006             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2007             ///
2008             /// let mut some_ints = [0; 10];
2009             #[doc = concat!("let a = &*", stringify!($atomic_type), "::from_mut_slice(&mut some_ints);")]
2010             /// std::thread::scope(|s| {
2011             ///     for i in 0..a.len() {
2012             ///         s.spawn(move || a[i].store(i as _, Ordering::Relaxed));
2013             ///     }
2014             /// });
2015             /// for (i, n) in some_ints.into_iter().enumerate() {
2016             ///     assert_eq!(i, n as usize);
2017             /// }
2018             /// ```
2019             #[inline]
2020             #[$cfg_align]
2021             #[unstable(feature = "atomic_from_mut", issue = "76314")]
2022             pub fn from_mut_slice(v: &mut [$int_type]) -> &mut [Self] {
2023                 use crate::mem::align_of;
2024                 let [] = [(); align_of::<Self>() - align_of::<$int_type>()];
2025                 // SAFETY:
2026                 //  - the mutable reference guarantees unique ownership.
2027                 //  - the alignment of `$int_type` and `Self` is the
2028                 //    same, as promised by $cfg_align and verified above.
2029                 unsafe { &mut *(v as *mut [$int_type] as *mut [Self]) }
2030             }
2031
2032             /// Consumes the atomic and returns the contained value.
2033             ///
2034             /// This is safe because passing `self` by value guarantees that no other threads are
2035             /// concurrently accessing the atomic data.
2036             ///
2037             /// # Examples
2038             ///
2039             /// ```
2040             #[doc = concat!($extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";")]
2041             ///
2042             #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
2043             /// assert_eq!(some_var.into_inner(), 5);
2044             /// ```
2045             #[inline]
2046             #[$stable_access]
2047             #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")]
2048             pub const fn into_inner(self) -> $int_type {
2049                 self.v.into_inner()
2050             }
2051
2052             /// Loads a value from the atomic integer.
2053             ///
2054             /// `load` takes an [`Ordering`] argument which describes the memory ordering of this operation.
2055             /// Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
2056             ///
2057             /// # Panics
2058             ///
2059             /// Panics if `order` is [`Release`] or [`AcqRel`].
2060             ///
2061             /// # Examples
2062             ///
2063             /// ```
2064             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2065             ///
2066             #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
2067             ///
2068             /// assert_eq!(some_var.load(Ordering::Relaxed), 5);
2069             /// ```
2070             #[inline]
2071             #[$stable]
2072             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2073             pub fn load(&self, order: Ordering) -> $int_type {
2074                 // SAFETY: data races are prevented by atomic intrinsics.
2075                 unsafe { atomic_load(self.v.get(), order) }
2076             }
2077
2078             /// Stores a value into the atomic integer.
2079             ///
2080             /// `store` takes an [`Ordering`] argument which describes the memory ordering of this operation.
2081             ///  Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
2082             ///
2083             /// # Panics
2084             ///
2085             /// Panics if `order` is [`Acquire`] or [`AcqRel`].
2086             ///
2087             /// # Examples
2088             ///
2089             /// ```
2090             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2091             ///
2092             #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
2093             ///
2094             /// some_var.store(10, Ordering::Relaxed);
2095             /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
2096             /// ```
2097             #[inline]
2098             #[$stable]
2099             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2100             pub fn store(&self, val: $int_type, order: Ordering) {
2101                 // SAFETY: data races are prevented by atomic intrinsics.
2102                 unsafe { atomic_store(self.v.get(), val, order); }
2103             }
2104
2105             /// Stores a value into the atomic integer, returning the previous value.
2106             ///
2107             /// `swap` takes an [`Ordering`] argument which describes the memory ordering
2108             /// of this operation. All ordering modes are possible. Note that using
2109             /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2110             /// using [`Release`] makes the load part [`Relaxed`].
2111             ///
2112             /// **Note**: This method is only available on platforms that support atomic operations on
2113             #[doc = concat!("[`", $s_int_type, "`].")]
2114             ///
2115             /// # Examples
2116             ///
2117             /// ```
2118             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2119             ///
2120             #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
2121             ///
2122             /// assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
2123             /// ```
2124             #[inline]
2125             #[$stable]
2126             #[$cfg_cas]
2127             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2128             pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
2129                 // SAFETY: data races are prevented by atomic intrinsics.
2130                 unsafe { atomic_swap(self.v.get(), val, order) }
2131             }
2132
2133             /// Stores a value into the atomic integer if the current value is the same as
2134             /// the `current` value.
2135             ///
2136             /// The return value is always the previous value. If it is equal to `current`, then the
2137             /// value was updated.
2138             ///
2139             /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
2140             /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
2141             /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
2142             /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
2143             /// happens, and using [`Release`] makes the load part [`Relaxed`].
2144             ///
2145             /// **Note**: This method is only available on platforms that support atomic operations on
2146             #[doc = concat!("[`", $s_int_type, "`].")]
2147             ///
2148             /// # Migrating to `compare_exchange` and `compare_exchange_weak`
2149             ///
2150             /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
2151             /// memory orderings:
2152             ///
2153             /// Original | Success | Failure
2154             /// -------- | ------- | -------
2155             /// Relaxed  | Relaxed | Relaxed
2156             /// Acquire  | Acquire | Acquire
2157             /// Release  | Release | Relaxed
2158             /// AcqRel   | AcqRel  | Acquire
2159             /// SeqCst   | SeqCst  | SeqCst
2160             ///
2161             /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
2162             /// which allows the compiler to generate better assembly code when the compare and swap
2163             /// is used in a loop.
2164             ///
2165             /// # Examples
2166             ///
2167             /// ```
2168             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2169             ///
2170             #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
2171             ///
2172             /// assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5);
2173             /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
2174             ///
2175             /// assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10);
2176             /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
2177             /// ```
2178             #[inline]
2179             #[$stable]
2180             #[deprecated(
2181                 since = "1.50.0",
2182                 note = "Use `compare_exchange` or `compare_exchange_weak` instead")
2183             ]
2184             #[$cfg_cas]
2185             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2186             pub fn compare_and_swap(&self,
2187                                     current: $int_type,
2188                                     new: $int_type,
2189                                     order: Ordering) -> $int_type {
2190                 match self.compare_exchange(current,
2191                                             new,
2192                                             order,
2193                                             strongest_failure_ordering(order)) {
2194                     Ok(x) => x,
2195                     Err(x) => x,
2196                 }
2197             }
2198
2199             /// Stores a value into the atomic integer if the current value is the same as
2200             /// the `current` value.
2201             ///
2202             /// The return value is a result indicating whether the new value was written and
2203             /// containing the previous value. On success this value is guaranteed to be equal to
2204             /// `current`.
2205             ///
2206             /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
2207             /// ordering of this operation. `success` describes the required ordering for the
2208             /// read-modify-write operation that takes place if the comparison with `current` succeeds.
2209             /// `failure` describes the required ordering for the load operation that takes place when
2210             /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
2211             /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
2212             /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
2213             ///
2214             /// **Note**: This method is only available on platforms that support atomic operations on
2215             #[doc = concat!("[`", $s_int_type, "`].")]
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_exchange(5, 10,
2225             ///                                      Ordering::Acquire,
2226             ///                                      Ordering::Relaxed),
2227             ///            Ok(5));
2228             /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
2229             ///
2230             /// assert_eq!(some_var.compare_exchange(6, 12,
2231             ///                                      Ordering::SeqCst,
2232             ///                                      Ordering::Acquire),
2233             ///            Err(10));
2234             /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
2235             /// ```
2236             #[inline]
2237             #[$stable_cxchg]
2238             #[$cfg_cas]
2239             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2240             pub fn compare_exchange(&self,
2241                                     current: $int_type,
2242                                     new: $int_type,
2243                                     success: Ordering,
2244                                     failure: Ordering) -> Result<$int_type, $int_type> {
2245                 // SAFETY: data races are prevented by atomic intrinsics.
2246                 unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) }
2247             }
2248
2249             /// Stores a value into the atomic integer if the current value is the same as
2250             /// the `current` value.
2251             ///
2252             #[doc = concat!("Unlike [`", stringify!($atomic_type), "::compare_exchange`],")]
2253             /// this function is allowed to spuriously fail even
2254             /// when the comparison succeeds, which can result in more efficient code on some
2255             /// platforms. The return value is a result indicating whether the new value was
2256             /// written and containing the previous value.
2257             ///
2258             /// `compare_exchange_weak` 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 val = ", stringify!($atomic_type), "::new(4);")]
2275             ///
2276             /// let mut old = val.load(Ordering::Relaxed);
2277             /// loop {
2278             ///     let new = old * 2;
2279             ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
2280             ///         Ok(_) => break,
2281             ///         Err(x) => old = x,
2282             ///     }
2283             /// }
2284             /// ```
2285             #[inline]
2286             #[$stable_cxchg]
2287             #[$cfg_cas]
2288             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2289             pub fn compare_exchange_weak(&self,
2290                                          current: $int_type,
2291                                          new: $int_type,
2292                                          success: Ordering,
2293                                          failure: Ordering) -> Result<$int_type, $int_type> {
2294                 // SAFETY: data races are prevented by atomic intrinsics.
2295                 unsafe {
2296                     atomic_compare_exchange_weak(self.v.get(), current, new, success, failure)
2297                 }
2298             }
2299
2300             /// Adds to the current value, returning the previous value.
2301             ///
2302             /// This operation wraps around on overflow.
2303             ///
2304             /// `fetch_add` takes an [`Ordering`] argument which describes the memory ordering
2305             /// of this operation. All ordering modes are possible. Note that using
2306             /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2307             /// using [`Release`] makes the load part [`Relaxed`].
2308             ///
2309             /// **Note**: This method is only available on platforms that support atomic operations on
2310             #[doc = concat!("[`", $s_int_type, "`].")]
2311             ///
2312             /// # Examples
2313             ///
2314             /// ```
2315             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2316             ///
2317             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0);")]
2318             /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
2319             /// assert_eq!(foo.load(Ordering::SeqCst), 10);
2320             /// ```
2321             #[inline]
2322             #[$stable]
2323             #[$cfg_cas]
2324             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2325             pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
2326                 // SAFETY: data races are prevented by atomic intrinsics.
2327                 unsafe { atomic_add(self.v.get(), val, order) }
2328             }
2329
2330             /// Subtracts from the current value, returning the previous value.
2331             ///
2332             /// This operation wraps around on overflow.
2333             ///
2334             /// `fetch_sub` takes an [`Ordering`] argument which describes the memory ordering
2335             /// of this operation. All ordering modes are possible. Note that using
2336             /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2337             /// using [`Release`] makes the load part [`Relaxed`].
2338             ///
2339             /// **Note**: This method is only available on platforms that support atomic operations on
2340             #[doc = concat!("[`", $s_int_type, "`].")]
2341             ///
2342             /// # Examples
2343             ///
2344             /// ```
2345             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2346             ///
2347             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(20);")]
2348             /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);
2349             /// assert_eq!(foo.load(Ordering::SeqCst), 10);
2350             /// ```
2351             #[inline]
2352             #[$stable]
2353             #[$cfg_cas]
2354             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2355             pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
2356                 // SAFETY: data races are prevented by atomic intrinsics.
2357                 unsafe { atomic_sub(self.v.get(), val, order) }
2358             }
2359
2360             /// Bitwise "and" with the current value.
2361             ///
2362             /// Performs a bitwise "and" operation on the current value and the argument `val`, and
2363             /// sets the new value to the result.
2364             ///
2365             /// Returns the previous value.
2366             ///
2367             /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
2368             /// of this operation. All ordering modes are possible. Note that using
2369             /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2370             /// using [`Release`] makes the load part [`Relaxed`].
2371             ///
2372             /// **Note**: This method is only available on platforms that support atomic operations on
2373             #[doc = concat!("[`", $s_int_type, "`].")]
2374             ///
2375             /// # Examples
2376             ///
2377             /// ```
2378             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2379             ///
2380             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0b101101);")]
2381             /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
2382             /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
2383             /// ```
2384             #[inline]
2385             #[$stable]
2386             #[$cfg_cas]
2387             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2388             pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
2389                 // SAFETY: data races are prevented by atomic intrinsics.
2390                 unsafe { atomic_and(self.v.get(), val, order) }
2391             }
2392
2393             /// Bitwise "nand" with the current value.
2394             ///
2395             /// Performs a bitwise "nand" operation on the current value and the argument `val`, and
2396             /// sets the new value to the result.
2397             ///
2398             /// Returns the previous value.
2399             ///
2400             /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
2401             /// of this operation. All ordering modes are possible. Note that using
2402             /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2403             /// using [`Release`] makes the load part [`Relaxed`].
2404             ///
2405             /// **Note**: This method is only available on platforms that support atomic operations on
2406             #[doc = concat!("[`", $s_int_type, "`].")]
2407             ///
2408             /// # Examples
2409             ///
2410             /// ```
2411             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2412             ///
2413             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0x13);")]
2414             /// assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);
2415             /// assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
2416             /// ```
2417             #[inline]
2418             #[$stable_nand]
2419             #[$cfg_cas]
2420             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2421             pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
2422                 // SAFETY: data races are prevented by atomic intrinsics.
2423                 unsafe { atomic_nand(self.v.get(), val, order) }
2424             }
2425
2426             /// Bitwise "or" with the current value.
2427             ///
2428             /// Performs a bitwise "or" operation on the current value and the argument `val`, and
2429             /// sets the new value to the result.
2430             ///
2431             /// Returns the previous value.
2432             ///
2433             /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
2434             /// of this operation. All ordering modes are possible. Note that using
2435             /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2436             /// using [`Release`] makes the load part [`Relaxed`].
2437             ///
2438             /// **Note**: This method is only available on platforms that support atomic operations on
2439             #[doc = concat!("[`", $s_int_type, "`].")]
2440             ///
2441             /// # Examples
2442             ///
2443             /// ```
2444             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2445             ///
2446             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0b101101);")]
2447             /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
2448             /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
2449             /// ```
2450             #[inline]
2451             #[$stable]
2452             #[$cfg_cas]
2453             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2454             pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
2455                 // SAFETY: data races are prevented by atomic intrinsics.
2456                 unsafe { atomic_or(self.v.get(), val, order) }
2457             }
2458
2459             /// Bitwise "xor" with the current value.
2460             ///
2461             /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
2462             /// sets the new value to the result.
2463             ///
2464             /// Returns the previous value.
2465             ///
2466             /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
2467             /// of this operation. All ordering modes are possible. Note that using
2468             /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2469             /// using [`Release`] makes the load part [`Relaxed`].
2470             ///
2471             /// **Note**: This method is only available on platforms that support atomic operations on
2472             #[doc = concat!("[`", $s_int_type, "`].")]
2473             ///
2474             /// # Examples
2475             ///
2476             /// ```
2477             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2478             ///
2479             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0b101101);")]
2480             /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
2481             /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
2482             /// ```
2483             #[inline]
2484             #[$stable]
2485             #[$cfg_cas]
2486             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2487             pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
2488                 // SAFETY: data races are prevented by atomic intrinsics.
2489                 unsafe { atomic_xor(self.v.get(), val, order) }
2490             }
2491
2492             /// Fetches the value, and applies a function to it that returns an optional
2493             /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else
2494             /// `Err(previous_value)`.
2495             ///
2496             /// Note: This may call the function multiple times if the value has been changed from other threads in
2497             /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied
2498             /// only once to the stored value.
2499             ///
2500             /// `fetch_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
2501             /// The first describes the required ordering for when the operation finally succeeds while the second
2502             /// describes the required ordering for loads. These correspond to the success and failure orderings of
2503             #[doc = concat!("[`", stringify!($atomic_type), "::compare_exchange`]")]
2504             /// respectively.
2505             ///
2506             /// Using [`Acquire`] as success ordering makes the store part
2507             /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
2508             /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
2509             ///
2510             /// **Note**: This method is only available on platforms that support atomic operations on
2511             #[doc = concat!("[`", $s_int_type, "`].")]
2512             ///
2513             /// # Examples
2514             ///
2515             /// ```rust
2516             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2517             ///
2518             #[doc = concat!("let x = ", stringify!($atomic_type), "::new(7);")]
2519             /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));
2520             /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7));
2521             /// assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8));
2522             /// assert_eq!(x.load(Ordering::SeqCst), 9);
2523             /// ```
2524             #[inline]
2525             #[stable(feature = "no_more_cas", since = "1.45.0")]
2526             #[$cfg_cas]
2527             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2528             pub fn fetch_update<F>(&self,
2529                                    set_order: Ordering,
2530                                    fetch_order: Ordering,
2531                                    mut f: F) -> Result<$int_type, $int_type>
2532             where F: FnMut($int_type) -> Option<$int_type> {
2533                 let mut prev = self.load(fetch_order);
2534                 while let Some(next) = f(prev) {
2535                     match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
2536                         x @ Ok(_) => return x,
2537                         Err(next_prev) => prev = next_prev
2538                     }
2539                 }
2540                 Err(prev)
2541             }
2542
2543             /// Maximum with the current value.
2544             ///
2545             /// Finds the maximum of the current value and the argument `val`, and
2546             /// sets the new value to the result.
2547             ///
2548             /// Returns the previous value.
2549             ///
2550             /// `fetch_max` takes an [`Ordering`] argument which describes the memory ordering
2551             /// of this operation. All ordering modes are possible. Note that using
2552             /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2553             /// using [`Release`] makes the load part [`Relaxed`].
2554             ///
2555             /// **Note**: This method is only available on platforms that support atomic operations on
2556             #[doc = concat!("[`", $s_int_type, "`].")]
2557             ///
2558             /// # Examples
2559             ///
2560             /// ```
2561             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2562             ///
2563             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
2564             /// assert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23);
2565             /// assert_eq!(foo.load(Ordering::SeqCst), 42);
2566             /// ```
2567             ///
2568             /// If you want to obtain the maximum value in one step, you can use the following:
2569             ///
2570             /// ```
2571             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2572             ///
2573             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
2574             /// let bar = 42;
2575             /// let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar);
2576             /// assert!(max_foo == 42);
2577             /// ```
2578             #[inline]
2579             #[stable(feature = "atomic_min_max", since = "1.45.0")]
2580             #[$cfg_cas]
2581             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2582             pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {
2583                 // SAFETY: data races are prevented by atomic intrinsics.
2584                 unsafe { $max_fn(self.v.get(), val, order) }
2585             }
2586
2587             /// Minimum with the current value.
2588             ///
2589             /// Finds the minimum of the current value and the argument `val`, and
2590             /// sets the new value to the result.
2591             ///
2592             /// Returns the previous value.
2593             ///
2594             /// `fetch_min` takes an [`Ordering`] argument which describes the memory ordering
2595             /// of this operation. All ordering modes are possible. Note that using
2596             /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2597             /// using [`Release`] makes the load part [`Relaxed`].
2598             ///
2599             /// **Note**: This method is only available on platforms that support atomic operations on
2600             #[doc = concat!("[`", $s_int_type, "`].")]
2601             ///
2602             /// # Examples
2603             ///
2604             /// ```
2605             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2606             ///
2607             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
2608             /// assert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23);
2609             /// assert_eq!(foo.load(Ordering::Relaxed), 23);
2610             /// assert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23);
2611             /// assert_eq!(foo.load(Ordering::Relaxed), 22);
2612             /// ```
2613             ///
2614             /// If you want to obtain the minimum value in one step, you can use the following:
2615             ///
2616             /// ```
2617             #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2618             ///
2619             #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
2620             /// let bar = 12;
2621             /// let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar);
2622             /// assert_eq!(min_foo, 12);
2623             /// ```
2624             #[inline]
2625             #[stable(feature = "atomic_min_max", since = "1.45.0")]
2626             #[$cfg_cas]
2627             #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2628             pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {
2629                 // SAFETY: data races are prevented by atomic intrinsics.
2630                 unsafe { $min_fn(self.v.get(), val, order) }
2631             }
2632
2633             /// Returns a mutable pointer to the underlying integer.
2634             ///
2635             /// Doing non-atomic reads and writes on the resulting integer can be a data race.
2636             /// This method is mostly useful for FFI, where the function signature may use
2637             #[doc = concat!("`*mut ", stringify!($int_type), "` instead of `&", stringify!($atomic_type), "`.")]
2638             ///
2639             /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
2640             /// atomic types work with interior mutability. All modifications of an atomic change the value
2641             /// through a shared reference, and can do so safely as long as they use atomic operations. Any
2642             /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the same
2643             /// restriction: operations on it must be atomic.
2644             ///
2645             /// # Examples
2646             ///
2647             /// ```ignore (extern-declaration)
2648             /// # fn main() {
2649             #[doc = concat!($extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";")]
2650             ///
2651             /// extern "C" {
2652             #[doc = concat!("    fn my_atomic_op(arg: *mut ", stringify!($int_type), ");")]
2653             /// }
2654             ///
2655             #[doc = concat!("let mut atomic = ", stringify!($atomic_type), "::new(1);")]
2656             ///
2657             // SAFETY: Safe as long as `my_atomic_op` is atomic.
2658             /// unsafe {
2659             ///     my_atomic_op(atomic.as_mut_ptr());
2660             /// }
2661             /// # }
2662             /// ```
2663             #[inline]
2664             #[unstable(feature = "atomic_mut_ptr",
2665                    reason = "recently added",
2666                    issue = "66893")]
2667             pub fn as_mut_ptr(&self) -> *mut $int_type {
2668                 self.v.get()
2669             }
2670         }
2671     }
2672 }
2673
2674 #[cfg(target_has_atomic_load_store = "8")]
2675 atomic_int! {
2676     cfg(target_has_atomic = "8"),
2677     cfg(target_has_atomic_equal_alignment = "8"),
2678     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2679     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2680     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2681     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2682     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2683     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2684     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2685     unstable(feature = "integer_atomics", issue = "99069"),
2686     cfg_attr(not(test), rustc_diagnostic_item = "AtomicI8"),
2687     "i8",
2688     "",
2689     atomic_min, atomic_max,
2690     1,
2691     "AtomicI8::new(0)",
2692     i8 AtomicI8 ATOMIC_I8_INIT
2693 }
2694 #[cfg(target_has_atomic_load_store = "8")]
2695 atomic_int! {
2696     cfg(target_has_atomic = "8"),
2697     cfg(target_has_atomic_equal_alignment = "8"),
2698     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2699     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2700     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2701     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2702     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2703     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2704     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2705     unstable(feature = "integer_atomics", issue = "99069"),
2706     cfg_attr(not(test), rustc_diagnostic_item = "AtomicU8"),
2707     "u8",
2708     "",
2709     atomic_umin, atomic_umax,
2710     1,
2711     "AtomicU8::new(0)",
2712     u8 AtomicU8 ATOMIC_U8_INIT
2713 }
2714 #[cfg(target_has_atomic_load_store = "16")]
2715 atomic_int! {
2716     cfg(target_has_atomic = "16"),
2717     cfg(target_has_atomic_equal_alignment = "16"),
2718     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2719     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2720     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2721     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2722     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2723     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2724     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2725     unstable(feature = "integer_atomics", issue = "99069"),
2726     cfg_attr(not(test), rustc_diagnostic_item = "AtomicI16"),
2727     "i16",
2728     "",
2729     atomic_min, atomic_max,
2730     2,
2731     "AtomicI16::new(0)",
2732     i16 AtomicI16 ATOMIC_I16_INIT
2733 }
2734 #[cfg(target_has_atomic_load_store = "16")]
2735 atomic_int! {
2736     cfg(target_has_atomic = "16"),
2737     cfg(target_has_atomic_equal_alignment = "16"),
2738     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2739     stable(feature = "integer_atomics_stable", since = "1.34.0"),
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     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2745     unstable(feature = "integer_atomics", issue = "99069"),
2746     cfg_attr(not(test), rustc_diagnostic_item = "AtomicU16"),
2747     "u16",
2748     "",
2749     atomic_umin, atomic_umax,
2750     2,
2751     "AtomicU16::new(0)",
2752     u16 AtomicU16 ATOMIC_U16_INIT
2753 }
2754 #[cfg(target_has_atomic_load_store = "32")]
2755 atomic_int! {
2756     cfg(target_has_atomic = "32"),
2757     cfg(target_has_atomic_equal_alignment = "32"),
2758     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2759     stable(feature = "integer_atomics_stable", since = "1.34.0"),
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     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2765     unstable(feature = "integer_atomics", issue = "99069"),
2766     cfg_attr(not(test), rustc_diagnostic_item = "AtomicI32"),
2767     "i32",
2768     "",
2769     atomic_min, atomic_max,
2770     4,
2771     "AtomicI32::new(0)",
2772     i32 AtomicI32 ATOMIC_I32_INIT
2773 }
2774 #[cfg(target_has_atomic_load_store = "32")]
2775 atomic_int! {
2776     cfg(target_has_atomic = "32"),
2777     cfg(target_has_atomic_equal_alignment = "32"),
2778     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2779     stable(feature = "integer_atomics_stable", since = "1.34.0"),
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     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2785     unstable(feature = "integer_atomics", issue = "99069"),
2786     cfg_attr(not(test), rustc_diagnostic_item = "AtomicU32"),
2787     "u32",
2788     "",
2789     atomic_umin, atomic_umax,
2790     4,
2791     "AtomicU32::new(0)",
2792     u32 AtomicU32 ATOMIC_U32_INIT
2793 }
2794 #[cfg(target_has_atomic_load_store = "64")]
2795 atomic_int! {
2796     cfg(target_has_atomic = "64"),
2797     cfg(target_has_atomic_equal_alignment = "64"),
2798     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2799     stable(feature = "integer_atomics_stable", since = "1.34.0"),
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     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2805     unstable(feature = "integer_atomics", issue = "99069"),
2806     cfg_attr(not(test), rustc_diagnostic_item = "AtomicI64"),
2807     "i64",
2808     "",
2809     atomic_min, atomic_max,
2810     8,
2811     "AtomicI64::new(0)",
2812     i64 AtomicI64 ATOMIC_I64_INIT
2813 }
2814 #[cfg(target_has_atomic_load_store = "64")]
2815 atomic_int! {
2816     cfg(target_has_atomic = "64"),
2817     cfg(target_has_atomic_equal_alignment = "64"),
2818     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2819     stable(feature = "integer_atomics_stable", since = "1.34.0"),
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     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2825     unstable(feature = "integer_atomics", issue = "99069"),
2826     cfg_attr(not(test), rustc_diagnostic_item = "AtomicU64"),
2827     "u64",
2828     "",
2829     atomic_umin, atomic_umax,
2830     8,
2831     "AtomicU64::new(0)",
2832     u64 AtomicU64 ATOMIC_U64_INIT
2833 }
2834 #[cfg(target_has_atomic_load_store = "128")]
2835 atomic_int! {
2836     cfg(target_has_atomic = "128"),
2837     cfg(target_has_atomic_equal_alignment = "128"),
2838     unstable(feature = "integer_atomics", issue = "99069"),
2839     unstable(feature = "integer_atomics", issue = "99069"),
2840     unstable(feature = "integer_atomics", issue = "99069"),
2841     unstable(feature = "integer_atomics", issue = "99069"),
2842     unstable(feature = "integer_atomics", issue = "99069"),
2843     unstable(feature = "integer_atomics", issue = "99069"),
2844     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2845     unstable(feature = "integer_atomics", issue = "99069"),
2846     cfg_attr(not(test), rustc_diagnostic_item = "AtomicI128"),
2847     "i128",
2848     "#![feature(integer_atomics)]\n\n",
2849     atomic_min, atomic_max,
2850     16,
2851     "AtomicI128::new(0)",
2852     i128 AtomicI128 ATOMIC_I128_INIT
2853 }
2854 #[cfg(target_has_atomic_load_store = "128")]
2855 atomic_int! {
2856     cfg(target_has_atomic = "128"),
2857     cfg(target_has_atomic_equal_alignment = "128"),
2858     unstable(feature = "integer_atomics", issue = "99069"),
2859     unstable(feature = "integer_atomics", issue = "99069"),
2860     unstable(feature = "integer_atomics", issue = "99069"),
2861     unstable(feature = "integer_atomics", issue = "99069"),
2862     unstable(feature = "integer_atomics", issue = "99069"),
2863     unstable(feature = "integer_atomics", issue = "99069"),
2864     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2865     unstable(feature = "integer_atomics", issue = "99069"),
2866     cfg_attr(not(test), rustc_diagnostic_item = "AtomicU128"),
2867     "u128",
2868     "#![feature(integer_atomics)]\n\n",
2869     atomic_umin, atomic_umax,
2870     16,
2871     "AtomicU128::new(0)",
2872     u128 AtomicU128 ATOMIC_U128_INIT
2873 }
2874
2875 macro_rules! atomic_int_ptr_sized {
2876     ( $($target_pointer_width:literal $align:literal)* ) => { $(
2877         #[cfg(target_has_atomic_load_store = "ptr")]
2878         #[cfg(target_pointer_width = $target_pointer_width)]
2879         atomic_int! {
2880             cfg(target_has_atomic = "ptr"),
2881             cfg(target_has_atomic_equal_alignment = "ptr"),
2882             stable(feature = "rust1", since = "1.0.0"),
2883             stable(feature = "extended_compare_and_swap", since = "1.10.0"),
2884             stable(feature = "atomic_debug", since = "1.3.0"),
2885             stable(feature = "atomic_access", since = "1.15.0"),
2886             stable(feature = "atomic_from", since = "1.23.0"),
2887             stable(feature = "atomic_nand", since = "1.27.0"),
2888             rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"),
2889             stable(feature = "rust1", since = "1.0.0"),
2890             cfg_attr(not(test), rustc_diagnostic_item = "AtomicIsize"),
2891             "isize",
2892             "",
2893             atomic_min, atomic_max,
2894             $align,
2895             "AtomicIsize::new(0)",
2896             isize AtomicIsize ATOMIC_ISIZE_INIT
2897         }
2898         #[cfg(target_has_atomic_load_store = "ptr")]
2899         #[cfg(target_pointer_width = $target_pointer_width)]
2900         atomic_int! {
2901             cfg(target_has_atomic = "ptr"),
2902             cfg(target_has_atomic_equal_alignment = "ptr"),
2903             stable(feature = "rust1", since = "1.0.0"),
2904             stable(feature = "extended_compare_and_swap", since = "1.10.0"),
2905             stable(feature = "atomic_debug", since = "1.3.0"),
2906             stable(feature = "atomic_access", since = "1.15.0"),
2907             stable(feature = "atomic_from", since = "1.23.0"),
2908             stable(feature = "atomic_nand", since = "1.27.0"),
2909             rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"),
2910             stable(feature = "rust1", since = "1.0.0"),
2911             cfg_attr(not(test), rustc_diagnostic_item = "AtomicUsize"),
2912             "usize",
2913             "",
2914             atomic_umin, atomic_umax,
2915             $align,
2916             "AtomicUsize::new(0)",
2917             usize AtomicUsize ATOMIC_USIZE_INIT
2918         }
2919     )* };
2920 }
2921
2922 atomic_int_ptr_sized! {
2923     "16" 2
2924     "32" 4
2925     "64" 8
2926 }
2927
2928 #[inline]
2929 #[cfg(target_has_atomic = "8")]
2930 fn strongest_failure_ordering(order: Ordering) -> Ordering {
2931     match order {
2932         Release => Relaxed,
2933         Relaxed => Relaxed,
2934         SeqCst => SeqCst,
2935         Acquire => Acquire,
2936         AcqRel => Acquire,
2937     }
2938 }
2939
2940 #[inline]
2941 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2942 unsafe fn atomic_store<T: Copy>(dst: *mut T, val: T, order: Ordering) {
2943     // SAFETY: the caller must uphold the safety contract for `atomic_store`.
2944     unsafe {
2945         match order {
2946             Relaxed => intrinsics::atomic_store_relaxed(dst, val),
2947             Release => intrinsics::atomic_store_release(dst, val),
2948             SeqCst => intrinsics::atomic_store_seqcst(dst, val),
2949             Acquire => panic!("there is no such thing as an acquire store"),
2950             AcqRel => panic!("there is no such thing as an acquire-release store"),
2951         }
2952     }
2953 }
2954
2955 #[inline]
2956 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2957 unsafe fn atomic_load<T: Copy>(dst: *const T, order: Ordering) -> T {
2958     // SAFETY: the caller must uphold the safety contract for `atomic_load`.
2959     unsafe {
2960         match order {
2961             Relaxed => intrinsics::atomic_load_relaxed(dst),
2962             Acquire => intrinsics::atomic_load_acquire(dst),
2963             SeqCst => intrinsics::atomic_load_seqcst(dst),
2964             Release => panic!("there is no such thing as a release load"),
2965             AcqRel => panic!("there is no such thing as an acquire-release load"),
2966         }
2967     }
2968 }
2969
2970 #[inline]
2971 #[cfg(target_has_atomic = "8")]
2972 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2973 unsafe fn atomic_swap<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
2974     // SAFETY: the caller must uphold the safety contract for `atomic_swap`.
2975     unsafe {
2976         match order {
2977             Relaxed => intrinsics::atomic_xchg_relaxed(dst, val),
2978             Acquire => intrinsics::atomic_xchg_acquire(dst, val),
2979             Release => intrinsics::atomic_xchg_release(dst, val),
2980             AcqRel => intrinsics::atomic_xchg_acqrel(dst, val),
2981             SeqCst => intrinsics::atomic_xchg_seqcst(dst, val),
2982         }
2983     }
2984 }
2985
2986 /// Returns the previous value (like __sync_fetch_and_add).
2987 #[inline]
2988 #[cfg(target_has_atomic = "8")]
2989 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2990 unsafe fn atomic_add<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
2991     // SAFETY: the caller must uphold the safety contract for `atomic_add`.
2992     unsafe {
2993         match order {
2994             Relaxed => intrinsics::atomic_xadd_relaxed(dst, val),
2995             Acquire => intrinsics::atomic_xadd_acquire(dst, val),
2996             Release => intrinsics::atomic_xadd_release(dst, val),
2997             AcqRel => intrinsics::atomic_xadd_acqrel(dst, val),
2998             SeqCst => intrinsics::atomic_xadd_seqcst(dst, val),
2999         }
3000     }
3001 }
3002
3003 /// Returns the previous value (like __sync_fetch_and_sub).
3004 #[inline]
3005 #[cfg(target_has_atomic = "8")]
3006 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3007 unsafe fn atomic_sub<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3008     // SAFETY: the caller must uphold the safety contract for `atomic_sub`.
3009     unsafe {
3010         match order {
3011             Relaxed => intrinsics::atomic_xsub_relaxed(dst, val),
3012             Acquire => intrinsics::atomic_xsub_acquire(dst, val),
3013             Release => intrinsics::atomic_xsub_release(dst, val),
3014             AcqRel => intrinsics::atomic_xsub_acqrel(dst, val),
3015             SeqCst => intrinsics::atomic_xsub_seqcst(dst, val),
3016         }
3017     }
3018 }
3019
3020 #[inline]
3021 #[cfg(target_has_atomic = "8")]
3022 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3023 unsafe fn atomic_compare_exchange<T: Copy>(
3024     dst: *mut T,
3025     old: T,
3026     new: T,
3027     success: Ordering,
3028     failure: Ordering,
3029 ) -> Result<T, T> {
3030     // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange`.
3031     let (val, ok) = unsafe {
3032         match (success, failure) {
3033             (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed_relaxed(dst, old, new),
3034             (Relaxed, Acquire) => intrinsics::atomic_cxchg_relaxed_acquire(dst, old, new),
3035             (Relaxed, SeqCst) => intrinsics::atomic_cxchg_relaxed_seqcst(dst, old, new),
3036             (Acquire, Relaxed) => intrinsics::atomic_cxchg_acquire_relaxed(dst, old, new),
3037             (Acquire, Acquire) => intrinsics::atomic_cxchg_acquire_acquire(dst, old, new),
3038             (Acquire, SeqCst) => intrinsics::atomic_cxchg_acquire_seqcst(dst, old, new),
3039             (Release, Relaxed) => intrinsics::atomic_cxchg_release_relaxed(dst, old, new),
3040             (Release, Acquire) => intrinsics::atomic_cxchg_release_acquire(dst, old, new),
3041             (Release, SeqCst) => intrinsics::atomic_cxchg_release_seqcst(dst, old, new),
3042             (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_relaxed(dst, old, new),
3043             (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel_acquire(dst, old, new),
3044             (AcqRel, SeqCst) => intrinsics::atomic_cxchg_acqrel_seqcst(dst, old, new),
3045             (SeqCst, Relaxed) => intrinsics::atomic_cxchg_seqcst_relaxed(dst, old, new),
3046             (SeqCst, Acquire) => intrinsics::atomic_cxchg_seqcst_acquire(dst, old, new),
3047             (SeqCst, SeqCst) => intrinsics::atomic_cxchg_seqcst_seqcst(dst, old, new),
3048             (_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"),
3049             (_, Release) => panic!("there is no such thing as a release failure ordering"),
3050         }
3051     };
3052     if ok { Ok(val) } else { Err(val) }
3053 }
3054
3055 #[inline]
3056 #[cfg(target_has_atomic = "8")]
3057 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3058 unsafe fn atomic_compare_exchange_weak<T: Copy>(
3059     dst: *mut T,
3060     old: T,
3061     new: T,
3062     success: Ordering,
3063     failure: Ordering,
3064 ) -> Result<T, T> {
3065     // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange_weak`.
3066     let (val, ok) = unsafe {
3067         match (success, failure) {
3068             (Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed_relaxed(dst, old, new),
3069             (Relaxed, Acquire) => intrinsics::atomic_cxchgweak_relaxed_acquire(dst, old, new),
3070             (Relaxed, SeqCst) => intrinsics::atomic_cxchgweak_relaxed_seqcst(dst, old, new),
3071             (Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acquire_relaxed(dst, old, new),
3072             (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acquire_acquire(dst, old, new),
3073             (Acquire, SeqCst) => intrinsics::atomic_cxchgweak_acquire_seqcst(dst, old, new),
3074             (Release, Relaxed) => intrinsics::atomic_cxchgweak_release_relaxed(dst, old, new),
3075             (Release, Acquire) => intrinsics::atomic_cxchgweak_release_acquire(dst, old, new),
3076             (Release, SeqCst) => intrinsics::atomic_cxchgweak_release_seqcst(dst, old, new),
3077             (AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_relaxed(dst, old, new),
3078             (AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel_acquire(dst, old, new),
3079             (AcqRel, SeqCst) => intrinsics::atomic_cxchgweak_acqrel_seqcst(dst, old, new),
3080             (SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_seqcst_relaxed(dst, old, new),
3081             (SeqCst, Acquire) => intrinsics::atomic_cxchgweak_seqcst_acquire(dst, old, new),
3082             (SeqCst, SeqCst) => intrinsics::atomic_cxchgweak_seqcst_seqcst(dst, old, new),
3083             (_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"),
3084             (_, Release) => panic!("there is no such thing as a release failure ordering"),
3085         }
3086     };
3087     if ok { Ok(val) } else { Err(val) }
3088 }
3089
3090 #[inline]
3091 #[cfg(target_has_atomic = "8")]
3092 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3093 unsafe fn atomic_and<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3094     // SAFETY: the caller must uphold the safety contract for `atomic_and`
3095     unsafe {
3096         match order {
3097             Relaxed => intrinsics::atomic_and_relaxed(dst, val),
3098             Acquire => intrinsics::atomic_and_acquire(dst, val),
3099             Release => intrinsics::atomic_and_release(dst, val),
3100             AcqRel => intrinsics::atomic_and_acqrel(dst, val),
3101             SeqCst => intrinsics::atomic_and_seqcst(dst, val),
3102         }
3103     }
3104 }
3105
3106 #[inline]
3107 #[cfg(target_has_atomic = "8")]
3108 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3109 unsafe fn atomic_nand<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3110     // SAFETY: the caller must uphold the safety contract for `atomic_nand`
3111     unsafe {
3112         match order {
3113             Relaxed => intrinsics::atomic_nand_relaxed(dst, val),
3114             Acquire => intrinsics::atomic_nand_acquire(dst, val),
3115             Release => intrinsics::atomic_nand_release(dst, val),
3116             AcqRel => intrinsics::atomic_nand_acqrel(dst, val),
3117             SeqCst => intrinsics::atomic_nand_seqcst(dst, val),
3118         }
3119     }
3120 }
3121
3122 #[inline]
3123 #[cfg(target_has_atomic = "8")]
3124 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3125 unsafe fn atomic_or<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3126     // SAFETY: the caller must uphold the safety contract for `atomic_or`
3127     unsafe {
3128         match order {
3129             SeqCst => intrinsics::atomic_or_seqcst(dst, val),
3130             Acquire => intrinsics::atomic_or_acquire(dst, val),
3131             Release => intrinsics::atomic_or_release(dst, val),
3132             AcqRel => intrinsics::atomic_or_acqrel(dst, val),
3133             Relaxed => intrinsics::atomic_or_relaxed(dst, val),
3134         }
3135     }
3136 }
3137
3138 #[inline]
3139 #[cfg(target_has_atomic = "8")]
3140 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3141 unsafe fn atomic_xor<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3142     // SAFETY: the caller must uphold the safety contract for `atomic_xor`
3143     unsafe {
3144         match order {
3145             SeqCst => intrinsics::atomic_xor_seqcst(dst, val),
3146             Acquire => intrinsics::atomic_xor_acquire(dst, val),
3147             Release => intrinsics::atomic_xor_release(dst, val),
3148             AcqRel => intrinsics::atomic_xor_acqrel(dst, val),
3149             Relaxed => intrinsics::atomic_xor_relaxed(dst, val),
3150         }
3151     }
3152 }
3153
3154 /// returns the max value (signed comparison)
3155 #[inline]
3156 #[cfg(target_has_atomic = "8")]
3157 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3158 unsafe fn atomic_max<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3159     // SAFETY: the caller must uphold the safety contract for `atomic_max`
3160     unsafe {
3161         match order {
3162             Relaxed => intrinsics::atomic_max_relaxed(dst, val),
3163             Acquire => intrinsics::atomic_max_acquire(dst, val),
3164             Release => intrinsics::atomic_max_release(dst, val),
3165             AcqRel => intrinsics::atomic_max_acqrel(dst, val),
3166             SeqCst => intrinsics::atomic_max_seqcst(dst, val),
3167         }
3168     }
3169 }
3170
3171 /// returns the min value (signed comparison)
3172 #[inline]
3173 #[cfg(target_has_atomic = "8")]
3174 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3175 unsafe fn atomic_min<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3176     // SAFETY: the caller must uphold the safety contract for `atomic_min`
3177     unsafe {
3178         match order {
3179             Relaxed => intrinsics::atomic_min_relaxed(dst, val),
3180             Acquire => intrinsics::atomic_min_acquire(dst, val),
3181             Release => intrinsics::atomic_min_release(dst, val),
3182             AcqRel => intrinsics::atomic_min_acqrel(dst, val),
3183             SeqCst => intrinsics::atomic_min_seqcst(dst, val),
3184         }
3185     }
3186 }
3187
3188 /// returns the max value (unsigned comparison)
3189 #[inline]
3190 #[cfg(target_has_atomic = "8")]
3191 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3192 unsafe fn atomic_umax<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3193     // SAFETY: the caller must uphold the safety contract for `atomic_umax`
3194     unsafe {
3195         match order {
3196             Relaxed => intrinsics::atomic_umax_relaxed(dst, val),
3197             Acquire => intrinsics::atomic_umax_acquire(dst, val),
3198             Release => intrinsics::atomic_umax_release(dst, val),
3199             AcqRel => intrinsics::atomic_umax_acqrel(dst, val),
3200             SeqCst => intrinsics::atomic_umax_seqcst(dst, val),
3201         }
3202     }
3203 }
3204
3205 /// returns the min value (unsigned comparison)
3206 #[inline]
3207 #[cfg(target_has_atomic = "8")]
3208 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3209 unsafe fn atomic_umin<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
3210     // SAFETY: the caller must uphold the safety contract for `atomic_umin`
3211     unsafe {
3212         match order {
3213             Relaxed => intrinsics::atomic_umin_relaxed(dst, val),
3214             Acquire => intrinsics::atomic_umin_acquire(dst, val),
3215             Release => intrinsics::atomic_umin_release(dst, val),
3216             AcqRel => intrinsics::atomic_umin_acqrel(dst, val),
3217             SeqCst => intrinsics::atomic_umin_seqcst(dst, val),
3218         }
3219     }
3220 }
3221
3222 /// An atomic fence.
3223 ///
3224 /// Depending on the specified order, a fence prevents the compiler and CPU from
3225 /// reordering certain types of memory operations around it.
3226 /// That creates synchronizes-with relationships between it and atomic operations
3227 /// or fences in other threads.
3228 ///
3229 /// A fence 'A' which has (at least) [`Release`] ordering semantics, synchronizes
3230 /// with a fence 'B' with (at least) [`Acquire`] semantics, if and only if there
3231 /// exist operations X and Y, both operating on some atomic object 'M' such
3232 /// that A is sequenced before X, Y is sequenced before B and Y observes
3233 /// the change to M. This provides a happens-before dependence between A and B.
3234 ///
3235 /// ```text
3236 ///     Thread 1                                          Thread 2
3237 ///
3238 /// fence(Release);      A --------------
3239 /// x.store(3, Relaxed); X ---------    |
3240 ///                                |    |
3241 ///                                |    |
3242 ///                                -------------> Y  if x.load(Relaxed) == 3 {
3243 ///                                     |-------> B      fence(Acquire);
3244 ///                                                      ...
3245 ///                                                  }
3246 /// ```
3247 ///
3248 /// Atomic operations with [`Release`] or [`Acquire`] semantics can also synchronize
3249 /// with a fence.
3250 ///
3251 /// A fence which has [`SeqCst`] ordering, in addition to having both [`Acquire`]
3252 /// and [`Release`] semantics, participates in the global program order of the
3253 /// other [`SeqCst`] operations and/or fences.
3254 ///
3255 /// Accepts [`Acquire`], [`Release`], [`AcqRel`] and [`SeqCst`] orderings.
3256 ///
3257 /// # Panics
3258 ///
3259 /// Panics if `order` is [`Relaxed`].
3260 ///
3261 /// # Examples
3262 ///
3263 /// ```
3264 /// use std::sync::atomic::AtomicBool;
3265 /// use std::sync::atomic::fence;
3266 /// use std::sync::atomic::Ordering;
3267 ///
3268 /// // A mutual exclusion primitive based on spinlock.
3269 /// pub struct Mutex {
3270 ///     flag: AtomicBool,
3271 /// }
3272 ///
3273 /// impl Mutex {
3274 ///     pub fn new() -> Mutex {
3275 ///         Mutex {
3276 ///             flag: AtomicBool::new(false),
3277 ///         }
3278 ///     }
3279 ///
3280 ///     pub fn lock(&self) {
3281 ///         // Wait until the old value is `false`.
3282 ///         while self
3283 ///             .flag
3284 ///             .compare_exchange_weak(false, true, Ordering::Relaxed, Ordering::Relaxed)
3285 ///             .is_err()
3286 ///         {}
3287 ///         // This fence synchronizes-with store in `unlock`.
3288 ///         fence(Ordering::Acquire);
3289 ///     }
3290 ///
3291 ///     pub fn unlock(&self) {
3292 ///         self.flag.store(false, Ordering::Release);
3293 ///     }
3294 /// }
3295 /// ```
3296 #[inline]
3297 #[stable(feature = "rust1", since = "1.0.0")]
3298 #[rustc_diagnostic_item = "fence"]
3299 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3300 pub fn fence(order: Ordering) {
3301     // SAFETY: using an atomic fence is safe.
3302     unsafe {
3303         match order {
3304             Acquire => intrinsics::atomic_fence_acquire(),
3305             Release => intrinsics::atomic_fence_release(),
3306             AcqRel => intrinsics::atomic_fence_acqrel(),
3307             SeqCst => intrinsics::atomic_fence_seqcst(),
3308             Relaxed => panic!("there is no such thing as a relaxed fence"),
3309         }
3310     }
3311 }
3312
3313 /// A compiler memory fence.
3314 ///
3315 /// `compiler_fence` does not emit any machine code, but restricts the kinds
3316 /// of memory re-ordering the compiler is allowed to do. Specifically, depending on
3317 /// the given [`Ordering`] semantics, the compiler may be disallowed from moving reads
3318 /// or writes from before or after the call to the other side of the call to
3319 /// `compiler_fence`. Note that it does **not** prevent the *hardware*
3320 /// from doing such re-ordering. This is not a problem in a single-threaded,
3321 /// execution context, but when other threads may modify memory at the same
3322 /// time, stronger synchronization primitives such as [`fence`] are required.
3323 ///
3324 /// The re-ordering prevented by the different ordering semantics are:
3325 ///
3326 ///  - with [`SeqCst`], no re-ordering of reads and writes across this point is allowed.
3327 ///  - with [`Release`], preceding reads and writes cannot be moved past subsequent writes.
3328 ///  - with [`Acquire`], subsequent reads and writes cannot be moved ahead of preceding reads.
3329 ///  - with [`AcqRel`], both of the above rules are enforced.
3330 ///
3331 /// `compiler_fence` is generally only useful for preventing a thread from
3332 /// racing *with itself*. That is, if a given thread is executing one piece
3333 /// of code, and is then interrupted, and starts executing code elsewhere
3334 /// (while still in the same thread, and conceptually still on the same
3335 /// core). In traditional programs, this can only occur when a signal
3336 /// handler is registered. In more low-level code, such situations can also
3337 /// arise when handling interrupts, when implementing green threads with
3338 /// pre-emption, etc. Curious readers are encouraged to read the Linux kernel's
3339 /// discussion of [memory barriers].
3340 ///
3341 /// # Panics
3342 ///
3343 /// Panics if `order` is [`Relaxed`].
3344 ///
3345 /// # Examples
3346 ///
3347 /// Without `compiler_fence`, the `assert_eq!` in following code
3348 /// is *not* guaranteed to succeed, despite everything happening in a single thread.
3349 /// To see why, remember that the compiler is free to swap the stores to
3350 /// `IMPORTANT_VARIABLE` and `IS_READY` since they are both
3351 /// `Ordering::Relaxed`. If it does, and the signal handler is invoked right
3352 /// after `IS_READY` is updated, then the signal handler will see
3353 /// `IS_READY=1`, but `IMPORTANT_VARIABLE=0`.
3354 /// Using a `compiler_fence` remedies this situation.
3355 ///
3356 /// ```
3357 /// use std::sync::atomic::{AtomicBool, AtomicUsize};
3358 /// use std::sync::atomic::Ordering;
3359 /// use std::sync::atomic::compiler_fence;
3360 ///
3361 /// static IMPORTANT_VARIABLE: AtomicUsize = AtomicUsize::new(0);
3362 /// static IS_READY: AtomicBool = AtomicBool::new(false);
3363 ///
3364 /// fn main() {
3365 ///     IMPORTANT_VARIABLE.store(42, Ordering::Relaxed);
3366 ///     // prevent earlier writes from being moved beyond this point
3367 ///     compiler_fence(Ordering::Release);
3368 ///     IS_READY.store(true, Ordering::Relaxed);
3369 /// }
3370 ///
3371 /// fn signal_handler() {
3372 ///     if IS_READY.load(Ordering::Relaxed) {
3373 ///         assert_eq!(IMPORTANT_VARIABLE.load(Ordering::Relaxed), 42);
3374 ///     }
3375 /// }
3376 /// ```
3377 ///
3378 /// [memory barriers]: https://www.kernel.org/doc/Documentation/memory-barriers.txt
3379 #[inline]
3380 #[stable(feature = "compiler_fences", since = "1.21.0")]
3381 #[rustc_diagnostic_item = "compiler_fence"]
3382 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3383 pub fn compiler_fence(order: Ordering) {
3384     // SAFETY: using an atomic fence is safe.
3385     unsafe {
3386         match order {
3387             Acquire => intrinsics::atomic_singlethreadfence_acquire(),
3388             Release => intrinsics::atomic_singlethreadfence_release(),
3389             AcqRel => intrinsics::atomic_singlethreadfence_acqrel(),
3390             SeqCst => intrinsics::atomic_singlethreadfence_seqcst(),
3391             Relaxed => panic!("there is no such thing as a relaxed compiler fence"),
3392         }
3393     }
3394 }
3395
3396 #[cfg(target_has_atomic_load_store = "8")]
3397 #[stable(feature = "atomic_debug", since = "1.3.0")]
3398 impl fmt::Debug for AtomicBool {
3399     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3400         fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
3401     }
3402 }
3403
3404 #[cfg(target_has_atomic_load_store = "ptr")]
3405 #[stable(feature = "atomic_debug", since = "1.3.0")]
3406 impl<T> fmt::Debug for AtomicPtr<T> {
3407     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3408         fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
3409     }
3410 }
3411
3412 #[cfg(target_has_atomic_load_store = "ptr")]
3413 #[stable(feature = "atomic_pointer", since = "1.24.0")]
3414 impl<T> fmt::Pointer for AtomicPtr<T> {
3415     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3416         fmt::Pointer::fmt(&self.load(Ordering::SeqCst), f)
3417     }
3418 }
3419
3420 /// Signals the processor that it is inside a busy-wait spin-loop ("spin lock").
3421 ///
3422 /// This function is deprecated in favor of [`hint::spin_loop`].
3423 ///
3424 /// [`hint::spin_loop`]: crate::hint::spin_loop
3425 #[inline]
3426 #[stable(feature = "spin_loop_hint", since = "1.24.0")]
3427 #[deprecated(since = "1.51.0", note = "use hint::spin_loop instead")]
3428 pub fn spin_loop_hint() {
3429     spin_loop()
3430 }