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