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