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