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