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