]> git.lizzy.rs Git - rust.git/blob - src/libcore/sync/atomic.rs
Specify output filenames for compatibility with Windows
[rust.git] / src / libcore / sync / atomic.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Atomic types
12 //!
13 //! Atomic types provide primitive shared-memory communication between
14 //! threads, and are the building blocks of other concurrent
15 //! types.
16 //!
17 //! This module defines atomic versions of a select number of primitive
18 //! types, including [`AtomicBool`], [`AtomicIsize`], and [`AtomicUsize`].
19 //! Atomic types present operations that, when used correctly, synchronize
20 //! updates between threads.
21 //!
22 //! [`AtomicBool`]: struct.AtomicBool.html
23 //! [`AtomicIsize`]: struct.AtomicIsize.html
24 //! [`AtomicUsize`]: struct.AtomicUsize.html
25 //!
26 //! Each method takes an [`Ordering`] which represents the strength of
27 //! the memory barrier for that operation. These orderings are the
28 //! same as [LLVM atomic orderings][1]. For more information see the [nomicon][2].
29 //!
30 //! [`Ordering`]: enum.Ordering.html
31 //!
32 //! [1]: http://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations
33 //! [2]: ../../../nomicon/atomics.html
34 //!
35 //! Atomic variables are safe to share between threads (they implement [`Sync`])
36 //! but they do not themselves provide the mechanism for sharing and follow the
37 //! [threading model](../../../std/thread/index.html#the-threading-model) of rust.
38 //! The most common way to share an atomic variable is to put it into an [`Arc`][arc] (an
39 //! atomically-reference-counted shared pointer).
40 //!
41 //! [`Sync`]: ../../marker/trait.Sync.html
42 //! [arc]: ../../../std/sync/struct.Arc.html
43 //!
44 //! Most atomic types may be stored in static variables, initialized using
45 //! the provided static initializers like [`ATOMIC_BOOL_INIT`]. Atomic statics
46 //! are often used for lazy global initialization.
47 //!
48 //! [`ATOMIC_BOOL_INIT`]: constant.ATOMIC_BOOL_INIT.html
49 //!
50 //! # Examples
51 //!
52 //! A simple spinlock:
53 //!
54 //! ```
55 //! use std::sync::Arc;
56 //! use std::sync::atomic::{AtomicUsize, Ordering};
57 //! use std::thread;
58 //!
59 //! fn main() {
60 //!     let spinlock = Arc::new(AtomicUsize::new(1));
61 //!
62 //!     let spinlock_clone = spinlock.clone();
63 //!     let thread = thread::spawn(move|| {
64 //!         spinlock_clone.store(0, Ordering::SeqCst);
65 //!     });
66 //!
67 //!     // Wait for the other thread to release the lock
68 //!     while spinlock.load(Ordering::SeqCst) != 0 {}
69 //!
70 //!     if let Err(panic) = thread.join() {
71 //!         println!("Thread had an error: {:?}", panic);
72 //!     }
73 //! }
74 //! ```
75 //!
76 //! Keep a global count of live threads:
77 //!
78 //! ```
79 //! use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
80 //!
81 //! static GLOBAL_THREAD_COUNT: AtomicUsize = ATOMIC_USIZE_INIT;
82 //!
83 //! let old_thread_count = GLOBAL_THREAD_COUNT.fetch_add(1, Ordering::SeqCst);
84 //! println!("live threads: {}", old_thread_count + 1);
85 //! ```
86
87 #![stable(feature = "rust1", since = "1.0.0")]
88 #![cfg_attr(not(target_has_atomic = "8"), allow(dead_code))]
89 #![cfg_attr(not(target_has_atomic = "8"), allow(unused_imports))]
90
91 use self::Ordering::*;
92
93 use intrinsics;
94 use cell::UnsafeCell;
95 use fmt;
96
97 /// Save power or switch hyperthreads in a busy-wait spin-loop.
98 ///
99 /// This function is deliberately more primitive than
100 /// `std::thread::yield_now` and does not directly yield to the
101 /// system's scheduler.  In some cases it might be useful to use a
102 /// combination of both functions.  Careful benchmarking is advised.
103 ///
104 /// On some platforms this function may not do anything at all.
105 #[inline]
106 #[stable(feature = "spin_loop_hint", since = "1.24.0")]
107 pub fn spin_loop_hint() {
108     #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
109     unsafe {
110         asm!("pause" ::: "memory" : "volatile");
111     }
112
113     #[cfg(target_arch = "aarch64")]
114     unsafe {
115         asm!("yield" ::: "memory" : "volatile");
116     }
117 }
118
119 /// A boolean type which can be safely shared between threads.
120 ///
121 /// This type has the same in-memory representation as a [`bool`].
122 ///
123 /// [`bool`]: ../../../std/primitive.bool.html
124 #[cfg(target_has_atomic = "8")]
125 #[stable(feature = "rust1", since = "1.0.0")]
126 pub struct AtomicBool {
127     v: UnsafeCell<u8>,
128 }
129
130 #[cfg(target_has_atomic = "8")]
131 #[stable(feature = "rust1", since = "1.0.0")]
132 impl Default for AtomicBool {
133     /// Creates an `AtomicBool` initialized to `false`.
134     fn default() -> Self {
135         Self::new(false)
136     }
137 }
138
139 // Send is implicitly implemented for AtomicBool.
140 #[cfg(target_has_atomic = "8")]
141 #[stable(feature = "rust1", since = "1.0.0")]
142 unsafe impl Sync for AtomicBool {}
143
144 /// A raw pointer type which can be safely shared between threads.
145 ///
146 /// This type has the same in-memory representation as a `*mut T`.
147 #[cfg(target_has_atomic = "ptr")]
148 #[stable(feature = "rust1", since = "1.0.0")]
149 pub struct AtomicPtr<T> {
150     p: UnsafeCell<*mut T>,
151 }
152
153 #[cfg(target_has_atomic = "ptr")]
154 #[stable(feature = "rust1", since = "1.0.0")]
155 impl<T> Default for AtomicPtr<T> {
156     /// Creates a null `AtomicPtr<T>`.
157     fn default() -> AtomicPtr<T> {
158         AtomicPtr::new(::ptr::null_mut())
159     }
160 }
161
162 #[cfg(target_has_atomic = "ptr")]
163 #[stable(feature = "rust1", since = "1.0.0")]
164 unsafe impl<T> Send for AtomicPtr<T> {}
165 #[cfg(target_has_atomic = "ptr")]
166 #[stable(feature = "rust1", since = "1.0.0")]
167 unsafe impl<T> Sync for AtomicPtr<T> {}
168
169 /// Atomic memory orderings
170 ///
171 /// Memory orderings limit the ways that both the compiler and CPU may reorder
172 /// instructions around atomic operations. At its most restrictive,
173 /// "sequentially consistent" atomics allow neither reads nor writes
174 /// to be moved either before or after the atomic operation; on the other end
175 /// "relaxed" atomics allow all reorderings.
176 ///
177 /// Rust's memory orderings are [the same as
178 /// LLVM's](http://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations).
179 ///
180 /// For more information see the [nomicon].
181 ///
182 /// [nomicon]: ../../../nomicon/atomics.html
183 #[stable(feature = "rust1", since = "1.0.0")]
184 #[derive(Copy, Clone, Debug)]
185 pub enum Ordering {
186     /// No ordering constraints, only atomic operations.
187     ///
188     /// Corresponds to LLVM's [`Monotonic`] ordering.
189     ///
190     /// [`Monotonic`]: http://llvm.org/docs/Atomics.html#monotonic
191     #[stable(feature = "rust1", since = "1.0.0")]
192     Relaxed,
193     /// When coupled with a store, all previous writes become visible
194     /// to the other threads that perform a load with [`Acquire`] ordering
195     /// on the same value.
196     ///
197     /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire
198     #[stable(feature = "rust1", since = "1.0.0")]
199     Release,
200     /// When coupled with a load, all subsequent loads will see data
201     /// written before a store with [`Release`] ordering on the same value
202     /// in other threads.
203     ///
204     /// [`Release`]: http://llvm.org/docs/Atomics.html#release
205     #[stable(feature = "rust1", since = "1.0.0")]
206     Acquire,
207     /// When coupled with a load, uses [`Acquire`] ordering, and with a store
208     /// [`Release`] ordering.
209     ///
210     /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire
211     /// [`Release`]: http://llvm.org/docs/Atomics.html#release
212     #[stable(feature = "rust1", since = "1.0.0")]
213     AcqRel,
214     /// Like `AcqRel` with the additional guarantee that all threads see all
215     /// sequentially consistent operations in the same order.
216     #[stable(feature = "rust1", since = "1.0.0")]
217     SeqCst,
218     // Prevent exhaustive matching to allow for future extension
219     #[doc(hidden)]
220     #[unstable(feature = "future_atomic_orderings", issue = "0")]
221     __Nonexhaustive,
222 }
223
224 /// An [`AtomicBool`] initialized to `false`.
225 ///
226 /// [`AtomicBool`]: struct.AtomicBool.html
227 #[cfg(target_has_atomic = "8")]
228 #[stable(feature = "rust1", since = "1.0.0")]
229 pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false);
230
231 #[cfg(target_has_atomic = "8")]
232 impl AtomicBool {
233     /// Creates a new `AtomicBool`.
234     ///
235     /// # Examples
236     ///
237     /// ```
238     /// use std::sync::atomic::AtomicBool;
239     ///
240     /// let atomic_true  = AtomicBool::new(true);
241     /// let atomic_false = AtomicBool::new(false);
242     /// ```
243     #[inline]
244     #[stable(feature = "rust1", since = "1.0.0")]
245     pub const fn new(v: bool) -> AtomicBool {
246         AtomicBool { v: UnsafeCell::new(v as u8) }
247     }
248
249     /// Returns a mutable reference to the underlying [`bool`].
250     ///
251     /// This is safe because the mutable reference guarantees that no other threads are
252     /// concurrently accessing the atomic data.
253     ///
254     /// [`bool`]: ../../../std/primitive.bool.html
255     ///
256     /// # Examples
257     ///
258     /// ```
259     /// use std::sync::atomic::{AtomicBool, Ordering};
260     ///
261     /// let mut some_bool = AtomicBool::new(true);
262     /// assert_eq!(*some_bool.get_mut(), true);
263     /// *some_bool.get_mut() = false;
264     /// assert_eq!(some_bool.load(Ordering::SeqCst), false);
265     /// ```
266     #[inline]
267     #[stable(feature = "atomic_access", since = "1.15.0")]
268     pub fn get_mut(&mut self) -> &mut bool {
269         unsafe { &mut *(self.v.get() as *mut bool) }
270     }
271
272     /// Consumes the atomic and returns the contained value.
273     ///
274     /// This is safe because passing `self` by value guarantees that no other threads are
275     /// concurrently accessing the atomic data.
276     ///
277     /// # Examples
278     ///
279     /// ```
280     /// use std::sync::atomic::AtomicBool;
281     ///
282     /// let some_bool = AtomicBool::new(true);
283     /// assert_eq!(some_bool.into_inner(), true);
284     /// ```
285     #[inline]
286     #[stable(feature = "atomic_access", since = "1.15.0")]
287     pub fn into_inner(self) -> bool {
288         unsafe { self.v.into_inner() != 0 }
289     }
290
291     /// Loads a value from the bool.
292     ///
293     /// `load` takes an [`Ordering`] argument which describes the memory ordering
294     /// of this operation.
295     ///
296     /// # Panics
297     ///
298     /// Panics if `order` is [`Release`] or [`AcqRel`].
299     ///
300     /// [`Ordering`]: enum.Ordering.html
301     /// [`Release`]: enum.Ordering.html#variant.Release
302     /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
303     ///
304     /// # Examples
305     ///
306     /// ```
307     /// use std::sync::atomic::{AtomicBool, Ordering};
308     ///
309     /// let some_bool = AtomicBool::new(true);
310     ///
311     /// assert_eq!(some_bool.load(Ordering::Relaxed), true);
312     /// ```
313     #[inline]
314     #[stable(feature = "rust1", since = "1.0.0")]
315     pub fn load(&self, order: Ordering) -> bool {
316         unsafe { atomic_load(self.v.get(), order) != 0 }
317     }
318
319     /// Stores a value into the bool.
320     ///
321     /// `store` takes an [`Ordering`] argument which describes the memory ordering
322     /// of this operation.
323     ///
324     /// [`Ordering`]: enum.Ordering.html
325     ///
326     /// # Examples
327     ///
328     /// ```
329     /// use std::sync::atomic::{AtomicBool, Ordering};
330     ///
331     /// let some_bool = AtomicBool::new(true);
332     ///
333     /// some_bool.store(false, Ordering::Relaxed);
334     /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
335     /// ```
336     ///
337     /// # Panics
338     ///
339     /// Panics if `order` is [`Acquire`] or [`AcqRel`].
340     ///
341     /// [`Acquire`]: enum.Ordering.html#variant.Acquire
342     /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
343     #[inline]
344     #[stable(feature = "rust1", since = "1.0.0")]
345     pub fn store(&self, val: bool, order: Ordering) {
346         unsafe {
347             atomic_store(self.v.get(), val as u8, order);
348         }
349     }
350
351     /// Stores a value into the bool, returning the previous value.
352     ///
353     /// `swap` takes an [`Ordering`] argument which describes the memory ordering
354     /// of this operation.
355     ///
356     /// [`Ordering`]: enum.Ordering.html
357     ///
358     /// # Examples
359     ///
360     /// ```
361     /// use std::sync::atomic::{AtomicBool, Ordering};
362     ///
363     /// let some_bool = AtomicBool::new(true);
364     ///
365     /// assert_eq!(some_bool.swap(false, Ordering::Relaxed), true);
366     /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
367     /// ```
368     #[inline]
369     #[stable(feature = "rust1", since = "1.0.0")]
370     pub fn swap(&self, val: bool, order: Ordering) -> bool {
371         unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 }
372     }
373
374     /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
375     ///
376     /// The return value is always the previous value. If it is equal to `current`, then the value
377     /// was updated.
378     ///
379     /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
380     /// ordering of this operation.
381     ///
382     /// [`Ordering`]: enum.Ordering.html
383     /// [`bool`]: ../../../std/primitive.bool.html
384     ///
385     /// # Examples
386     ///
387     /// ```
388     /// use std::sync::atomic::{AtomicBool, Ordering};
389     ///
390     /// let some_bool = AtomicBool::new(true);
391     ///
392     /// assert_eq!(some_bool.compare_and_swap(true, false, Ordering::Relaxed), true);
393     /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
394     ///
395     /// assert_eq!(some_bool.compare_and_swap(true, true, Ordering::Relaxed), false);
396     /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
397     /// ```
398     #[inline]
399     #[stable(feature = "rust1", since = "1.0.0")]
400     pub fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> bool {
401         match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
402             Ok(x) => x,
403             Err(x) => x,
404         }
405     }
406
407     /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
408     ///
409     /// The return value is a result indicating whether the new value was written and containing
410     /// the previous value. On success this value is guaranteed to be equal to `current`.
411     ///
412     /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
413     /// ordering of this operation. The first describes the required ordering if the
414     /// operation succeeds while the second describes the required ordering when the
415     /// operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and must
416     /// be equivalent or weaker than the success ordering.
417     ///
418     /// [`bool`]: ../../../std/primitive.bool.html
419     /// [`Ordering`]: enum.Ordering.html
420     /// [`Release`]: enum.Ordering.html#variant.Release
421     /// [`AcqRel`]: enum.Ordering.html#variant.Release
422     ///
423     /// # Examples
424     ///
425     /// ```
426     /// use std::sync::atomic::{AtomicBool, Ordering};
427     ///
428     /// let some_bool = AtomicBool::new(true);
429     ///
430     /// assert_eq!(some_bool.compare_exchange(true,
431     ///                                       false,
432     ///                                       Ordering::Acquire,
433     ///                                       Ordering::Relaxed),
434     ///            Ok(true));
435     /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
436     ///
437     /// assert_eq!(some_bool.compare_exchange(true, true,
438     ///                                       Ordering::SeqCst,
439     ///                                       Ordering::Acquire),
440     ///            Err(false));
441     /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
442     /// ```
443     #[inline]
444     #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
445     pub fn compare_exchange(&self,
446                             current: bool,
447                             new: bool,
448                             success: Ordering,
449                             failure: Ordering)
450                             -> Result<bool, bool> {
451         match unsafe {
452             atomic_compare_exchange(self.v.get(), current as u8, new as u8, success, failure)
453         } {
454             Ok(x) => Ok(x != 0),
455             Err(x) => Err(x != 0),
456         }
457     }
458
459     /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
460     ///
461     /// Unlike [`compare_exchange`], this function is allowed to spuriously fail even when the
462     /// comparison succeeds, which can result in more efficient code on some platforms. The
463     /// return value is a result indicating whether the new value was written and containing the
464     /// previous value.
465     ///
466     /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
467     /// ordering of this operation. The first describes the required ordering if the operation
468     /// succeeds while the second describes the required ordering when the operation fails. The
469     /// failure ordering can't be [`Release`] or [`AcqRel`] and must be equivalent or
470     /// weaker than the success ordering.
471     ///
472     /// [`bool`]: ../../../std/primitive.bool.html
473     /// [`compare_exchange`]: #method.compare_exchange
474     /// [`Ordering`]: enum.Ordering.html
475     /// [`Release`]: enum.Ordering.html#variant.Release
476     /// [`AcqRel`]: enum.Ordering.html#variant.Release
477     ///
478     /// # Examples
479     ///
480     /// ```
481     /// use std::sync::atomic::{AtomicBool, Ordering};
482     ///
483     /// let val = AtomicBool::new(false);
484     ///
485     /// let new = true;
486     /// let mut old = val.load(Ordering::Relaxed);
487     /// loop {
488     ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
489     ///         Ok(_) => break,
490     ///         Err(x) => old = x,
491     ///     }
492     /// }
493     /// ```
494     #[inline]
495     #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
496     pub fn compare_exchange_weak(&self,
497                                  current: bool,
498                                  new: bool,
499                                  success: Ordering,
500                                  failure: Ordering)
501                                  -> Result<bool, bool> {
502         match unsafe {
503             atomic_compare_exchange_weak(self.v.get(), current as u8, new as u8, success, failure)
504         } {
505             Ok(x) => Ok(x != 0),
506             Err(x) => Err(x != 0),
507         }
508     }
509
510     /// Logical "and" with a boolean value.
511     ///
512     /// Performs a logical "and" operation on the current value and the argument `val`, and sets
513     /// the new value to the result.
514     ///
515     /// Returns the previous value.
516     ///
517     /// # Examples
518     ///
519     /// ```
520     /// use std::sync::atomic::{AtomicBool, Ordering};
521     ///
522     /// let foo = AtomicBool::new(true);
523     /// assert_eq!(foo.fetch_and(false, Ordering::SeqCst), true);
524     /// assert_eq!(foo.load(Ordering::SeqCst), false);
525     ///
526     /// let foo = AtomicBool::new(true);
527     /// assert_eq!(foo.fetch_and(true, Ordering::SeqCst), true);
528     /// assert_eq!(foo.load(Ordering::SeqCst), true);
529     ///
530     /// let foo = AtomicBool::new(false);
531     /// assert_eq!(foo.fetch_and(false, Ordering::SeqCst), false);
532     /// assert_eq!(foo.load(Ordering::SeqCst), false);
533     /// ```
534     #[inline]
535     #[stable(feature = "rust1", since = "1.0.0")]
536     pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
537         unsafe { atomic_and(self.v.get(), val as u8, order) != 0 }
538     }
539
540     /// Logical "nand" with a boolean value.
541     ///
542     /// Performs a logical "nand" operation on the current value and the argument `val`, and sets
543     /// the new value to the result.
544     ///
545     /// Returns the previous value.
546     ///
547     /// # Examples
548     ///
549     /// ```
550     /// use std::sync::atomic::{AtomicBool, Ordering};
551     ///
552     /// let foo = AtomicBool::new(true);
553     /// assert_eq!(foo.fetch_nand(false, Ordering::SeqCst), true);
554     /// assert_eq!(foo.load(Ordering::SeqCst), true);
555     ///
556     /// let foo = AtomicBool::new(true);
557     /// assert_eq!(foo.fetch_nand(true, Ordering::SeqCst), true);
558     /// assert_eq!(foo.load(Ordering::SeqCst) as usize, 0);
559     /// assert_eq!(foo.load(Ordering::SeqCst), false);
560     ///
561     /// let foo = AtomicBool::new(false);
562     /// assert_eq!(foo.fetch_nand(false, Ordering::SeqCst), false);
563     /// assert_eq!(foo.load(Ordering::SeqCst), true);
564     /// ```
565     #[inline]
566     #[stable(feature = "rust1", since = "1.0.0")]
567     pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
568         // We can't use atomic_nand here because it can result in a bool with
569         // an invalid value. This happens because the atomic operation is done
570         // with an 8-bit integer internally, which would set the upper 7 bits.
571         // So we just use fetch_xor or swap instead.
572         if val {
573             // !(x & true) == !x
574             // We must invert the bool.
575             self.fetch_xor(true, order)
576         } else {
577             // !(x & false) == true
578             // We must set the bool to true.
579             self.swap(true, order)
580         }
581     }
582
583     /// Logical "or" with a boolean value.
584     ///
585     /// Performs a logical "or" operation on the current value and the argument `val`, and sets the
586     /// new value to the result.
587     ///
588     /// Returns the previous value.
589     ///
590     /// # Examples
591     ///
592     /// ```
593     /// use std::sync::atomic::{AtomicBool, Ordering};
594     ///
595     /// let foo = AtomicBool::new(true);
596     /// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), true);
597     /// assert_eq!(foo.load(Ordering::SeqCst), true);
598     ///
599     /// let foo = AtomicBool::new(true);
600     /// assert_eq!(foo.fetch_or(true, Ordering::SeqCst), true);
601     /// assert_eq!(foo.load(Ordering::SeqCst), true);
602     ///
603     /// let foo = AtomicBool::new(false);
604     /// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), false);
605     /// assert_eq!(foo.load(Ordering::SeqCst), false);
606     /// ```
607     #[inline]
608     #[stable(feature = "rust1", since = "1.0.0")]
609     pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
610         unsafe { atomic_or(self.v.get(), val as u8, order) != 0 }
611     }
612
613     /// Logical "xor" with a boolean value.
614     ///
615     /// Performs a logical "xor" operation on the current value and the argument `val`, and sets
616     /// the new value to the result.
617     ///
618     /// Returns the previous value.
619     ///
620     /// # Examples
621     ///
622     /// ```
623     /// use std::sync::atomic::{AtomicBool, Ordering};
624     ///
625     /// let foo = AtomicBool::new(true);
626     /// assert_eq!(foo.fetch_xor(false, Ordering::SeqCst), true);
627     /// assert_eq!(foo.load(Ordering::SeqCst), true);
628     ///
629     /// let foo = AtomicBool::new(true);
630     /// assert_eq!(foo.fetch_xor(true, Ordering::SeqCst), true);
631     /// assert_eq!(foo.load(Ordering::SeqCst), false);
632     ///
633     /// let foo = AtomicBool::new(false);
634     /// assert_eq!(foo.fetch_xor(false, Ordering::SeqCst), false);
635     /// assert_eq!(foo.load(Ordering::SeqCst), false);
636     /// ```
637     #[inline]
638     #[stable(feature = "rust1", since = "1.0.0")]
639     pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
640         unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 }
641     }
642 }
643
644 #[cfg(target_has_atomic = "ptr")]
645 impl<T> AtomicPtr<T> {
646     /// Creates a new `AtomicPtr`.
647     ///
648     /// # Examples
649     ///
650     /// ```
651     /// use std::sync::atomic::AtomicPtr;
652     ///
653     /// let ptr = &mut 5;
654     /// let atomic_ptr  = AtomicPtr::new(ptr);
655     /// ```
656     #[inline]
657     #[stable(feature = "rust1", since = "1.0.0")]
658     pub const fn new(p: *mut T) -> AtomicPtr<T> {
659         AtomicPtr { p: UnsafeCell::new(p) }
660     }
661
662     /// Returns a mutable reference to the underlying pointer.
663     ///
664     /// This is safe because the mutable reference guarantees that no other threads are
665     /// concurrently accessing the atomic data.
666     ///
667     /// # Examples
668     ///
669     /// ```
670     /// use std::sync::atomic::{AtomicPtr, Ordering};
671     ///
672     /// let mut atomic_ptr = AtomicPtr::new(&mut 10);
673     /// *atomic_ptr.get_mut() = &mut 5;
674     /// assert_eq!(unsafe { *atomic_ptr.load(Ordering::SeqCst) }, 5);
675     /// ```
676     #[inline]
677     #[stable(feature = "atomic_access", since = "1.15.0")]
678     pub fn get_mut(&mut self) -> &mut *mut T {
679         unsafe { &mut *self.p.get() }
680     }
681
682     /// Consumes the atomic and returns the contained value.
683     ///
684     /// This is safe because passing `self` by value guarantees that no other threads are
685     /// concurrently accessing the atomic data.
686     ///
687     /// # Examples
688     ///
689     /// ```
690     /// use std::sync::atomic::AtomicPtr;
691     ///
692     /// let atomic_ptr = AtomicPtr::new(&mut 5);
693     /// assert_eq!(unsafe { *atomic_ptr.into_inner() }, 5);
694     /// ```
695     #[inline]
696     #[stable(feature = "atomic_access", since = "1.15.0")]
697     pub fn into_inner(self) -> *mut T {
698         unsafe { self.p.into_inner() }
699     }
700
701     /// Loads a value from the pointer.
702     ///
703     /// `load` takes an [`Ordering`] argument which describes the memory ordering
704     /// of this operation.
705     ///
706     /// # Panics
707     ///
708     /// Panics if `order` is [`Release`] or [`AcqRel`].
709     ///
710     /// [`Ordering`]: enum.Ordering.html
711     /// [`Release`]: enum.Ordering.html#variant.Release
712     /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
713     ///
714     /// # Examples
715     ///
716     /// ```
717     /// use std::sync::atomic::{AtomicPtr, Ordering};
718     ///
719     /// let ptr = &mut 5;
720     /// let some_ptr  = AtomicPtr::new(ptr);
721     ///
722     /// let value = some_ptr.load(Ordering::Relaxed);
723     /// ```
724     #[inline]
725     #[stable(feature = "rust1", since = "1.0.0")]
726     pub fn load(&self, order: Ordering) -> *mut T {
727         unsafe { atomic_load(self.p.get() as *mut usize, order) as *mut T }
728     }
729
730     /// Stores a value into the pointer.
731     ///
732     /// `store` takes an [`Ordering`] argument which describes the memory ordering
733     /// of this operation.
734     ///
735     /// [`Ordering`]: enum.Ordering.html
736     ///
737     /// # Examples
738     ///
739     /// ```
740     /// use std::sync::atomic::{AtomicPtr, Ordering};
741     ///
742     /// let ptr = &mut 5;
743     /// let some_ptr  = AtomicPtr::new(ptr);
744     ///
745     /// let other_ptr = &mut 10;
746     ///
747     /// some_ptr.store(other_ptr, Ordering::Relaxed);
748     /// ```
749     ///
750     /// # Panics
751     ///
752     /// Panics if `order` is [`Acquire`] or [`AcqRel`].
753     ///
754     /// [`Acquire`]: enum.Ordering.html#variant.Acquire
755     /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
756     #[inline]
757     #[stable(feature = "rust1", since = "1.0.0")]
758     pub fn store(&self, ptr: *mut T, order: Ordering) {
759         unsafe {
760             atomic_store(self.p.get() as *mut usize, ptr as usize, order);
761         }
762     }
763
764     /// Stores a value into the pointer, returning the previous value.
765     ///
766     /// `swap` takes an [`Ordering`] argument which describes the memory ordering
767     /// of this operation.
768     ///
769     /// [`Ordering`]: enum.Ordering.html
770     ///
771     /// # Examples
772     ///
773     /// ```
774     /// use std::sync::atomic::{AtomicPtr, Ordering};
775     ///
776     /// let ptr = &mut 5;
777     /// let some_ptr  = AtomicPtr::new(ptr);
778     ///
779     /// let other_ptr = &mut 10;
780     ///
781     /// let value = some_ptr.swap(other_ptr, Ordering::Relaxed);
782     /// ```
783     #[inline]
784     #[stable(feature = "rust1", since = "1.0.0")]
785     pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
786         unsafe { atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T }
787     }
788
789     /// Stores a value into the pointer if the current value is the same as the `current` value.
790     ///
791     /// The return value is always the previous value. If it is equal to `current`, then the value
792     /// was updated.
793     ///
794     /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
795     /// ordering of this operation.
796     ///
797     /// [`Ordering`]: enum.Ordering.html
798     ///
799     /// # Examples
800     ///
801     /// ```
802     /// use std::sync::atomic::{AtomicPtr, Ordering};
803     ///
804     /// let ptr = &mut 5;
805     /// let some_ptr  = AtomicPtr::new(ptr);
806     ///
807     /// let other_ptr   = &mut 10;
808     /// let another_ptr = &mut 10;
809     ///
810     /// let value = some_ptr.compare_and_swap(other_ptr, another_ptr, Ordering::Relaxed);
811     /// ```
812     #[inline]
813     #[stable(feature = "rust1", since = "1.0.0")]
814     pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) -> *mut T {
815         match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
816             Ok(x) => x,
817             Err(x) => x,
818         }
819     }
820
821     /// Stores a value into the pointer if the current value is the same as the `current` value.
822     ///
823     /// The return value is a result indicating whether the new value was written and containing
824     /// the previous value. On success this value is guaranteed to be equal to `current`.
825     ///
826     /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
827     /// ordering of this operation. The first describes the required ordering if
828     /// the operation succeeds while the second describes the required ordering when
829     /// the operation fails. The failure ordering can't be [`Release`] or [`AcqRel`]
830     /// and must be equivalent or weaker than the success ordering.
831     ///
832     /// [`Ordering`]: enum.Ordering.html
833     /// [`Release`]: enum.Ordering.html#variant.Release
834     /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
835     ///
836     /// # Examples
837     ///
838     /// ```
839     /// use std::sync::atomic::{AtomicPtr, Ordering};
840     ///
841     /// let ptr = &mut 5;
842     /// let some_ptr  = AtomicPtr::new(ptr);
843     ///
844     /// let other_ptr   = &mut 10;
845     /// let another_ptr = &mut 10;
846     ///
847     /// let value = some_ptr.compare_exchange(other_ptr, another_ptr,
848     ///                                       Ordering::SeqCst, Ordering::Relaxed);
849     /// ```
850     #[inline]
851     #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
852     pub fn compare_exchange(&self,
853                             current: *mut T,
854                             new: *mut T,
855                             success: Ordering,
856                             failure: Ordering)
857                             -> Result<*mut T, *mut T> {
858         unsafe {
859             let res = atomic_compare_exchange(self.p.get() as *mut usize,
860                                               current as usize,
861                                               new as usize,
862                                               success,
863                                               failure);
864             match res {
865                 Ok(x) => Ok(x as *mut T),
866                 Err(x) => Err(x as *mut T),
867             }
868         }
869     }
870
871     /// Stores a value into the pointer if the current value is the same as the `current` value.
872     ///
873     /// Unlike [`compare_exchange`], this function is allowed to spuriously fail even when the
874     /// comparison succeeds, which can result in more efficient code on some platforms. The
875     /// return value is a result indicating whether the new value was written and containing the
876     /// previous value.
877     ///
878     /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
879     /// ordering of this operation. The first describes the required ordering if the operation
880     /// succeeds while the second describes the required ordering when the operation fails. The
881     /// failure ordering can't be [`Release`] or [`AcqRel`] and must be equivalent or
882     /// weaker than the success ordering.
883     ///
884     /// [`compare_exchange`]: #method.compare_exchange
885     /// [`Ordering`]: enum.Ordering.html
886     /// [`Release`]: enum.Ordering.html#variant.Release
887     /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
888     ///
889     /// # Examples
890     ///
891     /// ```
892     /// use std::sync::atomic::{AtomicPtr, Ordering};
893     ///
894     /// let some_ptr = AtomicPtr::new(&mut 5);
895     ///
896     /// let new = &mut 10;
897     /// let mut old = some_ptr.load(Ordering::Relaxed);
898     /// loop {
899     ///     match some_ptr.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
900     ///         Ok(_) => break,
901     ///         Err(x) => old = x,
902     ///     }
903     /// }
904     /// ```
905     #[inline]
906     #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
907     pub fn compare_exchange_weak(&self,
908                                  current: *mut T,
909                                  new: *mut T,
910                                  success: Ordering,
911                                  failure: Ordering)
912                                  -> Result<*mut T, *mut T> {
913         unsafe {
914             let res = atomic_compare_exchange_weak(self.p.get() as *mut usize,
915                                                    current as usize,
916                                                    new as usize,
917                                                    success,
918                                                    failure);
919             match res {
920                 Ok(x) => Ok(x as *mut T),
921                 Err(x) => Err(x as *mut T),
922             }
923         }
924     }
925 }
926
927 #[cfg(target_has_atomic = "8")]
928 #[stable(feature = "atomic_bool_from", since = "1.24.0")]
929 impl From<bool> for AtomicBool {
930     #[inline]
931     fn from(b: bool) -> Self { Self::new(b) }
932 }
933
934 #[cfg(target_has_atomic = "ptr")]
935 #[stable(feature = "atomic_from", since = "1.23.0")]
936 impl<T> From<*mut T> for AtomicPtr<T> {
937     #[inline]
938     fn from(p: *mut T) -> Self { Self::new(p) }
939 }
940
941 #[cfg(target_has_atomic = "ptr")]
942 macro_rules! atomic_int {
943     ($stable:meta,
944      $stable_cxchg:meta,
945      $stable_debug:meta,
946      $stable_access:meta,
947      $stable_from:meta,
948      $s_int_type:expr, $int_ref:expr,
949      $int_type:ident $atomic_type:ident $atomic_init:ident) => {
950         /// An integer type which can be safely shared between threads.
951         ///
952         /// This type has the same in-memory representation as the underlying
953         /// integer type, [`
954         #[doc = $s_int_type]
955         /// `](
956         #[doc = $int_ref]
957         /// ). For more about the differences between atomic types and
958         /// non-atomic types, please see the [module-level documentation].
959         ///
960         /// Please note that examples are shared between atomic variants of
961         /// primitive integer types, so it's normal that they are all
962         /// demonstrating [`AtomicIsize`].
963         ///
964         /// [module-level documentation]: index.html
965         /// [`AtomicIsize`]: struct.AtomicIsize.html
966         #[$stable]
967         pub struct $atomic_type {
968             v: UnsafeCell<$int_type>,
969         }
970
971         /// An atomic integer initialized to `0`.
972         #[$stable]
973         pub const $atomic_init: $atomic_type = $atomic_type::new(0);
974
975         #[$stable]
976         impl Default for $atomic_type {
977             fn default() -> Self {
978                 Self::new(Default::default())
979             }
980         }
981
982         #[$stable_from]
983         impl From<$int_type> for $atomic_type {
984             #[inline]
985             fn from(v: $int_type) -> Self { Self::new(v) }
986         }
987
988         #[$stable_debug]
989         impl fmt::Debug for $atomic_type {
990             fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
991                 f.debug_tuple(stringify!($atomic_type))
992                  .field(&self.load(Ordering::SeqCst))
993                  .finish()
994             }
995         }
996
997         // Send is implicitly implemented.
998         #[$stable]
999         unsafe impl Sync for $atomic_type {}
1000
1001         impl $atomic_type {
1002             /// Creates a new atomic integer.
1003             ///
1004             /// # Examples
1005             ///
1006             /// ```
1007             /// use std::sync::atomic::AtomicIsize;
1008             ///
1009             /// let atomic_forty_two  = AtomicIsize::new(42);
1010             /// ```
1011             #[inline]
1012             #[$stable]
1013             pub const fn new(v: $int_type) -> Self {
1014                 $atomic_type {v: UnsafeCell::new(v)}
1015             }
1016
1017             /// Returns a mutable reference to the underlying integer.
1018             ///
1019             /// This is safe because the mutable reference guarantees that no other threads are
1020             /// concurrently accessing the atomic data.
1021             ///
1022             /// # Examples
1023             ///
1024             /// ```
1025             /// use std::sync::atomic::{AtomicIsize, Ordering};
1026             ///
1027             /// let mut some_isize = AtomicIsize::new(10);
1028             /// assert_eq!(*some_isize.get_mut(), 10);
1029             /// *some_isize.get_mut() = 5;
1030             /// assert_eq!(some_isize.load(Ordering::SeqCst), 5);
1031             /// ```
1032             #[inline]
1033             #[$stable_access]
1034             pub fn get_mut(&mut self) -> &mut $int_type {
1035                 unsafe { &mut *self.v.get() }
1036             }
1037
1038             /// Consumes the atomic and returns the contained value.
1039             ///
1040             /// This is safe because passing `self` by value guarantees that no other threads are
1041             /// concurrently accessing the atomic data.
1042             ///
1043             /// # Examples
1044             ///
1045             /// ```
1046             /// use std::sync::atomic::AtomicIsize;
1047             ///
1048             /// let some_isize = AtomicIsize::new(5);
1049             /// assert_eq!(some_isize.into_inner(), 5);
1050             /// ```
1051             #[inline]
1052             #[$stable_access]
1053             pub fn into_inner(self) -> $int_type {
1054                 unsafe { self.v.into_inner() }
1055             }
1056
1057             /// Loads a value from the atomic integer.
1058             ///
1059             /// `load` takes an [`Ordering`] argument which describes the memory ordering of this
1060             /// operation.
1061             ///
1062             /// # Panics
1063             ///
1064             /// Panics if `order` is [`Release`] or [`AcqRel`].
1065             ///
1066             /// [`Ordering`]: enum.Ordering.html
1067             /// [`Release`]: enum.Ordering.html#variant.Release
1068             /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
1069             ///
1070             /// # Examples
1071             ///
1072             /// ```
1073             /// use std::sync::atomic::{AtomicIsize, Ordering};
1074             ///
1075             /// let some_isize = AtomicIsize::new(5);
1076             ///
1077             /// assert_eq!(some_isize.load(Ordering::Relaxed), 5);
1078             /// ```
1079             #[inline]
1080             #[$stable]
1081             pub fn load(&self, order: Ordering) -> $int_type {
1082                 unsafe { atomic_load(self.v.get(), order) }
1083             }
1084
1085             /// Stores a value into the atomic integer.
1086             ///
1087             /// `store` takes an [`Ordering`] argument which describes the memory ordering of this
1088             /// operation.
1089             ///
1090             /// [`Ordering`]: enum.Ordering.html
1091             ///
1092             /// # Examples
1093             ///
1094             /// ```
1095             /// use std::sync::atomic::{AtomicIsize, Ordering};
1096             ///
1097             /// let some_isize = AtomicIsize::new(5);
1098             ///
1099             /// some_isize.store(10, Ordering::Relaxed);
1100             /// assert_eq!(some_isize.load(Ordering::Relaxed), 10);
1101             /// ```
1102             ///
1103             /// # Panics
1104             ///
1105             /// Panics if `order` is [`Acquire`] or [`AcqRel`].
1106             ///
1107             /// [`Acquire`]: enum.Ordering.html#variant.Acquire
1108             /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
1109             #[inline]
1110             #[$stable]
1111             pub fn store(&self, val: $int_type, order: Ordering) {
1112                 unsafe { atomic_store(self.v.get(), val, order); }
1113             }
1114
1115             /// Stores a value into the atomic integer, returning the previous value.
1116             ///
1117             /// `swap` takes an [`Ordering`] argument which describes the memory ordering of this
1118             /// operation.
1119             ///
1120             /// [`Ordering`]: enum.Ordering.html
1121             ///
1122             /// # Examples
1123             ///
1124             /// ```
1125             /// use std::sync::atomic::{AtomicIsize, Ordering};
1126             ///
1127             /// let some_isize = AtomicIsize::new(5);
1128             ///
1129             /// assert_eq!(some_isize.swap(10, Ordering::Relaxed), 5);
1130             /// ```
1131             #[inline]
1132             #[$stable]
1133             pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
1134                 unsafe { atomic_swap(self.v.get(), val, order) }
1135             }
1136
1137             /// Stores a value into the atomic integer if the current value is the same as the
1138             /// `current` value.
1139             ///
1140             /// The return value is always the previous value. If it is equal to `current`, then the
1141             /// value was updated.
1142             ///
1143             /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
1144             /// ordering of this operation.
1145             ///
1146             /// [`Ordering`]: enum.Ordering.html
1147             ///
1148             /// # Examples
1149             ///
1150             /// ```
1151             /// use std::sync::atomic::{AtomicIsize, Ordering};
1152             ///
1153             /// let some_isize = AtomicIsize::new(5);
1154             ///
1155             /// assert_eq!(some_isize.compare_and_swap(5, 10, Ordering::Relaxed), 5);
1156             /// assert_eq!(some_isize.load(Ordering::Relaxed), 10);
1157             ///
1158             /// assert_eq!(some_isize.compare_and_swap(6, 12, Ordering::Relaxed), 10);
1159             /// assert_eq!(some_isize.load(Ordering::Relaxed), 10);
1160             /// ```
1161             #[inline]
1162             #[$stable]
1163             pub fn compare_and_swap(&self,
1164                                     current: $int_type,
1165                                     new: $int_type,
1166                                     order: Ordering) -> $int_type {
1167                 match self.compare_exchange(current,
1168                                             new,
1169                                             order,
1170                                             strongest_failure_ordering(order)) {
1171                     Ok(x) => x,
1172                     Err(x) => x,
1173                 }
1174             }
1175
1176             /// Stores a value into the atomic integer if the current value is the same as the
1177             /// `current` value.
1178             ///
1179             /// The return value is a result indicating whether the new value was written and
1180             /// containing the previous value. On success this value is guaranteed to be equal to
1181             /// `current`.
1182             ///
1183             /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
1184             /// ordering of this operation. The first describes the required ordering if
1185             /// the operation succeeds while the second describes the required ordering when
1186             /// the operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and
1187             /// must be equivalent or weaker than the success ordering.
1188             ///
1189             /// [`Ordering`]: enum.Ordering.html
1190             /// [`Release`]: enum.Ordering.html#variant.Release
1191             /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
1192             ///
1193             /// # Examples
1194             ///
1195             /// ```
1196             /// use std::sync::atomic::{AtomicIsize, Ordering};
1197             ///
1198             /// let some_isize = AtomicIsize::new(5);
1199             ///
1200             /// assert_eq!(some_isize.compare_exchange(5, 10,
1201             ///                                        Ordering::Acquire,
1202             ///                                        Ordering::Relaxed),
1203             ///            Ok(5));
1204             /// assert_eq!(some_isize.load(Ordering::Relaxed), 10);
1205             ///
1206             /// assert_eq!(some_isize.compare_exchange(6, 12,
1207             ///                                        Ordering::SeqCst,
1208             ///                                        Ordering::Acquire),
1209             ///            Err(10));
1210             /// assert_eq!(some_isize.load(Ordering::Relaxed), 10);
1211             /// ```
1212             #[inline]
1213             #[$stable_cxchg]
1214             pub fn compare_exchange(&self,
1215                                     current: $int_type,
1216                                     new: $int_type,
1217                                     success: Ordering,
1218                                     failure: Ordering) -> Result<$int_type, $int_type> {
1219                 unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) }
1220             }
1221
1222             /// Stores a value into the atomic integer if the current value is the same as the
1223             /// `current` value.
1224             ///
1225             /// Unlike [`compare_exchange`], this function is allowed to spuriously fail even
1226             /// when the comparison succeeds, which can result in more efficient code on some
1227             /// platforms. The return value is a result indicating whether the new value was
1228             /// written and containing the previous value.
1229             ///
1230             /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
1231             /// ordering of this operation. The first describes the required ordering if the
1232             /// operation succeeds while the second describes the required ordering when the
1233             /// operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and
1234             /// must be equivalent or weaker than the success ordering.
1235             ///
1236             /// [`compare_exchange`]: #method.compare_exchange
1237             /// [`Ordering`]: enum.Ordering.html
1238             /// [`Release`]: enum.Ordering.html#variant.Release
1239             /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
1240             ///
1241             /// # Examples
1242             ///
1243             /// ```
1244             /// use std::sync::atomic::{AtomicIsize, Ordering};
1245             ///
1246             /// let val = AtomicIsize::new(4);
1247             ///
1248             /// let mut old = val.load(Ordering::Relaxed);
1249             /// loop {
1250             ///     let new = old * 2;
1251             ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
1252             ///         Ok(_) => break,
1253             ///         Err(x) => old = x,
1254             ///     }
1255             /// }
1256             /// ```
1257             #[inline]
1258             #[$stable_cxchg]
1259             pub fn compare_exchange_weak(&self,
1260                                          current: $int_type,
1261                                          new: $int_type,
1262                                          success: Ordering,
1263                                          failure: Ordering) -> Result<$int_type, $int_type> {
1264                 unsafe {
1265                     atomic_compare_exchange_weak(self.v.get(), current, new, success, failure)
1266                 }
1267             }
1268
1269             /// Adds to the current value, returning the previous value.
1270             ///
1271             /// This operation wraps around on overflow.
1272             ///
1273             /// # Examples
1274             ///
1275             /// ```
1276             /// use std::sync::atomic::{AtomicIsize, Ordering};
1277             ///
1278             /// let foo = AtomicIsize::new(0);
1279             /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
1280             /// assert_eq!(foo.load(Ordering::SeqCst), 10);
1281             /// ```
1282             #[inline]
1283             #[$stable]
1284             pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
1285                 unsafe { atomic_add(self.v.get(), val, order) }
1286             }
1287
1288             /// Subtracts from the current value, returning the previous value.
1289             ///
1290             /// This operation wraps around on overflow.
1291             ///
1292             /// # Examples
1293             ///
1294             /// ```
1295             /// use std::sync::atomic::{AtomicIsize, Ordering};
1296             ///
1297             /// let foo = AtomicIsize::new(0);
1298             /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 0);
1299             /// assert_eq!(foo.load(Ordering::SeqCst), -10);
1300             /// ```
1301             #[inline]
1302             #[$stable]
1303             pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
1304                 unsafe { atomic_sub(self.v.get(), val, order) }
1305             }
1306
1307             /// Bitwise "and" with the current value.
1308             ///
1309             /// Performs a bitwise "and" operation on the current value and the argument `val`, and
1310             /// sets the new value to the result.
1311             ///
1312             /// Returns the previous value.
1313             ///
1314             /// # Examples
1315             ///
1316             /// ```
1317             /// use std::sync::atomic::{AtomicIsize, Ordering};
1318             ///
1319             /// let foo = AtomicIsize::new(0b101101);
1320             /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
1321             /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
1322             #[inline]
1323             #[$stable]
1324             pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
1325                 unsafe { atomic_and(self.v.get(), val, order) }
1326             }
1327
1328             /// Bitwise "or" with the current value.
1329             ///
1330             /// Performs a bitwise "or" operation on the current value and the argument `val`, and
1331             /// sets the new value to the result.
1332             ///
1333             /// Returns the previous value.
1334             ///
1335             /// # Examples
1336             ///
1337             /// ```
1338             /// use std::sync::atomic::{AtomicIsize, Ordering};
1339             ///
1340             /// let foo = AtomicIsize::new(0b101101);
1341             /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
1342             /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
1343             #[inline]
1344             #[$stable]
1345             pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
1346                 unsafe { atomic_or(self.v.get(), val, order) }
1347             }
1348
1349             /// Bitwise "xor" with the current value.
1350             ///
1351             /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
1352             /// sets the new value to the result.
1353             ///
1354             /// Returns the previous value.
1355             ///
1356             /// # Examples
1357             ///
1358             /// ```
1359             /// use std::sync::atomic::{AtomicIsize, Ordering};
1360             ///
1361             /// let foo = AtomicIsize::new(0b101101);
1362             /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
1363             /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
1364             #[inline]
1365             #[$stable]
1366             pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
1367                 unsafe { atomic_xor(self.v.get(), val, order) }
1368             }
1369         }
1370     }
1371 }
1372
1373 #[cfg(target_has_atomic = "8")]
1374 atomic_int! {
1375     unstable(feature = "integer_atomics", issue = "32976"),
1376     unstable(feature = "integer_atomics", issue = "32976"),
1377     unstable(feature = "integer_atomics", issue = "32976"),
1378     unstable(feature = "integer_atomics", issue = "32976"),
1379     unstable(feature = "integer_atomics", issue = "32976"),
1380     "i8", "../../../std/primitive.i8.html",
1381     i8 AtomicI8 ATOMIC_I8_INIT
1382 }
1383 #[cfg(target_has_atomic = "8")]
1384 atomic_int! {
1385     unstable(feature = "integer_atomics", issue = "32976"),
1386     unstable(feature = "integer_atomics", issue = "32976"),
1387     unstable(feature = "integer_atomics", issue = "32976"),
1388     unstable(feature = "integer_atomics", issue = "32976"),
1389     unstable(feature = "integer_atomics", issue = "32976"),
1390     "u8", "../../../std/primitive.u8.html",
1391     u8 AtomicU8 ATOMIC_U8_INIT
1392 }
1393 #[cfg(target_has_atomic = "16")]
1394 atomic_int! {
1395     unstable(feature = "integer_atomics", issue = "32976"),
1396     unstable(feature = "integer_atomics", issue = "32976"),
1397     unstable(feature = "integer_atomics", issue = "32976"),
1398     unstable(feature = "integer_atomics", issue = "32976"),
1399     unstable(feature = "integer_atomics", issue = "32976"),
1400     "i16", "../../../std/primitive.i16.html",
1401     i16 AtomicI16 ATOMIC_I16_INIT
1402 }
1403 #[cfg(target_has_atomic = "16")]
1404 atomic_int! {
1405     unstable(feature = "integer_atomics", issue = "32976"),
1406     unstable(feature = "integer_atomics", issue = "32976"),
1407     unstable(feature = "integer_atomics", issue = "32976"),
1408     unstable(feature = "integer_atomics", issue = "32976"),
1409     unstable(feature = "integer_atomics", issue = "32976"),
1410     "u16", "../../../std/primitive.u16.html",
1411     u16 AtomicU16 ATOMIC_U16_INIT
1412 }
1413 #[cfg(target_has_atomic = "32")]
1414 atomic_int! {
1415     unstable(feature = "integer_atomics", issue = "32976"),
1416     unstable(feature = "integer_atomics", issue = "32976"),
1417     unstable(feature = "integer_atomics", issue = "32976"),
1418     unstable(feature = "integer_atomics", issue = "32976"),
1419     unstable(feature = "integer_atomics", issue = "32976"),
1420     "i32", "../../../std/primitive.i32.html",
1421     i32 AtomicI32 ATOMIC_I32_INIT
1422 }
1423 #[cfg(target_has_atomic = "32")]
1424 atomic_int! {
1425     unstable(feature = "integer_atomics", issue = "32976"),
1426     unstable(feature = "integer_atomics", issue = "32976"),
1427     unstable(feature = "integer_atomics", issue = "32976"),
1428     unstable(feature = "integer_atomics", issue = "32976"),
1429     unstable(feature = "integer_atomics", issue = "32976"),
1430     "u32", "../../../std/primitive.u32.html",
1431     u32 AtomicU32 ATOMIC_U32_INIT
1432 }
1433 #[cfg(target_has_atomic = "64")]
1434 atomic_int! {
1435     unstable(feature = "integer_atomics", issue = "32976"),
1436     unstable(feature = "integer_atomics", issue = "32976"),
1437     unstable(feature = "integer_atomics", issue = "32976"),
1438     unstable(feature = "integer_atomics", issue = "32976"),
1439     unstable(feature = "integer_atomics", issue = "32976"),
1440     "i64", "../../../std/primitive.i64.html",
1441     i64 AtomicI64 ATOMIC_I64_INIT
1442 }
1443 #[cfg(target_has_atomic = "64")]
1444 atomic_int! {
1445     unstable(feature = "integer_atomics", issue = "32976"),
1446     unstable(feature = "integer_atomics", issue = "32976"),
1447     unstable(feature = "integer_atomics", issue = "32976"),
1448     unstable(feature = "integer_atomics", issue = "32976"),
1449     unstable(feature = "integer_atomics", issue = "32976"),
1450     "u64", "../../../std/primitive.u64.html",
1451     u64 AtomicU64 ATOMIC_U64_INIT
1452 }
1453 #[cfg(target_has_atomic = "ptr")]
1454 atomic_int!{
1455     stable(feature = "rust1", since = "1.0.0"),
1456     stable(feature = "extended_compare_and_swap", since = "1.10.0"),
1457     stable(feature = "atomic_debug", since = "1.3.0"),
1458     stable(feature = "atomic_access", since = "1.15.0"),
1459     stable(feature = "atomic_from", since = "1.23.0"),
1460     "isize", "../../../std/primitive.isize.html",
1461     isize AtomicIsize ATOMIC_ISIZE_INIT
1462 }
1463 #[cfg(target_has_atomic = "ptr")]
1464 atomic_int!{
1465     stable(feature = "rust1", since = "1.0.0"),
1466     stable(feature = "extended_compare_and_swap", since = "1.10.0"),
1467     stable(feature = "atomic_debug", since = "1.3.0"),
1468     stable(feature = "atomic_access", since = "1.15.0"),
1469     stable(feature = "atomic_from", since = "1.23.0"),
1470     "usize", "../../../std/primitive.usize.html",
1471     usize AtomicUsize ATOMIC_USIZE_INIT
1472 }
1473
1474 #[inline]
1475 fn strongest_failure_ordering(order: Ordering) -> Ordering {
1476     match order {
1477         Release => Relaxed,
1478         Relaxed => Relaxed,
1479         SeqCst => SeqCst,
1480         Acquire => Acquire,
1481         AcqRel => Acquire,
1482         __Nonexhaustive => __Nonexhaustive,
1483     }
1484 }
1485
1486 #[inline]
1487 unsafe fn atomic_store<T>(dst: *mut T, val: T, order: Ordering) {
1488     match order {
1489         Release => intrinsics::atomic_store_rel(dst, val),
1490         Relaxed => intrinsics::atomic_store_relaxed(dst, val),
1491         SeqCst => intrinsics::atomic_store(dst, val),
1492         Acquire => panic!("there is no such thing as an acquire store"),
1493         AcqRel => panic!("there is no such thing as an acquire/release store"),
1494         __Nonexhaustive => panic!("invalid memory ordering"),
1495     }
1496 }
1497
1498 #[inline]
1499 unsafe fn atomic_load<T>(dst: *const T, order: Ordering) -> T {
1500     match order {
1501         Acquire => intrinsics::atomic_load_acq(dst),
1502         Relaxed => intrinsics::atomic_load_relaxed(dst),
1503         SeqCst => intrinsics::atomic_load(dst),
1504         Release => panic!("there is no such thing as a release load"),
1505         AcqRel => panic!("there is no such thing as an acquire/release load"),
1506         __Nonexhaustive => panic!("invalid memory ordering"),
1507     }
1508 }
1509
1510 #[inline]
1511 unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T {
1512     match order {
1513         Acquire => intrinsics::atomic_xchg_acq(dst, val),
1514         Release => intrinsics::atomic_xchg_rel(dst, val),
1515         AcqRel => intrinsics::atomic_xchg_acqrel(dst, val),
1516         Relaxed => intrinsics::atomic_xchg_relaxed(dst, val),
1517         SeqCst => intrinsics::atomic_xchg(dst, val),
1518         __Nonexhaustive => panic!("invalid memory ordering"),
1519     }
1520 }
1521
1522 /// Returns the previous value (like __sync_fetch_and_add).
1523 #[inline]
1524 unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T {
1525     match order {
1526         Acquire => intrinsics::atomic_xadd_acq(dst, val),
1527         Release => intrinsics::atomic_xadd_rel(dst, val),
1528         AcqRel => intrinsics::atomic_xadd_acqrel(dst, val),
1529         Relaxed => intrinsics::atomic_xadd_relaxed(dst, val),
1530         SeqCst => intrinsics::atomic_xadd(dst, val),
1531         __Nonexhaustive => panic!("invalid memory ordering"),
1532     }
1533 }
1534
1535 /// Returns the previous value (like __sync_fetch_and_sub).
1536 #[inline]
1537 unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T {
1538     match order {
1539         Acquire => intrinsics::atomic_xsub_acq(dst, val),
1540         Release => intrinsics::atomic_xsub_rel(dst, val),
1541         AcqRel => intrinsics::atomic_xsub_acqrel(dst, val),
1542         Relaxed => intrinsics::atomic_xsub_relaxed(dst, val),
1543         SeqCst => intrinsics::atomic_xsub(dst, val),
1544         __Nonexhaustive => panic!("invalid memory ordering"),
1545     }
1546 }
1547
1548 #[inline]
1549 unsafe fn atomic_compare_exchange<T>(dst: *mut T,
1550                                      old: T,
1551                                      new: T,
1552                                      success: Ordering,
1553                                      failure: Ordering)
1554                                      -> Result<T, T> {
1555     let (val, ok) = match (success, failure) {
1556         (Acquire, Acquire) => intrinsics::atomic_cxchg_acq(dst, old, new),
1557         (Release, Relaxed) => intrinsics::atomic_cxchg_rel(dst, old, new),
1558         (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel(dst, old, new),
1559         (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed(dst, old, new),
1560         (SeqCst, SeqCst) => intrinsics::atomic_cxchg(dst, old, new),
1561         (Acquire, Relaxed) => intrinsics::atomic_cxchg_acq_failrelaxed(dst, old, new),
1562         (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_failrelaxed(dst, old, new),
1563         (SeqCst, Relaxed) => intrinsics::atomic_cxchg_failrelaxed(dst, old, new),
1564         (SeqCst, Acquire) => intrinsics::atomic_cxchg_failacq(dst, old, new),
1565         (__Nonexhaustive, _) => panic!("invalid memory ordering"),
1566         (_, __Nonexhaustive) => panic!("invalid memory ordering"),
1567         (_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"),
1568         (_, Release) => panic!("there is no such thing as a release failure ordering"),
1569         _ => panic!("a failure ordering can't be stronger than a success ordering"),
1570     };
1571     if ok { Ok(val) } else { Err(val) }
1572 }
1573
1574 #[inline]
1575 unsafe fn atomic_compare_exchange_weak<T>(dst: *mut T,
1576                                           old: T,
1577                                           new: T,
1578                                           success: Ordering,
1579                                           failure: Ordering)
1580                                           -> Result<T, T> {
1581     let (val, ok) = match (success, failure) {
1582         (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acq(dst, old, new),
1583         (Release, Relaxed) => intrinsics::atomic_cxchgweak_rel(dst, old, new),
1584         (AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel(dst, old, new),
1585         (Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed(dst, old, new),
1586         (SeqCst, SeqCst) => intrinsics::atomic_cxchgweak(dst, old, new),
1587         (Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acq_failrelaxed(dst, old, new),
1588         (AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_failrelaxed(dst, old, new),
1589         (SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_failrelaxed(dst, old, new),
1590         (SeqCst, Acquire) => intrinsics::atomic_cxchgweak_failacq(dst, old, new),
1591         (__Nonexhaustive, _) => panic!("invalid memory ordering"),
1592         (_, __Nonexhaustive) => panic!("invalid memory ordering"),
1593         (_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"),
1594         (_, Release) => panic!("there is no such thing as a release failure ordering"),
1595         _ => panic!("a failure ordering can't be stronger than a success ordering"),
1596     };
1597     if ok { Ok(val) } else { Err(val) }
1598 }
1599
1600 #[inline]
1601 unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T {
1602     match order {
1603         Acquire => intrinsics::atomic_and_acq(dst, val),
1604         Release => intrinsics::atomic_and_rel(dst, val),
1605         AcqRel => intrinsics::atomic_and_acqrel(dst, val),
1606         Relaxed => intrinsics::atomic_and_relaxed(dst, val),
1607         SeqCst => intrinsics::atomic_and(dst, val),
1608         __Nonexhaustive => panic!("invalid memory ordering"),
1609     }
1610 }
1611
1612 #[inline]
1613 unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T {
1614     match order {
1615         Acquire => intrinsics::atomic_or_acq(dst, val),
1616         Release => intrinsics::atomic_or_rel(dst, val),
1617         AcqRel => intrinsics::atomic_or_acqrel(dst, val),
1618         Relaxed => intrinsics::atomic_or_relaxed(dst, val),
1619         SeqCst => intrinsics::atomic_or(dst, val),
1620         __Nonexhaustive => panic!("invalid memory ordering"),
1621     }
1622 }
1623
1624 #[inline]
1625 unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
1626     match order {
1627         Acquire => intrinsics::atomic_xor_acq(dst, val),
1628         Release => intrinsics::atomic_xor_rel(dst, val),
1629         AcqRel => intrinsics::atomic_xor_acqrel(dst, val),
1630         Relaxed => intrinsics::atomic_xor_relaxed(dst, val),
1631         SeqCst => intrinsics::atomic_xor(dst, val),
1632         __Nonexhaustive => panic!("invalid memory ordering"),
1633     }
1634 }
1635
1636 /// An atomic fence.
1637 ///
1638 /// Depending on the specified order, a fence prevents the compiler and CPU from
1639 /// reordering certain types of memory operations around it.
1640 /// That creates synchronizes-with relationships between it and atomic operations
1641 /// or fences in other threads.
1642 ///
1643 /// A fence 'A' which has (at least) [`Release`] ordering semantics, synchronizes
1644 /// with a fence 'B' with (at least) [`Acquire`] semantics, if and only if there
1645 /// exist operations X and Y, both operating on some atomic object 'M' such
1646 /// that A is sequenced before X, Y is synchronized before B and Y observes
1647 /// the change to M. This provides a happens-before dependence between A and B.
1648 ///
1649 /// ```text
1650 ///     Thread 1                                          Thread 2
1651 ///
1652 /// fence(Release);      A --------------
1653 /// x.store(3, Relaxed); X ---------    |
1654 ///                                |    |
1655 ///                                |    |
1656 ///                                -------------> Y  if x.load(Relaxed) == 3 {
1657 ///                                     |-------> B      fence(Acquire);
1658 ///                                                      ...
1659 ///                                                  }
1660 /// ```
1661 ///
1662 /// Atomic operations with [`Release`] or [`Acquire`] semantics can also synchronize
1663 /// with a fence.
1664 ///
1665 /// A fence which has [`SeqCst`] ordering, in addition to having both [`Acquire`]
1666 /// and [`Release`] semantics, participates in the global program order of the
1667 /// other [`SeqCst`] operations and/or fences.
1668 ///
1669 /// Accepts [`Acquire`], [`Release`], [`AcqRel`] and [`SeqCst`] orderings.
1670 ///
1671 /// # Panics
1672 ///
1673 /// Panics if `order` is [`Relaxed`].
1674 ///
1675 /// # Examples
1676 ///
1677 /// ```
1678 /// use std::sync::atomic::AtomicBool;
1679 /// use std::sync::atomic::fence;
1680 /// use std::sync::atomic::Ordering;
1681 ///
1682 /// // A mutual exclusion primitive based on spinlock.
1683 /// pub struct Mutex {
1684 ///     flag: AtomicBool,
1685 /// }
1686 ///
1687 /// impl Mutex {
1688 ///     pub fn new() -> Mutex {
1689 ///         Mutex {
1690 ///             flag: AtomicBool::new(false),
1691 ///         }
1692 ///     }
1693 ///
1694 ///     pub fn lock(&self) {
1695 ///         while !self.flag.compare_and_swap(false, true, Ordering::Relaxed) {}
1696 ///         // This fence synchronizes-with store in `unlock`.
1697 ///         fence(Ordering::Acquire);
1698 ///     }
1699 ///
1700 ///     pub fn unlock(&self) {
1701 ///         self.flag.store(false, Ordering::Release);
1702 ///     }
1703 /// }
1704 /// ```
1705 ///
1706 /// [`Ordering`]: enum.Ordering.html
1707 /// [`Acquire`]: enum.Ordering.html#variant.Acquire
1708 /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
1709 /// [`Release`]: enum.Ordering.html#variant.Release
1710 /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
1711 /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1712 #[inline]
1713 #[stable(feature = "rust1", since = "1.0.0")]
1714 pub fn fence(order: Ordering) {
1715     unsafe {
1716         match order {
1717             Acquire => intrinsics::atomic_fence_acq(),
1718             Release => intrinsics::atomic_fence_rel(),
1719             AcqRel => intrinsics::atomic_fence_acqrel(),
1720             SeqCst => intrinsics::atomic_fence(),
1721             Relaxed => panic!("there is no such thing as a relaxed fence"),
1722             __Nonexhaustive => panic!("invalid memory ordering"),
1723         }
1724     }
1725 }
1726
1727
1728 /// A compiler memory fence.
1729 ///
1730 /// `compiler_fence` does not emit any machine code, but restricts the kinds
1731 /// of memory re-ordering the compiler is allowed to do. Specifically, depending on
1732 /// the given [`Ordering`] semantics, the compiler may be disallowed from moving reads
1733 /// or writes from before or after the call to the other side of the call to
1734 /// `compiler_fence`. Note that it does **not** prevent the *hardware*
1735 /// from doing such re-ordering. This is not a problem in a single-threaded,
1736 /// execution context, but when other threads may modify memory at the same
1737 /// time, stronger synchronization primitives such as [`fence`] are required.
1738 ///
1739 /// The re-ordering prevented by the different ordering semantics are:
1740 ///
1741 ///  - with [`SeqCst`], no re-ordering of reads and writes across this point is allowed.
1742 ///  - with [`Release`], preceding reads and writes cannot be moved past subsequent writes.
1743 ///  - with [`Acquire`], subsequent reads and writes cannot be moved ahead of preceding reads.
1744 ///  - with [`AcqRel`], both of the above rules are enforced.
1745 ///
1746 /// `compiler_fence` is generally only useful for preventing a thread from
1747 /// racing *with itself*. That is, if a given thread is executing one piece
1748 /// of code, and is then interrupted, and starts executing code elsewhere
1749 /// (while still in the same thread, and conceptually still on the same
1750 /// core). In traditional programs, this can only occur when a signal
1751 /// handler is registered. In more low-level code, such situations can also
1752 /// arise when handling interrupts, when implementing green threads with
1753 /// pre-emption, etc. Curious readers are encouraged to read the Linux kernel's
1754 /// discussion of [memory barriers].
1755 ///
1756 /// # Panics
1757 ///
1758 /// Panics if `order` is [`Relaxed`].
1759 ///
1760 /// # Examples
1761 ///
1762 /// Without `compiler_fence`, the `assert_eq!` in following code
1763 /// is *not* guaranteed to succeed, despite everything happening in a single thread.
1764 /// To see why, remember that the compiler is free to swap the stores to
1765 /// `IMPORTANT_VARIABLE` and `IS_READ` since they are both
1766 /// `Ordering::Relaxed`. If it does, and the signal handler is invoked right
1767 /// after `IS_READY` is updated, then the signal handler will see
1768 /// `IS_READY=1`, but `IMPORTANT_VARIABLE=0`.
1769 /// Using a `compiler_fence` remedies this situation.
1770 ///
1771 /// ```
1772 /// use std::sync::atomic::{AtomicBool, AtomicUsize};
1773 /// use std::sync::atomic::{ATOMIC_BOOL_INIT, ATOMIC_USIZE_INIT};
1774 /// use std::sync::atomic::Ordering;
1775 /// use std::sync::atomic::compiler_fence;
1776 ///
1777 /// static IMPORTANT_VARIABLE: AtomicUsize = ATOMIC_USIZE_INIT;
1778 /// static IS_READY: AtomicBool = ATOMIC_BOOL_INIT;
1779 ///
1780 /// fn main() {
1781 ///     IMPORTANT_VARIABLE.store(42, Ordering::Relaxed);
1782 ///     // prevent earlier writes from being moved beyond this point
1783 ///     compiler_fence(Ordering::Release);
1784 ///     IS_READY.store(true, Ordering::Relaxed);
1785 /// }
1786 ///
1787 /// fn signal_handler() {
1788 ///     if IS_READY.load(Ordering::Relaxed) {
1789 ///         assert_eq!(IMPORTANT_VARIABLE.load(Ordering::Relaxed), 42);
1790 ///     }
1791 /// }
1792 /// ```
1793 ///
1794 /// [`fence`]: fn.fence.html
1795 /// [`Ordering`]: enum.Ordering.html
1796 /// [`Acquire`]: enum.Ordering.html#variant.Acquire
1797 /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
1798 /// [`Release`]: enum.Ordering.html#variant.Release
1799 /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
1800 /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
1801 /// [memory barriers]: https://www.kernel.org/doc/Documentation/memory-barriers.txt
1802 #[inline]
1803 #[stable(feature = "compiler_fences", since = "1.21.0")]
1804 pub fn compiler_fence(order: Ordering) {
1805     unsafe {
1806         match order {
1807             Acquire => intrinsics::atomic_singlethreadfence_acq(),
1808             Release => intrinsics::atomic_singlethreadfence_rel(),
1809             AcqRel => intrinsics::atomic_singlethreadfence_acqrel(),
1810             SeqCst => intrinsics::atomic_singlethreadfence(),
1811             Relaxed => panic!("there is no such thing as a relaxed compiler fence"),
1812             __Nonexhaustive => panic!("invalid memory ordering"),
1813         }
1814     }
1815 }
1816
1817
1818 #[cfg(target_has_atomic = "8")]
1819 #[stable(feature = "atomic_debug", since = "1.3.0")]
1820 impl fmt::Debug for AtomicBool {
1821     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1822         f.debug_tuple("AtomicBool").field(&self.load(Ordering::SeqCst)).finish()
1823     }
1824 }
1825
1826 #[cfg(target_has_atomic = "ptr")]
1827 #[stable(feature = "atomic_debug", since = "1.3.0")]
1828 impl<T> fmt::Debug for AtomicPtr<T> {
1829     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1830         f.debug_tuple("AtomicPtr").field(&self.load(Ordering::SeqCst)).finish()
1831     }
1832 }
1833
1834 #[cfg(target_has_atomic = "ptr")]
1835 #[stable(feature = "atomic_pointer", since = "1.24.0")]
1836 impl<T> fmt::Pointer for AtomicPtr<T> {
1837     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1838         fmt::Pointer::fmt(&self.load(Ordering::SeqCst), f)
1839     }
1840 }