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