]> git.lizzy.rs Git - rust.git/blob - src/libcore/sync/atomic.rs
Document unsafe blocks in core::{cell, str, sync}
[rust.git] / src / libcore / sync / atomic.rs
1 //! Atomic types
2 //!
3 //! Atomic types provide primitive shared-memory communication between
4 //! threads, and are the building blocks of other concurrent
5 //! types.
6 //!
7 //! This module defines atomic versions of a select number of primitive
8 //! types, including [`AtomicBool`], [`AtomicIsize`], [`AtomicUsize`],
9 //! [`AtomicI8`], [`AtomicU16`], etc.
10 //! Atomic types present operations that, when used correctly, synchronize
11 //! updates between threads.
12 //!
13 //! [`AtomicBool`]: struct.AtomicBool.html
14 //! [`AtomicIsize`]: struct.AtomicIsize.html
15 //! [`AtomicUsize`]: struct.AtomicUsize.html
16 //! [`AtomicI8`]: struct.AtomicI8.html
17 //! [`AtomicU16`]: struct.AtomicU16.html
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 //! [`Ordering`]: enum.Ordering.html
24 //!
25 //! [1]: https://en.cppreference.com/w/cpp/atomic/memory_order
26 //! [2]: ../../../nomicon/atomics.html
27 //!
28 //! Atomic variables are safe to share between threads (they implement [`Sync`])
29 //! but they do not themselves provide the mechanism for sharing and follow the
30 //! [threading model](../../../std/thread/index.html#the-threading-model) of Rust.
31 //! The most common way to share an atomic variable is to put it into an [`Arc`][arc] (an
32 //! atomically-reference-counted shared pointer).
33 //!
34 //! [`Sync`]: ../../marker/trait.Sync.html
35 //! [arc]: ../../../std/sync/struct.Arc.html
36 //!
37 //! Atomic types may be stored in static variables, initialized using
38 //! the constant initializers like [`AtomicBool::new`]. Atomic statics
39 //! are often used for lazy global initialization.
40 //!
41 //! [`AtomicBool::new`]: struct.AtomicBool.html#method.new
42 //!
43 //! # Portability
44 //!
45 //! All atomic types in this module are guaranteed to be [lock-free] if they're
46 //! available. This means they don't internally acquire a global mutex. Atomic
47 //! types and operations are not guaranteed to be wait-free. This means that
48 //! operations like `fetch_or` may be implemented with a compare-and-swap loop.
49 //!
50 //! Atomic operations may be implemented at the instruction layer with
51 //! larger-size atomics. For example some platforms use 4-byte atomic
52 //! instructions to implement `AtomicI8`. Note that this emulation should not
53 //! have an impact on correctness of code, it's just something to be aware of.
54 //!
55 //! The atomic types in this module may not be available on all platforms. The
56 //! atomic types here are all widely available, however, and can generally be
57 //! relied upon existing. Some notable exceptions are:
58 //!
59 //! * PowerPC and MIPS platforms with 32-bit pointers do not have `AtomicU64` or
60 //!   `AtomicI64` types.
61 //! * ARM platforms like `armv5te` that aren't for Linux do not have any atomics
62 //!   at all.
63 //! * ARM targets with `thumbv6m` do not have atomic operations at all.
64 //!
65 //! Note that future platforms may be added that also do not have support for
66 //! some atomic operations. Maximally portable code will want to be careful
67 //! about which atomic types are used. `AtomicUsize` and `AtomicIsize` are
68 //! generally the most portable, but even then they're not available everywhere.
69 //! For reference, the `std` library requires pointer-sized atomics, although
70 //! `core` does not.
71 //!
72 //! Currently you'll need to use `#[cfg(target_arch)]` primarily to
73 //! conditionally compile in code with atomics. There is an unstable
74 //! `#[cfg(target_has_atomic)]` as well which may be stabilized in the future.
75 //!
76 //! [lock-free]: https://en.wikipedia.org/wiki/Non-blocking_algorithm
77 //!
78 //! # Examples
79 //!
80 //! A simple spinlock:
81 //!
82 //! ```
83 //! use std::sync::Arc;
84 //! use std::sync::atomic::{AtomicUsize, Ordering};
85 //! use std::thread;
86 //!
87 //! fn main() {
88 //!     let spinlock = Arc::new(AtomicUsize::new(1));
89 //!
90 //!     let spinlock_clone = spinlock.clone();
91 //!     let thread = thread::spawn(move|| {
92 //!         spinlock_clone.store(0, Ordering::SeqCst);
93 //!     });
94 //!
95 //!     // Wait for the other thread to release the lock
96 //!     while spinlock.load(Ordering::SeqCst) != 0 {}
97 //!
98 //!     if let Err(panic) = thread.join() {
99 //!         println!("Thread had an error: {:?}", panic);
100 //!     }
101 //! }
102 //! ```
103 //!
104 //! Keep a global count of live threads:
105 //!
106 //! ```
107 //! use std::sync::atomic::{AtomicUsize, Ordering};
108 //!
109 //! static GLOBAL_THREAD_COUNT: AtomicUsize = AtomicUsize::new(0);
110 //!
111 //! let old_thread_count = GLOBAL_THREAD_COUNT.fetch_add(1, Ordering::SeqCst);
112 //! println!("live threads: {}", old_thread_count + 1);
113 //! ```
114
115 #![stable(feature = "rust1", since = "1.0.0")]
116 #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(dead_code))]
117 #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(unused_imports))]
118
119 use self::Ordering::*;
120
121 use crate::cell::UnsafeCell;
122 use crate::fmt;
123 use crate::intrinsics;
124
125 use crate::hint::spin_loop;
126
127 /// Signals the processor that it is inside a busy-wait spin-loop ("spin lock").
128 ///
129 /// Upon receiving spin-loop signal the processor can optimize its behavior by, for example, saving
130 /// power or switching hyper-threads.
131 ///
132 /// This function is different from [`std::thread::yield_now`] which directly yields to the
133 /// system's scheduler, whereas `spin_loop_hint` does not interact with the operating system.
134 ///
135 /// A common use case for `spin_loop_hint` is implementing bounded optimistic spinning in a CAS
136 /// loop in synchronization primitives. To avoid problems like priority inversion, it is strongly
137 /// recommended that the spin loop is terminated after a finite amount of iterations and an
138 /// appropriate blocking syscall is made.
139 ///
140 /// **Note**: On platforms that do not support receiving spin-loop hints this function does not
141 /// do anything at all.
142 ///
143 /// [`std::thread::yield_now`]: ../../../std/thread/fn.yield_now.html
144 /// [`std::thread::sleep`]: ../../../std/thread/fn.sleep.html
145 /// [`std::sync::Mutex`]: ../../../std/sync/struct.Mutex.html
146 #[inline]
147 #[stable(feature = "spin_loop_hint", since = "1.24.0")]
148 pub fn spin_loop_hint() {
149     spin_loop()
150 }
151
152 /// A boolean type which can be safely shared between threads.
153 ///
154 /// This type has the same in-memory representation as a [`bool`].
155 ///
156 /// [`bool`]: ../../../std/primitive.bool.html
157 #[cfg(target_has_atomic_load_store = "8")]
158 #[stable(feature = "rust1", since = "1.0.0")]
159 #[repr(C, align(1))]
160 pub struct AtomicBool {
161     v: UnsafeCell<u8>,
162 }
163
164 #[cfg(target_has_atomic_load_store = "8")]
165 #[stable(feature = "rust1", since = "1.0.0")]
166 impl Default for AtomicBool {
167     /// Creates an `AtomicBool` initialized to `false`.
168     fn default() -> Self {
169         Self::new(false)
170     }
171 }
172
173 // Send is implicitly implemented for AtomicBool.
174 #[cfg(target_has_atomic_load_store = "8")]
175 #[stable(feature = "rust1", since = "1.0.0")]
176 unsafe impl Sync for AtomicBool {}
177
178 /// A raw pointer type which can be safely shared between threads.
179 ///
180 /// This type has the same in-memory representation as a `*mut T`.
181 #[cfg(target_has_atomic_load_store = "ptr")]
182 #[stable(feature = "rust1", since = "1.0.0")]
183 #[cfg_attr(target_pointer_width = "16", repr(C, align(2)))]
184 #[cfg_attr(target_pointer_width = "32", repr(C, align(4)))]
185 #[cfg_attr(target_pointer_width = "64", repr(C, align(8)))]
186 pub struct AtomicPtr<T> {
187     p: UnsafeCell<*mut T>,
188 }
189
190 #[cfg(target_has_atomic_load_store = "ptr")]
191 #[stable(feature = "rust1", since = "1.0.0")]
192 impl<T> Default for AtomicPtr<T> {
193     /// Creates a null `AtomicPtr<T>`.
194     fn default() -> AtomicPtr<T> {
195         AtomicPtr::new(crate::ptr::null_mut())
196     }
197 }
198
199 #[cfg(target_has_atomic_load_store = "ptr")]
200 #[stable(feature = "rust1", since = "1.0.0")]
201 unsafe impl<T> Send for AtomicPtr<T> {}
202 #[cfg(target_has_atomic_load_store = "ptr")]
203 #[stable(feature = "rust1", since = "1.0.0")]
204 unsafe impl<T> Sync for AtomicPtr<T> {}
205
206 /// Atomic memory orderings
207 ///
208 /// Memory orderings specify the way atomic operations synchronize memory.
209 /// In its weakest [`Relaxed`][Ordering::Relaxed], only the memory directly touched by the
210 /// operation is synchronized. On the other hand, a store-load pair of [`SeqCst`][Ordering::SeqCst]
211 /// operations synchronize other memory while additionally preserving a total order of such
212 /// operations across all threads.
213 ///
214 /// Rust's memory orderings are [the same as those of
215 /// C++20](https://en.cppreference.com/w/cpp/atomic/memory_order).
216 ///
217 /// For more information see the [nomicon].
218 ///
219 /// [nomicon]: ../../../nomicon/atomics.html
220 /// [Ordering::Relaxed]: #variant.Relaxed
221 /// [Ordering::SeqCst]: #variant.SeqCst
222 #[stable(feature = "rust1", since = "1.0.0")]
223 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
224 #[non_exhaustive]
225 pub enum Ordering {
226     /// No ordering constraints, only atomic operations.
227     ///
228     /// Corresponds to [`memory_order_relaxed`] in C++20.
229     ///
230     /// [`memory_order_relaxed`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Relaxed_ordering
231     #[stable(feature = "rust1", since = "1.0.0")]
232     Relaxed,
233     /// When coupled with a store, all previous operations become ordered
234     /// before any load of this value with [`Acquire`] (or stronger) ordering.
235     /// In particular, all previous writes become visible to all threads
236     /// that perform an [`Acquire`] (or stronger) load of this value.
237     ///
238     /// Notice that using this ordering for an operation that combines loads
239     /// and stores leads to a [`Relaxed`] load operation!
240     ///
241     /// This ordering is only applicable for operations that can perform a store.
242     ///
243     /// Corresponds to [`memory_order_release`] in C++20.
244     ///
245     /// [`Release`]: #variant.Release
246     /// [`Acquire`]: #variant.Acquire
247     /// [`Relaxed`]: #variant.Relaxed
248     /// [`memory_order_release`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
249     #[stable(feature = "rust1", since = "1.0.0")]
250     Release,
251     /// When coupled with a load, if the loaded value was written by a store operation with
252     /// [`Release`] (or stronger) ordering, then all subsequent operations
253     /// become ordered after that store. In particular, all subsequent loads will see data
254     /// written before the store.
255     ///
256     /// Notice that using this ordering for an operation that combines loads
257     /// and stores leads to a [`Relaxed`] store operation!
258     ///
259     /// This ordering is only applicable for operations that can perform a load.
260     ///
261     /// Corresponds to [`memory_order_acquire`] in C++20.
262     ///
263     /// [`Acquire`]: #variant.Acquire
264     /// [`Release`]: #variant.Release
265     /// [`Relaxed`]: #variant.Relaxed
266     /// [`memory_order_acquire`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
267     #[stable(feature = "rust1", since = "1.0.0")]
268     Acquire,
269     /// Has the effects of both [`Acquire`] and [`Release`] together:
270     /// For loads it uses [`Acquire`] ordering. For stores it uses the [`Release`] ordering.
271     ///
272     /// Notice that in the case of `compare_and_swap`, it is possible that the operation ends up
273     /// not performing any store and hence it has just [`Acquire`] ordering. However,
274     /// `AcqRel` will never perform [`Relaxed`] accesses.
275     ///
276     /// This ordering is only applicable for operations that combine both loads and stores.
277     ///
278     /// Corresponds to [`memory_order_acq_rel`] in C++20.
279     ///
280     /// [`memory_order_acq_rel`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
281     /// [`Acquire`]: #variant.Acquire
282     /// [`Release`]: #variant.Release
283     /// [`Relaxed`]: #variant.Relaxed
284     #[stable(feature = "rust1", since = "1.0.0")]
285     AcqRel,
286     /// Like [`Acquire`]/[`Release`]/[`AcqRel`] (for load, store, and load-with-store
287     /// operations, respectively) with the additional guarantee that all threads see all
288     /// sequentially consistent operations in the same order.
289     ///
290     /// Corresponds to [`memory_order_seq_cst`] in C++20.
291     ///
292     /// [`memory_order_seq_cst`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Sequentially-consistent_ordering
293     /// [`Acquire`]: #variant.Acquire
294     /// [`Release`]: #variant.Release
295     /// [`AcqRel`]: #variant.AcqRel
296     #[stable(feature = "rust1", since = "1.0.0")]
297     SeqCst,
298 }
299
300 /// An [`AtomicBool`] initialized to `false`.
301 ///
302 /// [`AtomicBool`]: struct.AtomicBool.html
303 #[cfg(target_has_atomic_load_store = "8")]
304 #[stable(feature = "rust1", since = "1.0.0")]
305 #[rustc_deprecated(
306     since = "1.34.0",
307     reason = "the `new` function is now preferred",
308     suggestion = "AtomicBool::new(false)"
309 )]
310 pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false);
311
312 #[cfg(target_has_atomic_load_store = "8")]
313 impl AtomicBool {
314     /// Creates a new `AtomicBool`.
315     ///
316     /// # Examples
317     ///
318     /// ```
319     /// use std::sync::atomic::AtomicBool;
320     ///
321     /// let atomic_true  = AtomicBool::new(true);
322     /// let atomic_false = AtomicBool::new(false);
323     /// ```
324     #[inline]
325     #[stable(feature = "rust1", since = "1.0.0")]
326     #[rustc_const_stable(feature = "const_atomic_new", since = "1.32.0")]
327     pub const fn new(v: bool) -> AtomicBool {
328         AtomicBool { v: UnsafeCell::new(v as u8) }
329     }
330
331     /// Returns a mutable reference to the underlying [`bool`].
332     ///
333     /// This is safe because the mutable reference guarantees that no other threads are
334     /// concurrently accessing the atomic data.
335     ///
336     /// [`bool`]: ../../../std/primitive.bool.html
337     ///
338     /// # Examples
339     ///
340     /// ```
341     /// use std::sync::atomic::{AtomicBool, Ordering};
342     ///
343     /// let mut some_bool = AtomicBool::new(true);
344     /// assert_eq!(*some_bool.get_mut(), true);
345     /// *some_bool.get_mut() = false;
346     /// assert_eq!(some_bool.load(Ordering::SeqCst), false);
347     /// ```
348     #[inline]
349     #[stable(feature = "atomic_access", since = "1.15.0")]
350     pub fn get_mut(&mut self) -> &mut bool {
351         // SAFETY: the mutable reference guarantees unique ownership
352         unsafe { &mut *(self.v.get() as *mut bool) }
353     }
354
355     /// Consumes the atomic and returns the contained value.
356     ///
357     /// This is safe because passing `self` by value guarantees that no other threads are
358     /// concurrently accessing the atomic data.
359     ///
360     /// # Examples
361     ///
362     /// ```
363     /// use std::sync::atomic::AtomicBool;
364     ///
365     /// let some_bool = AtomicBool::new(true);
366     /// assert_eq!(some_bool.into_inner(), true);
367     /// ```
368     #[inline]
369     #[stable(feature = "atomic_access", since = "1.15.0")]
370     pub fn into_inner(self) -> bool {
371         self.v.into_inner() != 0
372     }
373
374     /// Loads a value from the bool.
375     ///
376     /// `load` takes an [`Ordering`] argument which describes the memory ordering
377     /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
378     ///
379     /// # Panics
380     ///
381     /// Panics if `order` is [`Release`] or [`AcqRel`].
382     ///
383     /// [`Ordering`]: enum.Ordering.html
384     /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
385     /// [`Release`]: enum.Ordering.html#variant.Release
386     /// [`Acquire`]: enum.Ordering.html#variant.Acquire
387     /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
388     /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
389     ///
390     /// # Examples
391     ///
392     /// ```
393     /// use std::sync::atomic::{AtomicBool, Ordering};
394     ///
395     /// let some_bool = AtomicBool::new(true);
396     ///
397     /// assert_eq!(some_bool.load(Ordering::Relaxed), true);
398     /// ```
399     #[inline]
400     #[stable(feature = "rust1", since = "1.0.0")]
401     pub fn load(&self, order: Ordering) -> bool {
402         // SAFETY: data races are prevented by atomic intrinsics
403         unsafe { atomic_load(self.v.get(), order) != 0 }
404     }
405
406     /// Stores a value into the bool.
407     ///
408     /// `store` takes an [`Ordering`] argument which describes the memory ordering
409     /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
410     ///
411     /// # Panics
412     ///
413     /// Panics if `order` is [`Acquire`] or [`AcqRel`].
414     ///
415     /// [`Ordering`]: enum.Ordering.html
416     /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
417     /// [`Release`]: enum.Ordering.html#variant.Release
418     /// [`Acquire`]: enum.Ordering.html#variant.Acquire
419     /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
420     /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
421     ///
422     /// # Examples
423     ///
424     /// ```
425     /// use std::sync::atomic::{AtomicBool, Ordering};
426     ///
427     /// let some_bool = AtomicBool::new(true);
428     ///
429     /// some_bool.store(false, Ordering::Relaxed);
430     /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
431     /// ```
432     #[inline]
433     #[stable(feature = "rust1", since = "1.0.0")]
434     pub fn store(&self, val: bool, order: Ordering) {
435         // SAFETY: data races are prevented by atomic intrinsics
436         unsafe {
437             atomic_store(self.v.get(), val as u8, order);
438         }
439     }
440
441     /// Stores a value into the bool, returning the previous value.
442     ///
443     /// `swap` takes an [`Ordering`] argument which describes the memory ordering
444     /// of this operation. All ordering modes are possible. Note that using
445     /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
446     /// using [`Release`] makes the load part [`Relaxed`].
447     ///
448     /// [`Ordering`]: enum.Ordering.html
449     /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
450     /// [`Release`]: enum.Ordering.html#variant.Release
451     /// [`Acquire`]: enum.Ordering.html#variant.Acquire
452     ///
453     /// # Examples
454     ///
455     /// ```
456     /// use std::sync::atomic::{AtomicBool, Ordering};
457     ///
458     /// let some_bool = AtomicBool::new(true);
459     ///
460     /// assert_eq!(some_bool.swap(false, Ordering::Relaxed), true);
461     /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
462     /// ```
463     #[inline]
464     #[stable(feature = "rust1", since = "1.0.0")]
465     #[cfg(target_has_atomic = "8")]
466     pub fn swap(&self, val: bool, order: Ordering) -> bool {
467         // SAFETY: data races are prevented by atomic intrinsics
468         unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 }
469     }
470
471     /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
472     ///
473     /// The return value is always the previous value. If it is equal to `current`, then the value
474     /// was updated.
475     ///
476     /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
477     /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
478     /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
479     /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
480     /// happens, and using [`Release`] makes the load part [`Relaxed`].
481     ///
482     /// [`Ordering`]: enum.Ordering.html
483     /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
484     /// [`Release`]: enum.Ordering.html#variant.Release
485     /// [`Acquire`]: enum.Ordering.html#variant.Acquire
486     /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
487     /// [`bool`]: ../../../std/primitive.bool.html
488     ///
489     /// # Examples
490     ///
491     /// ```
492     /// use std::sync::atomic::{AtomicBool, Ordering};
493     ///
494     /// let some_bool = AtomicBool::new(true);
495     ///
496     /// assert_eq!(some_bool.compare_and_swap(true, false, Ordering::Relaxed), true);
497     /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
498     ///
499     /// assert_eq!(some_bool.compare_and_swap(true, true, Ordering::Relaxed), false);
500     /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
501     /// ```
502     #[inline]
503     #[stable(feature = "rust1", since = "1.0.0")]
504     #[cfg(target_has_atomic = "8")]
505     pub fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> bool {
506         match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
507             Ok(x) => x,
508             Err(x) => x,
509         }
510     }
511
512     /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
513     ///
514     /// The return value is a result indicating whether the new value was written and containing
515     /// the previous value. On success this value is guaranteed to be equal to `current`.
516     ///
517     /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
518     /// ordering of this operation. The first describes the required ordering if the
519     /// operation succeeds while the second describes the required ordering when the
520     /// operation fails. Using [`Acquire`] as success ordering makes the store part
521     /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
522     /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]
523     /// and must be equivalent to or weaker than the success ordering.
524     ///
525     ///
526     /// [`bool`]: ../../../std/primitive.bool.html
527     /// [`Ordering`]: enum.Ordering.html
528     /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
529     /// [`Release`]: enum.Ordering.html#variant.Release
530     /// [`Acquire`]: enum.Ordering.html#variant.Acquire
531     /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
532     ///
533     /// # Examples
534     ///
535     /// ```
536     /// use std::sync::atomic::{AtomicBool, Ordering};
537     ///
538     /// let some_bool = AtomicBool::new(true);
539     ///
540     /// assert_eq!(some_bool.compare_exchange(true,
541     ///                                       false,
542     ///                                       Ordering::Acquire,
543     ///                                       Ordering::Relaxed),
544     ///            Ok(true));
545     /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
546     ///
547     /// assert_eq!(some_bool.compare_exchange(true, true,
548     ///                                       Ordering::SeqCst,
549     ///                                       Ordering::Acquire),
550     ///            Err(false));
551     /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
552     /// ```
553     #[inline]
554     #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
555     #[cfg(target_has_atomic = "8")]
556     pub fn compare_exchange(
557         &self,
558         current: bool,
559         new: bool,
560         success: Ordering,
561         failure: Ordering,
562     ) -> Result<bool, bool> {
563         // SAFETY: data races are prevented by atomic intrinsics
564         match unsafe {
565             atomic_compare_exchange(self.v.get(), current as u8, new as u8, success, failure)
566         } {
567             Ok(x) => Ok(x != 0),
568             Err(x) => Err(x != 0),
569         }
570     }
571
572     /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
573     ///
574     /// Unlike [`compare_exchange`], this function is allowed to spuriously fail even when the
575     /// comparison succeeds, which can result in more efficient code on some platforms. The
576     /// return value is a result indicating whether the new value was written and containing the
577     /// previous value.
578     ///
579     /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
580     /// ordering of this operation. The first describes the required ordering if the
581     /// operation succeeds while the second describes the required ordering when the
582     /// operation 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     /// and must be equivalent to or weaker than the success ordering.
586     ///
587     /// [`bool`]: ../../../std/primitive.bool.html
588     /// [`compare_exchange`]: #method.compare_exchange
589     /// [`Ordering`]: enum.Ordering.html
590     /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
591     /// [`Release`]: enum.Ordering.html#variant.Release
592     /// [`Acquire`]: enum.Ordering.html#variant.Acquire
593     /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
594     ///
595     /// # Examples
596     ///
597     /// ```
598     /// use std::sync::atomic::{AtomicBool, Ordering};
599     ///
600     /// let val = AtomicBool::new(false);
601     ///
602     /// let new = true;
603     /// let mut old = val.load(Ordering::Relaxed);
604     /// loop {
605     ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
606     ///         Ok(_) => break,
607     ///         Err(x) => old = x,
608     ///     }
609     /// }
610     /// ```
611     #[inline]
612     #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
613     #[cfg(target_has_atomic = "8")]
614     pub fn compare_exchange_weak(
615         &self,
616         current: bool,
617         new: bool,
618         success: Ordering,
619         failure: Ordering,
620     ) -> Result<bool, bool> {
621         // SAFETY: data races are prevented by atomic intrinsics
622         match unsafe {
623             atomic_compare_exchange_weak(self.v.get(), current as u8, new as u8, success, failure)
624         } {
625             Ok(x) => Ok(x != 0),
626             Err(x) => Err(x != 0),
627         }
628     }
629
630     /// Logical "and" with a boolean value.
631     ///
632     /// Performs a logical "and" operation on the current value and the argument `val`, and sets
633     /// the new value to the result.
634     ///
635     /// Returns the previous value.
636     ///
637     /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
638     /// of this operation. All ordering modes are possible. Note that using
639     /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
640     /// using [`Release`] makes the load part [`Relaxed`].
641     ///
642     /// [`Ordering`]: enum.Ordering.html
643     /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
644     /// [`Release`]: enum.Ordering.html#variant.Release
645     /// [`Acquire`]: enum.Ordering.html#variant.Acquire
646     ///
647     /// # Examples
648     ///
649     /// ```
650     /// use std::sync::atomic::{AtomicBool, Ordering};
651     ///
652     /// let foo = AtomicBool::new(true);
653     /// assert_eq!(foo.fetch_and(false, Ordering::SeqCst), true);
654     /// assert_eq!(foo.load(Ordering::SeqCst), false);
655     ///
656     /// let foo = AtomicBool::new(true);
657     /// assert_eq!(foo.fetch_and(true, Ordering::SeqCst), true);
658     /// assert_eq!(foo.load(Ordering::SeqCst), true);
659     ///
660     /// let foo = AtomicBool::new(false);
661     /// assert_eq!(foo.fetch_and(false, Ordering::SeqCst), false);
662     /// assert_eq!(foo.load(Ordering::SeqCst), false);
663     /// ```
664     #[inline]
665     #[stable(feature = "rust1", since = "1.0.0")]
666     #[cfg(target_has_atomic = "8")]
667     pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
668         // SAFETY: data races are prevented by atomic intrinsics
669         unsafe { atomic_and(self.v.get(), val as u8, order) != 0 }
670     }
671
672     /// Logical "nand" with a boolean value.
673     ///
674     /// Performs a logical "nand" operation on the current value and the argument `val`, and sets
675     /// the new value to the result.
676     ///
677     /// Returns the previous value.
678     ///
679     /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
680     /// of this operation. All ordering modes are possible. Note that using
681     /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
682     /// using [`Release`] makes the load part [`Relaxed`].
683     ///
684     /// [`Ordering`]: enum.Ordering.html
685     /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
686     /// [`Release`]: enum.Ordering.html#variant.Release
687     /// [`Acquire`]: enum.Ordering.html#variant.Acquire
688     ///
689     /// # Examples
690     ///
691     /// ```
692     /// use std::sync::atomic::{AtomicBool, Ordering};
693     ///
694     /// let foo = AtomicBool::new(true);
695     /// assert_eq!(foo.fetch_nand(false, Ordering::SeqCst), true);
696     /// assert_eq!(foo.load(Ordering::SeqCst), true);
697     ///
698     /// let foo = AtomicBool::new(true);
699     /// assert_eq!(foo.fetch_nand(true, Ordering::SeqCst), true);
700     /// assert_eq!(foo.load(Ordering::SeqCst) as usize, 0);
701     /// assert_eq!(foo.load(Ordering::SeqCst), false);
702     ///
703     /// let foo = AtomicBool::new(false);
704     /// assert_eq!(foo.fetch_nand(false, Ordering::SeqCst), false);
705     /// assert_eq!(foo.load(Ordering::SeqCst), true);
706     /// ```
707     #[inline]
708     #[stable(feature = "rust1", since = "1.0.0")]
709     #[cfg(target_has_atomic = "8")]
710     pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
711         // We can't use atomic_nand here because it can result in a bool with
712         // an invalid value. This happens because the atomic operation is done
713         // with an 8-bit integer internally, which would set the upper 7 bits.
714         // So we just use fetch_xor or swap instead.
715         if val {
716             // !(x & true) == !x
717             // We must invert the bool.
718             self.fetch_xor(true, order)
719         } else {
720             // !(x & false) == true
721             // We must set the bool to true.
722             self.swap(true, order)
723         }
724     }
725
726     /// Logical "or" with a boolean value.
727     ///
728     /// Performs a logical "or" operation on the current value and the argument `val`, and sets the
729     /// new value to the result.
730     ///
731     /// Returns the previous value.
732     ///
733     /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
734     /// of this operation. All ordering modes are possible. Note that using
735     /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
736     /// using [`Release`] makes the load part [`Relaxed`].
737     ///
738     /// [`Ordering`]: enum.Ordering.html
739     /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
740     /// [`Release`]: enum.Ordering.html#variant.Release
741     /// [`Acquire`]: enum.Ordering.html#variant.Acquire
742     ///
743     /// # Examples
744     ///
745     /// ```
746     /// use std::sync::atomic::{AtomicBool, Ordering};
747     ///
748     /// let foo = AtomicBool::new(true);
749     /// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), true);
750     /// assert_eq!(foo.load(Ordering::SeqCst), true);
751     ///
752     /// let foo = AtomicBool::new(true);
753     /// assert_eq!(foo.fetch_or(true, Ordering::SeqCst), true);
754     /// assert_eq!(foo.load(Ordering::SeqCst), true);
755     ///
756     /// let foo = AtomicBool::new(false);
757     /// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), false);
758     /// assert_eq!(foo.load(Ordering::SeqCst), false);
759     /// ```
760     #[inline]
761     #[stable(feature = "rust1", since = "1.0.0")]
762     #[cfg(target_has_atomic = "8")]
763     pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
764         // SAFETY: data races are prevented by atomic intrinsics
765         unsafe { atomic_or(self.v.get(), val as u8, order) != 0 }
766     }
767
768     /// Logical "xor" with a boolean value.
769     ///
770     /// Performs a logical "xor" operation on the current value and the argument `val`, and sets
771     /// the new value to the result.
772     ///
773     /// Returns the previous value.
774     ///
775     /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
776     /// of this operation. All ordering modes are possible. Note that using
777     /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
778     /// using [`Release`] makes the load part [`Relaxed`].
779     ///
780     /// [`Ordering`]: enum.Ordering.html
781     /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
782     /// [`Release`]: enum.Ordering.html#variant.Release
783     /// [`Acquire`]: enum.Ordering.html#variant.Acquire
784     ///
785     /// # Examples
786     ///
787     /// ```
788     /// use std::sync::atomic::{AtomicBool, Ordering};
789     ///
790     /// let foo = AtomicBool::new(true);
791     /// assert_eq!(foo.fetch_xor(false, Ordering::SeqCst), true);
792     /// assert_eq!(foo.load(Ordering::SeqCst), true);
793     ///
794     /// let foo = AtomicBool::new(true);
795     /// assert_eq!(foo.fetch_xor(true, Ordering::SeqCst), true);
796     /// assert_eq!(foo.load(Ordering::SeqCst), false);
797     ///
798     /// let foo = AtomicBool::new(false);
799     /// assert_eq!(foo.fetch_xor(false, Ordering::SeqCst), false);
800     /// assert_eq!(foo.load(Ordering::SeqCst), false);
801     /// ```
802     #[inline]
803     #[stable(feature = "rust1", since = "1.0.0")]
804     #[cfg(target_has_atomic = "8")]
805     pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
806         // SAFETY: data races are prevented by atomic intrinsics
807         unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 }
808     }
809
810     /// Returns a mutable pointer to the underlying [`bool`].
811     ///
812     /// Doing non-atomic reads and writes on the resulting integer can be a data race.
813     /// This method is mostly useful for FFI, where the function signature may use
814     /// `*mut bool` instead of `&AtomicBool`.
815     ///
816     /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
817     /// atomic types work with interior mutability. All modifications of an atomic change the value
818     /// through a shared reference, and can do so safely as long as they use atomic operations. Any
819     /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the same
820     /// restriction: operations on it must be atomic.
821     ///
822     /// [`bool`]: ../../../std/primitive.bool.html
823     ///
824     /// # Examples
825     ///
826     /// ```ignore (extern-declaration)
827     /// # fn main() {
828     /// use std::sync::atomic::AtomicBool;
829     /// extern {
830     ///     fn my_atomic_op(arg: *mut bool);
831     /// }
832     ///
833     /// let mut atomic = AtomicBool::new(true);
834     /// unsafe {
835     ///     my_atomic_op(atomic.as_mut_ptr());
836     /// }
837     /// # }
838     /// ```
839     #[inline]
840     #[unstable(feature = "atomic_mut_ptr", reason = "recently added", issue = "66893")]
841     pub fn as_mut_ptr(&self) -> *mut bool {
842         self.v.get() as *mut bool
843     }
844 }
845
846 #[cfg(target_has_atomic_load_store = "ptr")]
847 impl<T> AtomicPtr<T> {
848     /// Creates a new `AtomicPtr`.
849     ///
850     /// # Examples
851     ///
852     /// ```
853     /// use std::sync::atomic::AtomicPtr;
854     ///
855     /// let ptr = &mut 5;
856     /// let atomic_ptr  = AtomicPtr::new(ptr);
857     /// ```
858     #[inline]
859     #[stable(feature = "rust1", since = "1.0.0")]
860     #[rustc_const_stable(feature = "const_atomic_new", since = "1.32.0")]
861     pub const fn new(p: *mut T) -> AtomicPtr<T> {
862         AtomicPtr { p: UnsafeCell::new(p) }
863     }
864
865     /// Returns a mutable reference to the underlying pointer.
866     ///
867     /// This is safe because the mutable reference guarantees that no other threads are
868     /// concurrently accessing the atomic data.
869     ///
870     /// # Examples
871     ///
872     /// ```
873     /// use std::sync::atomic::{AtomicPtr, Ordering};
874     ///
875     /// let mut atomic_ptr = AtomicPtr::new(&mut 10);
876     /// *atomic_ptr.get_mut() = &mut 5;
877     /// assert_eq!(unsafe { *atomic_ptr.load(Ordering::SeqCst) }, 5);
878     /// ```
879     #[inline]
880     #[stable(feature = "atomic_access", since = "1.15.0")]
881     pub fn get_mut(&mut self) -> &mut *mut T {
882         // SAFETY: the mutable reference guarantees unique ownership
883         unsafe { &mut *self.p.get() }
884     }
885
886     /// Consumes the atomic and returns the contained value.
887     ///
888     /// This is safe because passing `self` by value guarantees that no other threads are
889     /// concurrently accessing the atomic data.
890     ///
891     /// # Examples
892     ///
893     /// ```
894     /// use std::sync::atomic::AtomicPtr;
895     ///
896     /// let atomic_ptr = AtomicPtr::new(&mut 5);
897     /// assert_eq!(unsafe { *atomic_ptr.into_inner() }, 5);
898     /// ```
899     #[inline]
900     #[stable(feature = "atomic_access", since = "1.15.0")]
901     pub fn into_inner(self) -> *mut T {
902         self.p.into_inner()
903     }
904
905     /// Loads a value from the pointer.
906     ///
907     /// `load` takes an [`Ordering`] argument which describes the memory ordering
908     /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
909     ///
910     /// # Panics
911     ///
912     /// Panics if `order` is [`Release`] or [`AcqRel`].
913     ///
914     /// [`Ordering`]: enum.Ordering.html
915     /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
916     /// [`Release`]: enum.Ordering.html#variant.Release
917     /// [`Acquire`]: enum.Ordering.html#variant.Acquire
918     /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
919     /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
920     ///
921     /// # Examples
922     ///
923     /// ```
924     /// use std::sync::atomic::{AtomicPtr, Ordering};
925     ///
926     /// let ptr = &mut 5;
927     /// let some_ptr  = AtomicPtr::new(ptr);
928     ///
929     /// let value = some_ptr.load(Ordering::Relaxed);
930     /// ```
931     #[inline]
932     #[stable(feature = "rust1", since = "1.0.0")]
933     pub fn load(&self, order: Ordering) -> *mut T {
934         // SAFETY: data races are prevented by atomic intrinsics
935         unsafe { atomic_load(self.p.get() as *mut usize, order) as *mut T }
936     }
937
938     /// Stores a value into the pointer.
939     ///
940     /// `store` takes an [`Ordering`] argument which describes the memory ordering
941     /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
942     ///
943     /// # Panics
944     ///
945     /// Panics if `order` is [`Acquire`] or [`AcqRel`].
946     ///
947     /// [`Ordering`]: enum.Ordering.html
948     /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
949     /// [`Release`]: enum.Ordering.html#variant.Release
950     /// [`Acquire`]: enum.Ordering.html#variant.Acquire
951     /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
952     /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
953     ///
954     /// # Examples
955     ///
956     /// ```
957     /// use std::sync::atomic::{AtomicPtr, Ordering};
958     ///
959     /// let ptr = &mut 5;
960     /// let some_ptr  = AtomicPtr::new(ptr);
961     ///
962     /// let other_ptr = &mut 10;
963     ///
964     /// some_ptr.store(other_ptr, Ordering::Relaxed);
965     /// ```
966     #[inline]
967     #[stable(feature = "rust1", since = "1.0.0")]
968     pub fn store(&self, ptr: *mut T, order: Ordering) {
969         // SAFETY: data races are prevented by atomic intrinsics
970         unsafe {
971             atomic_store(self.p.get() as *mut usize, ptr as usize, order);
972         }
973     }
974
975     /// Stores a value into the pointer, returning the previous value.
976     ///
977     /// `swap` takes an [`Ordering`] argument which describes the memory ordering
978     /// of this operation. All ordering modes are possible. Note that using
979     /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
980     /// using [`Release`] makes the load part [`Relaxed`].
981     ///
982     /// [`Ordering`]: enum.Ordering.html
983     /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
984     /// [`Release`]: enum.Ordering.html#variant.Release
985     /// [`Acquire`]: enum.Ordering.html#variant.Acquire
986     ///
987     /// # Examples
988     ///
989     /// ```
990     /// use std::sync::atomic::{AtomicPtr, Ordering};
991     ///
992     /// let ptr = &mut 5;
993     /// let some_ptr  = AtomicPtr::new(ptr);
994     ///
995     /// let other_ptr = &mut 10;
996     ///
997     /// let value = some_ptr.swap(other_ptr, Ordering::Relaxed);
998     /// ```
999     #[inline]
1000     #[stable(feature = "rust1", since = "1.0.0")]
1001     #[cfg(target_has_atomic = "ptr")]
1002     pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
1003         // SAFETY: data races are prevented by atomic intrinsics
1004         unsafe { atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T }
1005     }
1006
1007     /// Stores a value into the pointer if the current value is the same as the `current` value.
1008     ///
1009     /// The return value is always the previous value. If it is equal to `current`, then the value
1010     /// was updated.
1011     ///
1012     /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
1013     /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
1014     /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
1015     /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
1016     /// happens, and using [`Release`] makes the load part [`Relaxed`].
1017     ///
1018     /// [`Ordering`]: enum.Ordering.html
1019     /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1020     /// [`Release`]: enum.Ordering.html#variant.Release
1021     /// [`Acquire`]: enum.Ordering.html#variant.Acquire
1022     /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
1023     ///
1024     /// # Examples
1025     ///
1026     /// ```
1027     /// use std::sync::atomic::{AtomicPtr, Ordering};
1028     ///
1029     /// let ptr = &mut 5;
1030     /// let some_ptr  = AtomicPtr::new(ptr);
1031     ///
1032     /// let other_ptr   = &mut 10;
1033     ///
1034     /// let value = some_ptr.compare_and_swap(ptr, other_ptr, Ordering::Relaxed);
1035     /// ```
1036     #[inline]
1037     #[stable(feature = "rust1", since = "1.0.0")]
1038     #[cfg(target_has_atomic = "ptr")]
1039     pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) -> *mut T {
1040         match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
1041             Ok(x) => x,
1042             Err(x) => x,
1043         }
1044     }
1045
1046     /// Stores a value into the pointer if the current value is the same as the `current` value.
1047     ///
1048     /// The return value is a result indicating whether the new value was written and containing
1049     /// the previous value. On success this value is guaranteed to be equal to `current`.
1050     ///
1051     /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
1052     /// ordering of this operation. The first describes the required ordering if the
1053     /// operation succeeds while the second describes the required ordering when the
1054     /// operation fails. Using [`Acquire`] as success ordering makes the store part
1055     /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
1056     /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]
1057     /// and must be equivalent to or weaker than the success ordering.
1058     ///
1059     /// [`Ordering`]: enum.Ordering.html
1060     /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1061     /// [`Release`]: enum.Ordering.html#variant.Release
1062     /// [`Acquire`]: enum.Ordering.html#variant.Acquire
1063     /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
1064     ///
1065     /// # Examples
1066     ///
1067     /// ```
1068     /// use std::sync::atomic::{AtomicPtr, Ordering};
1069     ///
1070     /// let ptr = &mut 5;
1071     /// let some_ptr  = AtomicPtr::new(ptr);
1072     ///
1073     /// let other_ptr   = &mut 10;
1074     ///
1075     /// let value = some_ptr.compare_exchange(ptr, other_ptr,
1076     ///                                       Ordering::SeqCst, Ordering::Relaxed);
1077     /// ```
1078     #[inline]
1079     #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
1080     #[cfg(target_has_atomic = "ptr")]
1081     pub fn compare_exchange(
1082         &self,
1083         current: *mut T,
1084         new: *mut T,
1085         success: Ordering,
1086         failure: Ordering,
1087     ) -> Result<*mut T, *mut T> {
1088         // SAFETY: data races are prevented by atomic intrinsics
1089         unsafe {
1090             let res = atomic_compare_exchange(
1091                 self.p.get() as *mut usize,
1092                 current as usize,
1093                 new as usize,
1094                 success,
1095                 failure,
1096             );
1097             match res {
1098                 Ok(x) => Ok(x as *mut T),
1099                 Err(x) => Err(x as *mut T),
1100             }
1101         }
1102     }
1103
1104     /// Stores a value into the pointer if the current value is the same as the `current` value.
1105     ///
1106     /// Unlike [`compare_exchange`], this function is allowed to spuriously fail even when the
1107     /// comparison succeeds, which can result in more efficient code on some platforms. The
1108     /// return value is a result indicating whether the new value was written and containing the
1109     /// previous value.
1110     ///
1111     /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
1112     /// ordering of this operation. The first describes the required ordering if the
1113     /// operation succeeds while the second describes the required ordering when the
1114     /// operation fails. Using [`Acquire`] as success ordering makes the store part
1115     /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
1116     /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]
1117     /// and must be equivalent to or weaker than the success ordering.
1118     ///
1119     /// [`compare_exchange`]: #method.compare_exchange
1120     /// [`Ordering`]: enum.Ordering.html
1121     /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1122     /// [`Release`]: enum.Ordering.html#variant.Release
1123     /// [`Acquire`]: enum.Ordering.html#variant.Acquire
1124     /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
1125     ///
1126     /// # Examples
1127     ///
1128     /// ```
1129     /// use std::sync::atomic::{AtomicPtr, Ordering};
1130     ///
1131     /// let some_ptr = AtomicPtr::new(&mut 5);
1132     ///
1133     /// let new = &mut 10;
1134     /// let mut old = some_ptr.load(Ordering::Relaxed);
1135     /// loop {
1136     ///     match some_ptr.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
1137     ///         Ok(_) => break,
1138     ///         Err(x) => old = x,
1139     ///     }
1140     /// }
1141     /// ```
1142     #[inline]
1143     #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
1144     #[cfg(target_has_atomic = "ptr")]
1145     pub fn compare_exchange_weak(
1146         &self,
1147         current: *mut T,
1148         new: *mut T,
1149         success: Ordering,
1150         failure: Ordering,
1151     ) -> Result<*mut T, *mut T> {
1152         // SAFETY: data races are prevented by atomic intrinsics
1153         unsafe {
1154             let res = atomic_compare_exchange_weak(
1155                 self.p.get() as *mut usize,
1156                 current as usize,
1157                 new as usize,
1158                 success,
1159                 failure,
1160             );
1161             match res {
1162                 Ok(x) => Ok(x as *mut T),
1163                 Err(x) => Err(x as *mut T),
1164             }
1165         }
1166     }
1167 }
1168
1169 #[cfg(target_has_atomic_load_store = "8")]
1170 #[stable(feature = "atomic_bool_from", since = "1.24.0")]
1171 impl From<bool> for AtomicBool {
1172     /// Converts a `bool` into an `AtomicBool`.
1173     ///
1174     /// # Examples
1175     ///
1176     /// ```
1177     /// use std::sync::atomic::AtomicBool;
1178     /// let atomic_bool = AtomicBool::from(true);
1179     /// assert_eq!(format!("{:?}", atomic_bool), "true")
1180     /// ```
1181     #[inline]
1182     fn from(b: bool) -> Self {
1183         Self::new(b)
1184     }
1185 }
1186
1187 #[cfg(target_has_atomic_load_store = "ptr")]
1188 #[stable(feature = "atomic_from", since = "1.23.0")]
1189 impl<T> From<*mut T> for AtomicPtr<T> {
1190     #[inline]
1191     fn from(p: *mut T) -> Self {
1192         Self::new(p)
1193     }
1194 }
1195
1196 #[cfg(target_has_atomic_load_store = "8")]
1197 macro_rules! atomic_int {
1198     ($cfg_cas:meta,
1199      $stable:meta,
1200      $stable_cxchg:meta,
1201      $stable_debug:meta,
1202      $stable_access:meta,
1203      $stable_from:meta,
1204      $stable_nand:meta,
1205      $const_stable:meta,
1206      $stable_init_const:meta,
1207      $s_int_type:expr, $int_ref:expr,
1208      $extra_feature:expr,
1209      $min_fn:ident, $max_fn:ident,
1210      $align:expr,
1211      $atomic_new:expr,
1212      $int_type:ident $atomic_type:ident $atomic_init:ident) => {
1213         /// An integer type which can be safely shared between threads.
1214         ///
1215         /// This type has the same in-memory representation as the underlying
1216         /// integer type, [`
1217         #[doc = $s_int_type]
1218         /// `](
1219         #[doc = $int_ref]
1220         /// ). For more about the differences between atomic types and
1221         /// non-atomic types as well as information about the portability of
1222         /// this type, please see the [module-level documentation].
1223         ///
1224         /// [module-level documentation]: index.html
1225         #[$stable]
1226         #[repr(C, align($align))]
1227         pub struct $atomic_type {
1228             v: UnsafeCell<$int_type>,
1229         }
1230
1231         /// An atomic integer initialized to `0`.
1232         #[$stable_init_const]
1233         #[rustc_deprecated(
1234             since = "1.34.0",
1235             reason = "the `new` function is now preferred",
1236             suggestion = $atomic_new,
1237         )]
1238         pub const $atomic_init: $atomic_type = $atomic_type::new(0);
1239
1240         #[$stable]
1241         impl Default for $atomic_type {
1242             fn default() -> Self {
1243                 Self::new(Default::default())
1244             }
1245         }
1246
1247         #[$stable_from]
1248         impl From<$int_type> for $atomic_type {
1249             doc_comment! {
1250                 concat!(
1251 "Converts an `", stringify!($int_type), "` into an `", stringify!($atomic_type), "`."),
1252                 #[inline]
1253                 fn from(v: $int_type) -> Self { Self::new(v) }
1254             }
1255         }
1256
1257         #[$stable_debug]
1258         impl fmt::Debug for $atomic_type {
1259             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1260                 fmt::Debug::fmt(&self.load(Ordering::SeqCst), f)
1261             }
1262         }
1263
1264         // Send is implicitly implemented.
1265         #[$stable]
1266         unsafe impl Sync for $atomic_type {}
1267
1268         impl $atomic_type {
1269             doc_comment! {
1270                 concat!("Creates a new atomic integer.
1271
1272 # Examples
1273
1274 ```
1275 ", $extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";
1276
1277 let atomic_forty_two = ", stringify!($atomic_type), "::new(42);
1278 ```"),
1279                 #[inline]
1280                 #[$stable]
1281                 #[$const_stable]
1282                 pub const fn new(v: $int_type) -> Self {
1283                     Self {v: UnsafeCell::new(v)}
1284                 }
1285             }
1286
1287             doc_comment! {
1288                 concat!("Returns a mutable reference to the underlying integer.
1289
1290 This is safe because the mutable reference guarantees that no other threads are
1291 concurrently accessing the atomic data.
1292
1293 # Examples
1294
1295 ```
1296 ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
1297
1298 let mut some_var = ", stringify!($atomic_type), "::new(10);
1299 assert_eq!(*some_var.get_mut(), 10);
1300 *some_var.get_mut() = 5;
1301 assert_eq!(some_var.load(Ordering::SeqCst), 5);
1302 ```"),
1303                 #[inline]
1304                 #[$stable_access]
1305                 pub fn get_mut(&mut self) -> &mut $int_type {
1306                     // SAFETY: the mutable reference guarantees unique ownership
1307                     unsafe { &mut *self.v.get() }
1308                 }
1309             }
1310
1311             doc_comment! {
1312                 concat!("Consumes the atomic and returns the contained value.
1313
1314 This is safe because passing `self` by value guarantees that no other threads are
1315 concurrently accessing the atomic data.
1316
1317 # Examples
1318
1319 ```
1320 ", $extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";
1321
1322 let some_var = ", stringify!($atomic_type), "::new(5);
1323 assert_eq!(some_var.into_inner(), 5);
1324 ```"),
1325                 #[inline]
1326                 #[$stable_access]
1327                 pub fn into_inner(self) -> $int_type {
1328                     self.v.into_inner()
1329                 }
1330             }
1331
1332             doc_comment! {
1333                 concat!("Loads a value from the atomic integer.
1334
1335 `load` takes an [`Ordering`] argument which describes the memory ordering of this operation.
1336 Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
1337
1338 # Panics
1339
1340 Panics if `order` is [`Release`] or [`AcqRel`].
1341
1342 [`Ordering`]: enum.Ordering.html
1343 [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1344 [`Release`]: enum.Ordering.html#variant.Release
1345 [`Acquire`]: enum.Ordering.html#variant.Acquire
1346 [`AcqRel`]: enum.Ordering.html#variant.AcqRel
1347 [`SeqCst`]: enum.Ordering.html#variant.SeqCst
1348
1349 # Examples
1350
1351 ```
1352 ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
1353
1354 let some_var = ", stringify!($atomic_type), "::new(5);
1355
1356 assert_eq!(some_var.load(Ordering::Relaxed), 5);
1357 ```"),
1358                 #[inline]
1359                 #[$stable]
1360                 pub fn load(&self, order: Ordering) -> $int_type {
1361                     // SAFETY: data races are prevented by atomic intrinsics
1362                     unsafe { atomic_load(self.v.get(), order) }
1363                 }
1364             }
1365
1366             doc_comment! {
1367                 concat!("Stores a value into the atomic integer.
1368
1369 `store` takes an [`Ordering`] argument which describes the memory ordering of this operation.
1370  Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
1371
1372 # Panics
1373
1374 Panics if `order` is [`Acquire`] or [`AcqRel`].
1375
1376 [`Ordering`]: enum.Ordering.html
1377 [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1378 [`Release`]: enum.Ordering.html#variant.Release
1379 [`Acquire`]: enum.Ordering.html#variant.Acquire
1380 [`AcqRel`]: enum.Ordering.html#variant.AcqRel
1381 [`SeqCst`]: enum.Ordering.html#variant.SeqCst
1382
1383 # Examples
1384
1385 ```
1386 ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
1387
1388 let some_var = ", stringify!($atomic_type), "::new(5);
1389
1390 some_var.store(10, Ordering::Relaxed);
1391 assert_eq!(some_var.load(Ordering::Relaxed), 10);
1392 ```"),
1393                 #[inline]
1394                 #[$stable]
1395                 pub fn store(&self, val: $int_type, order: Ordering) {
1396                     // SAFETY: data races are prevented by atomic intrinsics
1397                     unsafe { atomic_store(self.v.get(), val, order); }
1398                 }
1399             }
1400
1401             doc_comment! {
1402                 concat!("Stores a value into the atomic integer, returning the previous value.
1403
1404 `swap` takes an [`Ordering`] argument which describes the memory ordering
1405 of this operation. All ordering modes are possible. Note that using
1406 [`Acquire`] makes the store part of this operation [`Relaxed`], and
1407 using [`Release`] makes the load part [`Relaxed`].
1408
1409 [`Ordering`]: enum.Ordering.html
1410 [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1411 [`Release`]: enum.Ordering.html#variant.Release
1412 [`Acquire`]: enum.Ordering.html#variant.Acquire
1413
1414 # Examples
1415
1416 ```
1417 ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
1418
1419 let some_var = ", stringify!($atomic_type), "::new(5);
1420
1421 assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
1422 ```"),
1423                 #[inline]
1424                 #[$stable]
1425                 #[$cfg_cas]
1426                 pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
1427                     // SAFETY: data races are prevented by atomic intrinsics
1428                     unsafe { atomic_swap(self.v.get(), val, order) }
1429                 }
1430             }
1431
1432             doc_comment! {
1433                 concat!("Stores a value into the atomic integer if the current value is the same as
1434 the `current` value.
1435
1436 The return value is always the previous value. If it is equal to `current`, then the
1437 value was updated.
1438
1439 `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
1440 ordering of this operation. Notice that even when using [`AcqRel`], the operation
1441 might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
1442 Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
1443 happens, and using [`Release`] makes the load part [`Relaxed`].
1444
1445 [`Ordering`]: enum.Ordering.html
1446 [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1447 [`Release`]: enum.Ordering.html#variant.Release
1448 [`Acquire`]: enum.Ordering.html#variant.Acquire
1449 [`AcqRel`]: enum.Ordering.html#variant.AcqRel
1450
1451 # Examples
1452
1453 ```
1454 ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
1455
1456 let some_var = ", stringify!($atomic_type), "::new(5);
1457
1458 assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5);
1459 assert_eq!(some_var.load(Ordering::Relaxed), 10);
1460
1461 assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10);
1462 assert_eq!(some_var.load(Ordering::Relaxed), 10);
1463 ```"),
1464                 #[inline]
1465                 #[$stable]
1466                 #[$cfg_cas]
1467                 pub fn compare_and_swap(&self,
1468                                         current: $int_type,
1469                                         new: $int_type,
1470                                         order: Ordering) -> $int_type {
1471                     match self.compare_exchange(current,
1472                                                 new,
1473                                                 order,
1474                                                 strongest_failure_ordering(order)) {
1475                         Ok(x) => x,
1476                         Err(x) => x,
1477                     }
1478                 }
1479             }
1480
1481             doc_comment! {
1482                 concat!("Stores a value into the atomic integer if the current value is the same as
1483 the `current` value.
1484
1485 The return value is a result indicating whether the new value was written and
1486 containing the previous value. On success this value is guaranteed to be equal to
1487 `current`.
1488
1489 `compare_exchange` takes two [`Ordering`] arguments to describe the memory
1490 ordering of this operation. The first describes the required ordering if the
1491 operation succeeds while the second describes the required ordering when the
1492 operation fails. Using [`Acquire`] as success ordering makes the store part
1493 of this operation [`Relaxed`], and using [`Release`] makes the successful load
1494 [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]
1495 and must be equivalent to or weaker than the success ordering.
1496
1497 [`Ordering`]: enum.Ordering.html
1498 [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1499 [`Release`]: enum.Ordering.html#variant.Release
1500 [`Acquire`]: enum.Ordering.html#variant.Acquire
1501 [`SeqCst`]: enum.Ordering.html#variant.SeqCst
1502
1503 # Examples
1504
1505 ```
1506 ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
1507
1508 let some_var = ", stringify!($atomic_type), "::new(5);
1509
1510 assert_eq!(some_var.compare_exchange(5, 10,
1511                                      Ordering::Acquire,
1512                                      Ordering::Relaxed),
1513            Ok(5));
1514 assert_eq!(some_var.load(Ordering::Relaxed), 10);
1515
1516 assert_eq!(some_var.compare_exchange(6, 12,
1517                                      Ordering::SeqCst,
1518                                      Ordering::Acquire),
1519            Err(10));
1520 assert_eq!(some_var.load(Ordering::Relaxed), 10);
1521 ```"),
1522                 #[inline]
1523                 #[$stable_cxchg]
1524                 #[$cfg_cas]
1525                 pub fn compare_exchange(&self,
1526                                         current: $int_type,
1527                                         new: $int_type,
1528                                         success: Ordering,
1529                                         failure: Ordering) -> Result<$int_type, $int_type> {
1530                     // SAFETY: data races are prevented by atomic intrinsics
1531                     unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) }
1532                 }
1533             }
1534
1535             doc_comment! {
1536                 concat!("Stores a value into the atomic integer if the current value is the same as
1537 the `current` value.
1538
1539 Unlike [`compare_exchange`], this function is allowed to spuriously fail even
1540 when the comparison succeeds, which can result in more efficient code on some
1541 platforms. The return value is a result indicating whether the new value was
1542 written and containing the previous value.
1543
1544 `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
1545 ordering of this operation. The first describes the required ordering if the
1546 operation succeeds while the second describes the required ordering when the
1547 operation fails. Using [`Acquire`] as success ordering makes the store part
1548 of this operation [`Relaxed`], and using [`Release`] makes the successful load
1549 [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]
1550 and must be equivalent to or weaker than the success ordering.
1551
1552 [`compare_exchange`]: #method.compare_exchange
1553 [`Ordering`]: enum.Ordering.html
1554 [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1555 [`Release`]: enum.Ordering.html#variant.Release
1556 [`Acquire`]: enum.Ordering.html#variant.Acquire
1557 [`SeqCst`]: enum.Ordering.html#variant.SeqCst
1558
1559 # Examples
1560
1561 ```
1562 ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
1563
1564 let val = ", stringify!($atomic_type), "::new(4);
1565
1566 let mut old = val.load(Ordering::Relaxed);
1567 loop {
1568     let new = old * 2;
1569     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
1570         Ok(_) => break,
1571         Err(x) => old = x,
1572     }
1573 }
1574 ```"),
1575                 #[inline]
1576                 #[$stable_cxchg]
1577                 #[$cfg_cas]
1578                 pub fn compare_exchange_weak(&self,
1579                                              current: $int_type,
1580                                              new: $int_type,
1581                                              success: Ordering,
1582                                              failure: Ordering) -> Result<$int_type, $int_type> {
1583                     // SAFETY: data races are prevented by atomic intrinsics
1584                     unsafe {
1585                         atomic_compare_exchange_weak(self.v.get(), current, new, success, failure)
1586                     }
1587                 }
1588             }
1589
1590             doc_comment! {
1591                 concat!("Adds to the current value, returning the previous value.
1592
1593 This operation wraps around on overflow.
1594
1595 `fetch_add` takes an [`Ordering`] argument which describes the memory ordering
1596 of this operation. All ordering modes are possible. Note that using
1597 [`Acquire`] makes the store part of this operation [`Relaxed`], and
1598 using [`Release`] makes the load part [`Relaxed`].
1599
1600 [`Ordering`]: enum.Ordering.html
1601 [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1602 [`Release`]: enum.Ordering.html#variant.Release
1603 [`Acquire`]: enum.Ordering.html#variant.Acquire
1604
1605 # Examples
1606
1607 ```
1608 ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
1609
1610 let foo = ", stringify!($atomic_type), "::new(0);
1611 assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
1612 assert_eq!(foo.load(Ordering::SeqCst), 10);
1613 ```"),
1614                 #[inline]
1615                 #[$stable]
1616                 #[$cfg_cas]
1617                 pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
1618                     // SAFETY: data races are prevented by atomic intrinsics
1619                     unsafe { atomic_add(self.v.get(), val, order) }
1620                 }
1621             }
1622
1623             doc_comment! {
1624                 concat!("Subtracts from the current value, returning the previous value.
1625
1626 This operation wraps around on overflow.
1627
1628 `fetch_sub` takes an [`Ordering`] argument which describes the memory ordering
1629 of this operation. All ordering modes are possible. Note that using
1630 [`Acquire`] makes the store part of this operation [`Relaxed`], and
1631 using [`Release`] makes the load part [`Relaxed`].
1632
1633 [`Ordering`]: enum.Ordering.html
1634 [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1635 [`Release`]: enum.Ordering.html#variant.Release
1636 [`Acquire`]: enum.Ordering.html#variant.Acquire
1637
1638 # Examples
1639
1640 ```
1641 ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
1642
1643 let foo = ", stringify!($atomic_type), "::new(20);
1644 assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);
1645 assert_eq!(foo.load(Ordering::SeqCst), 10);
1646 ```"),
1647                 #[inline]
1648                 #[$stable]
1649                 #[$cfg_cas]
1650                 pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
1651                     // SAFETY: data races are prevented by atomic intrinsics
1652                     unsafe { atomic_sub(self.v.get(), val, order) }
1653                 }
1654             }
1655
1656             doc_comment! {
1657                 concat!("Bitwise \"and\" with the current value.
1658
1659 Performs a bitwise \"and\" operation on the current value and the argument `val`, and
1660 sets the new value to the result.
1661
1662 Returns the previous value.
1663
1664 `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
1665 of this operation. All ordering modes are possible. Note that using
1666 [`Acquire`] makes the store part of this operation [`Relaxed`], and
1667 using [`Release`] makes the load part [`Relaxed`].
1668
1669 [`Ordering`]: enum.Ordering.html
1670 [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1671 [`Release`]: enum.Ordering.html#variant.Release
1672 [`Acquire`]: enum.Ordering.html#variant.Acquire
1673
1674 # Examples
1675
1676 ```
1677 ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
1678
1679 let foo = ", stringify!($atomic_type), "::new(0b101101);
1680 assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
1681 assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
1682 ```"),
1683                 #[inline]
1684                 #[$stable]
1685                 #[$cfg_cas]
1686                 pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
1687                     // SAFETY: data races are prevented by atomic intrinsics
1688                     unsafe { atomic_and(self.v.get(), val, order) }
1689                 }
1690             }
1691
1692             doc_comment! {
1693                 concat!("Bitwise \"nand\" with the current value.
1694
1695 Performs a bitwise \"nand\" operation on the current value and the argument `val`, and
1696 sets the new value to the result.
1697
1698 Returns the previous value.
1699
1700 `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
1701 of this operation. All ordering modes are possible. Note that using
1702 [`Acquire`] makes the store part of this operation [`Relaxed`], and
1703 using [`Release`] makes the load part [`Relaxed`].
1704
1705 [`Ordering`]: enum.Ordering.html
1706 [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1707 [`Release`]: enum.Ordering.html#variant.Release
1708 [`Acquire`]: enum.Ordering.html#variant.Acquire
1709
1710 # Examples
1711
1712 ```
1713 ", $extra_feature, "
1714 use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
1715
1716 let foo = ", stringify!($atomic_type), "::new(0x13);
1717 assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);
1718 assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
1719 ```"),
1720                 #[inline]
1721                 #[$stable_nand]
1722                 #[$cfg_cas]
1723                 pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
1724                     // SAFETY: data races are prevented by atomic intrinsics
1725                     unsafe { atomic_nand(self.v.get(), val, order) }
1726                 }
1727             }
1728
1729             doc_comment! {
1730                 concat!("Bitwise \"or\" with the current value.
1731
1732 Performs a bitwise \"or\" operation on the current value and the argument `val`, and
1733 sets the new value to the result.
1734
1735 Returns the previous value.
1736
1737 `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
1738 of this operation. All ordering modes are possible. Note that using
1739 [`Acquire`] makes the store part of this operation [`Relaxed`], and
1740 using [`Release`] makes the load part [`Relaxed`].
1741
1742 [`Ordering`]: enum.Ordering.html
1743 [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1744 [`Release`]: enum.Ordering.html#variant.Release
1745 [`Acquire`]: enum.Ordering.html#variant.Acquire
1746
1747 # Examples
1748
1749 ```
1750 ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
1751
1752 let foo = ", stringify!($atomic_type), "::new(0b101101);
1753 assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
1754 assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
1755 ```"),
1756                 #[inline]
1757                 #[$stable]
1758                 #[$cfg_cas]
1759                 pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
1760                     // SAFETY: data races are prevented by atomic intrinsics
1761                     unsafe { atomic_or(self.v.get(), val, order) }
1762                 }
1763             }
1764
1765             doc_comment! {
1766                 concat!("Bitwise \"xor\" with the current value.
1767
1768 Performs a bitwise \"xor\" operation on the current value and the argument `val`, and
1769 sets the new value to the result.
1770
1771 Returns the previous value.
1772
1773 `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
1774 of this operation. All ordering modes are possible. Note that using
1775 [`Acquire`] makes the store part of this operation [`Relaxed`], and
1776 using [`Release`] makes the load part [`Relaxed`].
1777
1778 [`Ordering`]: enum.Ordering.html
1779 [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1780 [`Release`]: enum.Ordering.html#variant.Release
1781 [`Acquire`]: enum.Ordering.html#variant.Acquire
1782
1783 # Examples
1784
1785 ```
1786 ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
1787
1788 let foo = ", stringify!($atomic_type), "::new(0b101101);
1789 assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
1790 assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
1791 ```"),
1792                 #[inline]
1793                 #[$stable]
1794                 #[$cfg_cas]
1795                 pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
1796                     // SAFETY: data races are prevented by atomic intrinsics
1797                     unsafe { atomic_xor(self.v.get(), val, order) }
1798                 }
1799             }
1800
1801             doc_comment! {
1802                 concat!("Fetches the value, and applies a function to it that returns an optional
1803 new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else
1804 `Err(previous_value)`.
1805
1806 Note: This may call the function multiple times if the value has been changed from other threads in
1807 the meantime, as long as the function returns `Some(_)`, but the function will have been applied
1808 but once to the stored value.
1809
1810 `fetch_update` takes two [`Ordering`] arguments to describe the memory
1811 ordering of this operation. The first describes the required ordering for loads
1812 and failed updates while the second describes the required ordering when the
1813 operation finally succeeds. Beware that this is different from the two
1814 modes in [`compare_exchange`]!
1815
1816 Using [`Acquire`] as success ordering makes the store part
1817 of this operation [`Relaxed`], and using [`Release`] makes the final successful load
1818 [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]
1819 and must be equivalent to or weaker than the success ordering.
1820
1821 [`bool`]: ../../../std/primitive.bool.html
1822 [`compare_exchange`]: #method.compare_exchange
1823 [`Ordering`]: enum.Ordering.html
1824 [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1825 [`Release`]: enum.Ordering.html#variant.Release
1826 [`Acquire`]: enum.Ordering.html#variant.Acquire
1827 [`SeqCst`]: enum.Ordering.html#variant.SeqCst
1828
1829 # Examples
1830
1831 ```rust
1832 #![feature(no_more_cas)]
1833 ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
1834
1835 let x = ", stringify!($atomic_type), "::new(7);
1836 assert_eq!(x.fetch_update(|_| None, Ordering::SeqCst, Ordering::SeqCst), Err(7));
1837 assert_eq!(x.fetch_update(|x| Some(x + 1), Ordering::SeqCst, Ordering::SeqCst), Ok(7));
1838 assert_eq!(x.fetch_update(|x| Some(x + 1), Ordering::SeqCst, Ordering::SeqCst), Ok(8));
1839 assert_eq!(x.load(Ordering::SeqCst), 9);
1840 ```"),
1841                 #[inline]
1842                 #[unstable(feature = "no_more_cas",
1843                        reason = "no more CAS loops in user code",
1844                        issue = "48655")]
1845                 #[$cfg_cas]
1846                 pub fn fetch_update<F>(&self,
1847                                        mut f: F,
1848                                        fetch_order: Ordering,
1849                                        set_order: Ordering) -> Result<$int_type, $int_type>
1850                 where F: FnMut($int_type) -> Option<$int_type> {
1851                     let mut prev = self.load(fetch_order);
1852                     while let Some(next) = f(prev) {
1853                         match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
1854                             x @ Ok(_) => return x,
1855                             Err(next_prev) => prev = next_prev
1856                         }
1857                     }
1858                     Err(prev)
1859                 }
1860             }
1861
1862             doc_comment! {
1863                 concat!("Maximum with the current value.
1864
1865 Finds the maximum of the current value and the argument `val`, and
1866 sets the new value to the result.
1867
1868 Returns the previous value.
1869
1870 `fetch_max` takes an [`Ordering`] argument which describes the memory ordering
1871 of this operation. All ordering modes are possible. Note that using
1872 [`Acquire`] makes the store part of this operation [`Relaxed`], and
1873 using [`Release`] makes the load part [`Relaxed`].
1874
1875 [`Ordering`]: enum.Ordering.html
1876 [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1877 [`Release`]: enum.Ordering.html#variant.Release
1878 [`Acquire`]: enum.Ordering.html#variant.Acquire
1879
1880 # Examples
1881
1882 ```
1883 #![feature(atomic_min_max)]
1884 ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
1885
1886 let foo = ", stringify!($atomic_type), "::new(23);
1887 assert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23);
1888 assert_eq!(foo.load(Ordering::SeqCst), 42);
1889 ```
1890
1891 If you want to obtain the maximum value in one step, you can use the following:
1892
1893 ```
1894 #![feature(atomic_min_max)]
1895 ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
1896
1897 let foo = ", stringify!($atomic_type), "::new(23);
1898 let bar = 42;
1899 let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar);
1900 assert!(max_foo == 42);
1901 ```"),
1902                 #[inline]
1903                 #[unstable(feature = "atomic_min_max",
1904                        reason = "easier and faster min/max than writing manual CAS loop",
1905                        issue = "48655")]
1906                 #[$cfg_cas]
1907                 pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {
1908                     // SAFETY: data races are prevented by atomic intrinsics
1909                     unsafe { $max_fn(self.v.get(), val, order) }
1910                 }
1911             }
1912
1913             doc_comment! {
1914                 concat!("Minimum with the current value.
1915
1916 Finds the minimum of the current value and the argument `val`, and
1917 sets the new value to the result.
1918
1919 Returns the previous value.
1920
1921 `fetch_min` takes an [`Ordering`] argument which describes the memory ordering
1922 of this operation. All ordering modes are possible. Note that using
1923 [`Acquire`] makes the store part of this operation [`Relaxed`], and
1924 using [`Release`] makes the load part [`Relaxed`].
1925
1926 [`Ordering`]: enum.Ordering.html
1927 [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1928 [`Release`]: enum.Ordering.html#variant.Release
1929 [`Acquire`]: enum.Ordering.html#variant.Acquire
1930
1931 # Examples
1932
1933 ```
1934 #![feature(atomic_min_max)]
1935 ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
1936
1937 let foo = ", stringify!($atomic_type), "::new(23);
1938 assert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23);
1939 assert_eq!(foo.load(Ordering::Relaxed), 23);
1940 assert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23);
1941 assert_eq!(foo.load(Ordering::Relaxed), 22);
1942 ```
1943
1944 If you want to obtain the minimum value in one step, you can use the following:
1945
1946 ```
1947 #![feature(atomic_min_max)]
1948 ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
1949
1950 let foo = ", stringify!($atomic_type), "::new(23);
1951 let bar = 12;
1952 let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar);
1953 assert_eq!(min_foo, 12);
1954 ```"),
1955                 #[inline]
1956                 #[unstable(feature = "atomic_min_max",
1957                        reason = "easier and faster min/max than writing manual CAS loop",
1958                        issue = "48655")]
1959                 #[$cfg_cas]
1960                 pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {
1961                     // SAFETY: data races are prevented by atomic intrinsics
1962                     unsafe { $min_fn(self.v.get(), val, order) }
1963                 }
1964             }
1965
1966             doc_comment! {
1967                 concat!("Returns a mutable pointer to the underlying integer.
1968
1969 Doing non-atomic reads and writes on the resulting integer can be a data race.
1970 This method is mostly useful for FFI, where the function signature may use
1971 `*mut ", stringify!($int_type), "` instead of `&", stringify!($atomic_type), "`.
1972
1973 Returning an `*mut` pointer from a shared reference to this atomic is safe because the
1974 atomic types work with interior mutability. All modifications of an atomic change the value
1975 through a shared reference, and can do so safely as long as they use atomic operations. Any
1976 use of the returned raw pointer requires an `unsafe` block and still has to uphold the same
1977 restriction: operations on it must be atomic.
1978
1979 # Examples
1980
1981 ```ignore (extern-declaration)
1982 # fn main() {
1983 ", $extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";
1984
1985 extern {
1986     fn my_atomic_op(arg: *mut ", stringify!($int_type), ");
1987 }
1988
1989 let mut atomic = ", stringify!($atomic_type), "::new(1);
1990 unsafe {
1991     my_atomic_op(atomic.as_mut_ptr());
1992 }
1993 # }
1994 ```"),
1995                 #[inline]
1996                 #[unstable(feature = "atomic_mut_ptr",
1997                        reason = "recently added",
1998                        issue = "66893")]
1999                 pub fn as_mut_ptr(&self) -> *mut $int_type {
2000                     self.v.get()
2001                 }
2002             }
2003         }
2004     }
2005 }
2006
2007 #[cfg(target_has_atomic_load_store = "8")]
2008 atomic_int! {
2009     cfg(target_has_atomic = "8"),
2010     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2011     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2012     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2013     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2014     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2015     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2016     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2017     unstable(feature = "integer_atomics", issue = "32976"),
2018     "i8", "../../../std/primitive.i8.html",
2019     "",
2020     atomic_min, atomic_max,
2021     1,
2022     "AtomicI8::new(0)",
2023     i8 AtomicI8 ATOMIC_I8_INIT
2024 }
2025 #[cfg(target_has_atomic_load_store = "8")]
2026 atomic_int! {
2027     cfg(target_has_atomic = "8"),
2028     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2029     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2030     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2031     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2032     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2033     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2034     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2035     unstable(feature = "integer_atomics", issue = "32976"),
2036     "u8", "../../../std/primitive.u8.html",
2037     "",
2038     atomic_umin, atomic_umax,
2039     1,
2040     "AtomicU8::new(0)",
2041     u8 AtomicU8 ATOMIC_U8_INIT
2042 }
2043 #[cfg(target_has_atomic_load_store = "16")]
2044 atomic_int! {
2045     cfg(target_has_atomic = "16"),
2046     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2047     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2048     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2049     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2050     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2051     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2052     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2053     unstable(feature = "integer_atomics", issue = "32976"),
2054     "i16", "../../../std/primitive.i16.html",
2055     "",
2056     atomic_min, atomic_max,
2057     2,
2058     "AtomicI16::new(0)",
2059     i16 AtomicI16 ATOMIC_I16_INIT
2060 }
2061 #[cfg(target_has_atomic_load_store = "16")]
2062 atomic_int! {
2063     cfg(target_has_atomic = "16"),
2064     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2065     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2066     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2067     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2068     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2069     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2070     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2071     unstable(feature = "integer_atomics", issue = "32976"),
2072     "u16", "../../../std/primitive.u16.html",
2073     "",
2074     atomic_umin, atomic_umax,
2075     2,
2076     "AtomicU16::new(0)",
2077     u16 AtomicU16 ATOMIC_U16_INIT
2078 }
2079 #[cfg(target_has_atomic_load_store = "32")]
2080 atomic_int! {
2081     cfg(target_has_atomic = "32"),
2082     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2083     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2084     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2085     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2086     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2087     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2088     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2089     unstable(feature = "integer_atomics", issue = "32976"),
2090     "i32", "../../../std/primitive.i32.html",
2091     "",
2092     atomic_min, atomic_max,
2093     4,
2094     "AtomicI32::new(0)",
2095     i32 AtomicI32 ATOMIC_I32_INIT
2096 }
2097 #[cfg(target_has_atomic_load_store = "32")]
2098 atomic_int! {
2099     cfg(target_has_atomic = "32"),
2100     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2101     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2102     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2103     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2104     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2105     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2106     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2107     unstable(feature = "integer_atomics", issue = "32976"),
2108     "u32", "../../../std/primitive.u32.html",
2109     "",
2110     atomic_umin, atomic_umax,
2111     4,
2112     "AtomicU32::new(0)",
2113     u32 AtomicU32 ATOMIC_U32_INIT
2114 }
2115 #[cfg(target_has_atomic_load_store = "64")]
2116 atomic_int! {
2117     cfg(target_has_atomic = "64"),
2118     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2119     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2120     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2121     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2122     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2123     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2124     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2125     unstable(feature = "integer_atomics", issue = "32976"),
2126     "i64", "../../../std/primitive.i64.html",
2127     "",
2128     atomic_min, atomic_max,
2129     8,
2130     "AtomicI64::new(0)",
2131     i64 AtomicI64 ATOMIC_I64_INIT
2132 }
2133 #[cfg(target_has_atomic_load_store = "64")]
2134 atomic_int! {
2135     cfg(target_has_atomic = "64"),
2136     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2137     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2138     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2139     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2140     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2141     stable(feature = "integer_atomics_stable", since = "1.34.0"),
2142     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2143     unstable(feature = "integer_atomics", issue = "32976"),
2144     "u64", "../../../std/primitive.u64.html",
2145     "",
2146     atomic_umin, atomic_umax,
2147     8,
2148     "AtomicU64::new(0)",
2149     u64 AtomicU64 ATOMIC_U64_INIT
2150 }
2151 #[cfg(target_has_atomic_load_store = "128")]
2152 atomic_int! {
2153     cfg(target_has_atomic = "128"),
2154     unstable(feature = "integer_atomics", issue = "32976"),
2155     unstable(feature = "integer_atomics", issue = "32976"),
2156     unstable(feature = "integer_atomics", issue = "32976"),
2157     unstable(feature = "integer_atomics", issue = "32976"),
2158     unstable(feature = "integer_atomics", issue = "32976"),
2159     unstable(feature = "integer_atomics", issue = "32976"),
2160     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2161     unstable(feature = "integer_atomics", issue = "32976"),
2162     "i128", "../../../std/primitive.i128.html",
2163     "#![feature(integer_atomics)]\n\n",
2164     atomic_min, atomic_max,
2165     16,
2166     "AtomicI128::new(0)",
2167     i128 AtomicI128 ATOMIC_I128_INIT
2168 }
2169 #[cfg(target_has_atomic_load_store = "128")]
2170 atomic_int! {
2171     cfg(target_has_atomic = "128"),
2172     unstable(feature = "integer_atomics", issue = "32976"),
2173     unstable(feature = "integer_atomics", issue = "32976"),
2174     unstable(feature = "integer_atomics", issue = "32976"),
2175     unstable(feature = "integer_atomics", issue = "32976"),
2176     unstable(feature = "integer_atomics", issue = "32976"),
2177     unstable(feature = "integer_atomics", issue = "32976"),
2178     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2179     unstable(feature = "integer_atomics", issue = "32976"),
2180     "u128", "../../../std/primitive.u128.html",
2181     "#![feature(integer_atomics)]\n\n",
2182     atomic_umin, atomic_umax,
2183     16,
2184     "AtomicU128::new(0)",
2185     u128 AtomicU128 ATOMIC_U128_INIT
2186 }
2187 #[cfg(target_has_atomic_load_store = "ptr")]
2188 #[cfg(target_pointer_width = "16")]
2189 macro_rules! ptr_width {
2190     () => {
2191         2
2192     };
2193 }
2194 #[cfg(target_has_atomic_load_store = "ptr")]
2195 #[cfg(target_pointer_width = "32")]
2196 macro_rules! ptr_width {
2197     () => {
2198         4
2199     };
2200 }
2201 #[cfg(target_has_atomic_load_store = "ptr")]
2202 #[cfg(target_pointer_width = "64")]
2203 macro_rules! ptr_width {
2204     () => {
2205         8
2206     };
2207 }
2208 #[cfg(target_has_atomic_load_store = "ptr")]
2209 atomic_int! {
2210     cfg(target_has_atomic = "ptr"),
2211     stable(feature = "rust1", since = "1.0.0"),
2212     stable(feature = "extended_compare_and_swap", since = "1.10.0"),
2213     stable(feature = "atomic_debug", since = "1.3.0"),
2214     stable(feature = "atomic_access", since = "1.15.0"),
2215     stable(feature = "atomic_from", since = "1.23.0"),
2216     stable(feature = "atomic_nand", since = "1.27.0"),
2217     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2218     stable(feature = "rust1", since = "1.0.0"),
2219     "isize", "../../../std/primitive.isize.html",
2220     "",
2221     atomic_min, atomic_max,
2222     ptr_width!(),
2223     "AtomicIsize::new(0)",
2224     isize AtomicIsize ATOMIC_ISIZE_INIT
2225 }
2226 #[cfg(target_has_atomic_load_store = "ptr")]
2227 atomic_int! {
2228     cfg(target_has_atomic = "ptr"),
2229     stable(feature = "rust1", since = "1.0.0"),
2230     stable(feature = "extended_compare_and_swap", since = "1.10.0"),
2231     stable(feature = "atomic_debug", since = "1.3.0"),
2232     stable(feature = "atomic_access", since = "1.15.0"),
2233     stable(feature = "atomic_from", since = "1.23.0"),
2234     stable(feature = "atomic_nand", since = "1.27.0"),
2235     rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
2236     stable(feature = "rust1", since = "1.0.0"),
2237     "usize", "../../../std/primitive.usize.html",
2238     "",
2239     atomic_umin, atomic_umax,
2240     ptr_width!(),
2241     "AtomicUsize::new(0)",
2242     usize AtomicUsize ATOMIC_USIZE_INIT
2243 }
2244
2245 #[inline]
2246 #[cfg(target_has_atomic = "8")]
2247 fn strongest_failure_ordering(order: Ordering) -> Ordering {
2248     match order {
2249         Release => Relaxed,
2250         Relaxed => Relaxed,
2251         SeqCst => SeqCst,
2252         Acquire => Acquire,
2253         AcqRel => Acquire,
2254     }
2255 }
2256
2257 #[inline]
2258 unsafe fn atomic_store<T>(dst: *mut T, val: T, order: Ordering) {
2259     match order {
2260         Release => intrinsics::atomic_store_rel(dst, val),
2261         Relaxed => intrinsics::atomic_store_relaxed(dst, val),
2262         SeqCst => intrinsics::atomic_store(dst, val),
2263         Acquire => panic!("there is no such thing as an acquire store"),
2264         AcqRel => panic!("there is no such thing as an acquire/release store"),
2265     }
2266 }
2267
2268 #[inline]
2269 unsafe fn atomic_load<T>(dst: *const T, order: Ordering) -> T {
2270     match order {
2271         Acquire => intrinsics::atomic_load_acq(dst),
2272         Relaxed => intrinsics::atomic_load_relaxed(dst),
2273         SeqCst => intrinsics::atomic_load(dst),
2274         Release => panic!("there is no such thing as a release load"),
2275         AcqRel => panic!("there is no such thing as an acquire/release load"),
2276     }
2277 }
2278
2279 #[inline]
2280 #[cfg(target_has_atomic = "8")]
2281 unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T {
2282     match order {
2283         Acquire => intrinsics::atomic_xchg_acq(dst, val),
2284         Release => intrinsics::atomic_xchg_rel(dst, val),
2285         AcqRel => intrinsics::atomic_xchg_acqrel(dst, val),
2286         Relaxed => intrinsics::atomic_xchg_relaxed(dst, val),
2287         SeqCst => intrinsics::atomic_xchg(dst, val),
2288     }
2289 }
2290
2291 /// Returns the previous value (like __sync_fetch_and_add).
2292 #[inline]
2293 #[cfg(target_has_atomic = "8")]
2294 unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T {
2295     match order {
2296         Acquire => intrinsics::atomic_xadd_acq(dst, val),
2297         Release => intrinsics::atomic_xadd_rel(dst, val),
2298         AcqRel => intrinsics::atomic_xadd_acqrel(dst, val),
2299         Relaxed => intrinsics::atomic_xadd_relaxed(dst, val),
2300         SeqCst => intrinsics::atomic_xadd(dst, val),
2301     }
2302 }
2303
2304 /// Returns the previous value (like __sync_fetch_and_sub).
2305 #[inline]
2306 #[cfg(target_has_atomic = "8")]
2307 unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T {
2308     match order {
2309         Acquire => intrinsics::atomic_xsub_acq(dst, val),
2310         Release => intrinsics::atomic_xsub_rel(dst, val),
2311         AcqRel => intrinsics::atomic_xsub_acqrel(dst, val),
2312         Relaxed => intrinsics::atomic_xsub_relaxed(dst, val),
2313         SeqCst => intrinsics::atomic_xsub(dst, val),
2314     }
2315 }
2316
2317 #[inline]
2318 #[cfg(target_has_atomic = "8")]
2319 unsafe fn atomic_compare_exchange<T>(
2320     dst: *mut T,
2321     old: T,
2322     new: T,
2323     success: Ordering,
2324     failure: Ordering,
2325 ) -> Result<T, T> {
2326     let (val, ok) = match (success, failure) {
2327         (Acquire, Acquire) => intrinsics::atomic_cxchg_acq(dst, old, new),
2328         (Release, Relaxed) => intrinsics::atomic_cxchg_rel(dst, old, new),
2329         (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel(dst, old, new),
2330         (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed(dst, old, new),
2331         (SeqCst, SeqCst) => intrinsics::atomic_cxchg(dst, old, new),
2332         (Acquire, Relaxed) => intrinsics::atomic_cxchg_acq_failrelaxed(dst, old, new),
2333         (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_failrelaxed(dst, old, new),
2334         (SeqCst, Relaxed) => intrinsics::atomic_cxchg_failrelaxed(dst, old, new),
2335         (SeqCst, Acquire) => intrinsics::atomic_cxchg_failacq(dst, old, new),
2336         (_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"),
2337         (_, Release) => panic!("there is no such thing as a release failure ordering"),
2338         _ => panic!("a failure ordering can't be stronger than a success ordering"),
2339     };
2340     if ok { Ok(val) } else { Err(val) }
2341 }
2342
2343 #[inline]
2344 #[cfg(target_has_atomic = "8")]
2345 unsafe fn atomic_compare_exchange_weak<T>(
2346     dst: *mut T,
2347     old: T,
2348     new: T,
2349     success: Ordering,
2350     failure: Ordering,
2351 ) -> Result<T, T> {
2352     let (val, ok) = match (success, failure) {
2353         (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acq(dst, old, new),
2354         (Release, Relaxed) => intrinsics::atomic_cxchgweak_rel(dst, old, new),
2355         (AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel(dst, old, new),
2356         (Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed(dst, old, new),
2357         (SeqCst, SeqCst) => intrinsics::atomic_cxchgweak(dst, old, new),
2358         (Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acq_failrelaxed(dst, old, new),
2359         (AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_failrelaxed(dst, old, new),
2360         (SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_failrelaxed(dst, old, new),
2361         (SeqCst, Acquire) => intrinsics::atomic_cxchgweak_failacq(dst, old, new),
2362         (_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"),
2363         (_, Release) => panic!("there is no such thing as a release failure ordering"),
2364         _ => panic!("a failure ordering can't be stronger than a success ordering"),
2365     };
2366     if ok { Ok(val) } else { Err(val) }
2367 }
2368
2369 #[inline]
2370 #[cfg(target_has_atomic = "8")]
2371 unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T {
2372     match order {
2373         Acquire => intrinsics::atomic_and_acq(dst, val),
2374         Release => intrinsics::atomic_and_rel(dst, val),
2375         AcqRel => intrinsics::atomic_and_acqrel(dst, val),
2376         Relaxed => intrinsics::atomic_and_relaxed(dst, val),
2377         SeqCst => intrinsics::atomic_and(dst, val),
2378     }
2379 }
2380
2381 #[inline]
2382 #[cfg(target_has_atomic = "8")]
2383 unsafe fn atomic_nand<T>(dst: *mut T, val: T, order: Ordering) -> T {
2384     match order {
2385         Acquire => intrinsics::atomic_nand_acq(dst, val),
2386         Release => intrinsics::atomic_nand_rel(dst, val),
2387         AcqRel => intrinsics::atomic_nand_acqrel(dst, val),
2388         Relaxed => intrinsics::atomic_nand_relaxed(dst, val),
2389         SeqCst => intrinsics::atomic_nand(dst, val),
2390     }
2391 }
2392
2393 #[inline]
2394 #[cfg(target_has_atomic = "8")]
2395 unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T {
2396     match order {
2397         Acquire => intrinsics::atomic_or_acq(dst, val),
2398         Release => intrinsics::atomic_or_rel(dst, val),
2399         AcqRel => intrinsics::atomic_or_acqrel(dst, val),
2400         Relaxed => intrinsics::atomic_or_relaxed(dst, val),
2401         SeqCst => intrinsics::atomic_or(dst, val),
2402     }
2403 }
2404
2405 #[inline]
2406 #[cfg(target_has_atomic = "8")]
2407 unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
2408     match order {
2409         Acquire => intrinsics::atomic_xor_acq(dst, val),
2410         Release => intrinsics::atomic_xor_rel(dst, val),
2411         AcqRel => intrinsics::atomic_xor_acqrel(dst, val),
2412         Relaxed => intrinsics::atomic_xor_relaxed(dst, val),
2413         SeqCst => intrinsics::atomic_xor(dst, val),
2414     }
2415 }
2416
2417 /// returns the max value (signed comparison)
2418 #[inline]
2419 #[cfg(target_has_atomic = "8")]
2420 unsafe fn atomic_max<T>(dst: *mut T, val: T, order: Ordering) -> T {
2421     match order {
2422         Acquire => intrinsics::atomic_max_acq(dst, val),
2423         Release => intrinsics::atomic_max_rel(dst, val),
2424         AcqRel => intrinsics::atomic_max_acqrel(dst, val),
2425         Relaxed => intrinsics::atomic_max_relaxed(dst, val),
2426         SeqCst => intrinsics::atomic_max(dst, val),
2427     }
2428 }
2429
2430 /// returns the min value (signed comparison)
2431 #[inline]
2432 #[cfg(target_has_atomic = "8")]
2433 unsafe fn atomic_min<T>(dst: *mut T, val: T, order: Ordering) -> T {
2434     match order {
2435         Acquire => intrinsics::atomic_min_acq(dst, val),
2436         Release => intrinsics::atomic_min_rel(dst, val),
2437         AcqRel => intrinsics::atomic_min_acqrel(dst, val),
2438         Relaxed => intrinsics::atomic_min_relaxed(dst, val),
2439         SeqCst => intrinsics::atomic_min(dst, val),
2440     }
2441 }
2442
2443 /// returns the max value (signed comparison)
2444 #[inline]
2445 #[cfg(target_has_atomic = "8")]
2446 unsafe fn atomic_umax<T>(dst: *mut T, val: T, order: Ordering) -> T {
2447     match order {
2448         Acquire => intrinsics::atomic_umax_acq(dst, val),
2449         Release => intrinsics::atomic_umax_rel(dst, val),
2450         AcqRel => intrinsics::atomic_umax_acqrel(dst, val),
2451         Relaxed => intrinsics::atomic_umax_relaxed(dst, val),
2452         SeqCst => intrinsics::atomic_umax(dst, val),
2453     }
2454 }
2455
2456 /// returns the min value (signed comparison)
2457 #[inline]
2458 #[cfg(target_has_atomic = "8")]
2459 unsafe fn atomic_umin<T>(dst: *mut T, val: T, order: Ordering) -> T {
2460     match order {
2461         Acquire => intrinsics::atomic_umin_acq(dst, val),
2462         Release => intrinsics::atomic_umin_rel(dst, val),
2463         AcqRel => intrinsics::atomic_umin_acqrel(dst, val),
2464         Relaxed => intrinsics::atomic_umin_relaxed(dst, val),
2465         SeqCst => intrinsics::atomic_umin(dst, val),
2466     }
2467 }
2468
2469 /// An atomic fence.
2470 ///
2471 /// Depending on the specified order, a fence prevents the compiler and CPU from
2472 /// reordering certain types of memory operations around it.
2473 /// That creates synchronizes-with relationships between it and atomic operations
2474 /// or fences in other threads.
2475 ///
2476 /// A fence 'A' which has (at least) [`Release`] ordering semantics, synchronizes
2477 /// with a fence 'B' with (at least) [`Acquire`] semantics, if and only if there
2478 /// exist operations X and Y, both operating on some atomic object 'M' such
2479 /// that A is sequenced before X, Y is synchronized before B and Y observes
2480 /// the change to M. This provides a happens-before dependence between A and B.
2481 ///
2482 /// ```text
2483 ///     Thread 1                                          Thread 2
2484 ///
2485 /// fence(Release);      A --------------
2486 /// x.store(3, Relaxed); X ---------    |
2487 ///                                |    |
2488 ///                                |    |
2489 ///                                -------------> Y  if x.load(Relaxed) == 3 {
2490 ///                                     |-------> B      fence(Acquire);
2491 ///                                                      ...
2492 ///                                                  }
2493 /// ```
2494 ///
2495 /// Atomic operations with [`Release`] or [`Acquire`] semantics can also synchronize
2496 /// with a fence.
2497 ///
2498 /// A fence which has [`SeqCst`] ordering, in addition to having both [`Acquire`]
2499 /// and [`Release`] semantics, participates in the global program order of the
2500 /// other [`SeqCst`] operations and/or fences.
2501 ///
2502 /// Accepts [`Acquire`], [`Release`], [`AcqRel`] and [`SeqCst`] orderings.
2503 ///
2504 /// # Panics
2505 ///
2506 /// Panics if `order` is [`Relaxed`].
2507 ///
2508 /// # Examples
2509 ///
2510 /// ```
2511 /// use std::sync::atomic::AtomicBool;
2512 /// use std::sync::atomic::fence;
2513 /// use std::sync::atomic::Ordering;
2514 ///
2515 /// // A mutual exclusion primitive based on spinlock.
2516 /// pub struct Mutex {
2517 ///     flag: AtomicBool,
2518 /// }
2519 ///
2520 /// impl Mutex {
2521 ///     pub fn new() -> Mutex {
2522 ///         Mutex {
2523 ///             flag: AtomicBool::new(false),
2524 ///         }
2525 ///     }
2526 ///
2527 ///     pub fn lock(&self) {
2528 ///         while !self.flag.compare_and_swap(false, true, Ordering::Relaxed) {}
2529 ///         // This fence synchronizes-with store in `unlock`.
2530 ///         fence(Ordering::Acquire);
2531 ///     }
2532 ///
2533 ///     pub fn unlock(&self) {
2534 ///         self.flag.store(false, Ordering::Release);
2535 ///     }
2536 /// }
2537 /// ```
2538 ///
2539 /// [`Ordering`]: enum.Ordering.html
2540 /// [`Acquire`]: enum.Ordering.html#variant.Acquire
2541 /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
2542 /// [`Release`]: enum.Ordering.html#variant.Release
2543 /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
2544 /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
2545 #[inline]
2546 #[stable(feature = "rust1", since = "1.0.0")]
2547 #[cfg_attr(target_arch = "wasm32", allow(unused_variables))]
2548 pub fn fence(order: Ordering) {
2549     // On wasm32 it looks like fences aren't implemented in LLVM yet in that
2550     // they will cause LLVM to abort. The wasm instruction set doesn't have
2551     // fences right now. There's discussion online about the best way for tools
2552     // to conventionally implement fences at
2553     // https://github.com/WebAssembly/tool-conventions/issues/59. We should
2554     // follow that discussion and implement a solution when one comes about!
2555     #[cfg(not(target_arch = "wasm32"))]
2556     // SAFETY: using an atomic fence is safe
2557     unsafe {
2558         match order {
2559             Acquire => intrinsics::atomic_fence_acq(),
2560             Release => intrinsics::atomic_fence_rel(),
2561             AcqRel => intrinsics::atomic_fence_acqrel(),
2562             SeqCst => intrinsics::atomic_fence(),
2563             Relaxed => panic!("there is no such thing as a relaxed fence"),
2564         }
2565     }
2566 }
2567
2568 /// A compiler memory fence.
2569 ///
2570 /// `compiler_fence` does not emit any machine code, but restricts the kinds
2571 /// of memory re-ordering the compiler is allowed to do. Specifically, depending on
2572 /// the given [`Ordering`] semantics, the compiler may be disallowed from moving reads
2573 /// or writes from before or after the call to the other side of the call to
2574 /// `compiler_fence`. Note that it does **not** prevent the *hardware*
2575 /// from doing such re-ordering. This is not a problem in a single-threaded,
2576 /// execution context, but when other threads may modify memory at the same
2577 /// time, stronger synchronization primitives such as [`fence`] are required.
2578 ///
2579 /// The re-ordering prevented by the different ordering semantics are:
2580 ///
2581 ///  - with [`SeqCst`], no re-ordering of reads and writes across this point is allowed.
2582 ///  - with [`Release`], preceding reads and writes cannot be moved past subsequent writes.
2583 ///  - with [`Acquire`], subsequent reads and writes cannot be moved ahead of preceding reads.
2584 ///  - with [`AcqRel`], both of the above rules are enforced.
2585 ///
2586 /// `compiler_fence` is generally only useful for preventing a thread from
2587 /// racing *with itself*. That is, if a given thread is executing one piece
2588 /// of code, and is then interrupted, and starts executing code elsewhere
2589 /// (while still in the same thread, and conceptually still on the same
2590 /// core). In traditional programs, this can only occur when a signal
2591 /// handler is registered. In more low-level code, such situations can also
2592 /// arise when handling interrupts, when implementing green threads with
2593 /// pre-emption, etc. Curious readers are encouraged to read the Linux kernel's
2594 /// discussion of [memory barriers].
2595 ///
2596 /// # Panics
2597 ///
2598 /// Panics if `order` is [`Relaxed`].
2599 ///
2600 /// # Examples
2601 ///
2602 /// Without `compiler_fence`, the `assert_eq!` in following code
2603 /// is *not* guaranteed to succeed, despite everything happening in a single thread.
2604 /// To see why, remember that the compiler is free to swap the stores to
2605 /// `IMPORTANT_VARIABLE` and `IS_READ` since they are both
2606 /// `Ordering::Relaxed`. If it does, and the signal handler is invoked right
2607 /// after `IS_READY` is updated, then the signal handler will see
2608 /// `IS_READY=1`, but `IMPORTANT_VARIABLE=0`.
2609 /// Using a `compiler_fence` remedies this situation.
2610 ///
2611 /// ```
2612 /// use std::sync::atomic::{AtomicBool, AtomicUsize};
2613 /// use std::sync::atomic::Ordering;
2614 /// use std::sync::atomic::compiler_fence;
2615 ///
2616 /// static IMPORTANT_VARIABLE: AtomicUsize = AtomicUsize::new(0);
2617 /// static IS_READY: AtomicBool = AtomicBool::new(false);
2618 ///
2619 /// fn main() {
2620 ///     IMPORTANT_VARIABLE.store(42, Ordering::Relaxed);
2621 ///     // prevent earlier writes from being moved beyond this point
2622 ///     compiler_fence(Ordering::Release);
2623 ///     IS_READY.store(true, Ordering::Relaxed);
2624 /// }
2625 ///
2626 /// fn signal_handler() {
2627 ///     if IS_READY.load(Ordering::Relaxed) {
2628 ///         assert_eq!(IMPORTANT_VARIABLE.load(Ordering::Relaxed), 42);
2629 ///     }
2630 /// }
2631 /// ```
2632 ///
2633 /// [`fence`]: fn.fence.html
2634 /// [`Ordering`]: enum.Ordering.html
2635 /// [`Acquire`]: enum.Ordering.html#variant.Acquire
2636 /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
2637 /// [`Release`]: enum.Ordering.html#variant.Release
2638 /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
2639 /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
2640 /// [memory barriers]: https://www.kernel.org/doc/Documentation/memory-barriers.txt
2641 #[inline]
2642 #[stable(feature = "compiler_fences", since = "1.21.0")]
2643 pub fn compiler_fence(order: Ordering) {
2644     // SAFETY: doesn't compile to machine code
2645     unsafe {
2646         match order {
2647             Acquire => intrinsics::atomic_singlethreadfence_acq(),
2648             Release => intrinsics::atomic_singlethreadfence_rel(),
2649             AcqRel => intrinsics::atomic_singlethreadfence_acqrel(),
2650             SeqCst => intrinsics::atomic_singlethreadfence(),
2651             Relaxed => panic!("there is no such thing as a relaxed compiler fence"),
2652         }
2653     }
2654 }
2655
2656 #[cfg(target_has_atomic_load_store = "8")]
2657 #[stable(feature = "atomic_debug", since = "1.3.0")]
2658 impl fmt::Debug for AtomicBool {
2659     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2660         fmt::Debug::fmt(&self.load(Ordering::SeqCst), f)
2661     }
2662 }
2663
2664 #[cfg(target_has_atomic_load_store = "ptr")]
2665 #[stable(feature = "atomic_debug", since = "1.3.0")]
2666 impl<T> fmt::Debug for AtomicPtr<T> {
2667     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2668         fmt::Debug::fmt(&self.load(Ordering::SeqCst), f)
2669     }
2670 }
2671
2672 #[cfg(target_has_atomic_load_store = "ptr")]
2673 #[stable(feature = "atomic_pointer", since = "1.24.0")]
2674 impl<T> fmt::Pointer for AtomicPtr<T> {
2675     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2676         fmt::Pointer::fmt(&self.load(Ordering::SeqCst), f)
2677     }
2678 }