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