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