1 //! Implementation of an atomic u64 cell. On 64 bit platforms, this is a wrapper
2 //! around `AtomicUsize`. On 32 bit platforms, this is implemented using a
3 //! `Mutex`.
4 //!
5 //! This file can be removed if/when `AtomicU64` lands in `std`.
6 
7 pub use self::imp::AtomicU64;
8 
9 #[cfg(target_pointer_width = "64")]
10 mod imp {
11     use std::sync::atomic::{AtomicUsize, Ordering};
12 
13     #[derive(Debug)]
14     pub struct AtomicU64 {
15         inner: AtomicUsize,
16     }
17 
18     impl AtomicU64 {
new(val: u64) -> AtomicU6419         pub fn new(val: u64) -> AtomicU64 {
20             AtomicU64 {
21                 inner: AtomicUsize::new(val as usize),
22             }
23         }
24 
load(&self, ordering: Ordering) -> u6425         pub fn load(&self, ordering: Ordering) -> u64 {
26             self.inner.load(ordering) as u64
27         }
28 
store(&self, val: u64, ordering: Ordering)29         pub fn store(&self, val: u64, ordering: Ordering) {
30             self.inner.store(val as usize, ordering)
31         }
32 
fetch_or(&self, val: u64, ordering: Ordering) -> u6433         pub fn fetch_or(&self, val: u64, ordering: Ordering) -> u64 {
34             self.inner.fetch_or(val as usize, ordering) as u64
35         }
36 
compare_and_swap(&self, old: u64, new: u64, ordering: Ordering) -> u6437         pub fn compare_and_swap(&self, old: u64, new: u64, ordering: Ordering) -> u64 {
38             self.inner
39                 .compare_and_swap(old as usize, new as usize, ordering) as u64
40         }
41     }
42 }
43 
44 #[cfg(not(target_pointer_width = "64"))]
45 mod imp {
46     use std::sync::atomic::Ordering;
47     use std::sync::Mutex;
48 
49     #[derive(Debug)]
50     pub struct AtomicU64 {
51         inner: Mutex<u64>,
52     }
53 
54     impl AtomicU64 {
new(val: u64) -> AtomicU6455         pub fn new(val: u64) -> AtomicU64 {
56             AtomicU64 {
57                 inner: Mutex::new(val),
58             }
59         }
60 
load(&self, _: Ordering) -> u6461         pub fn load(&self, _: Ordering) -> u64 {
62             *self.inner.lock().unwrap()
63         }
64 
store(&self, val: u64, _: Ordering)65         pub fn store(&self, val: u64, _: Ordering) {
66             *self.inner.lock().unwrap() = val;
67         }
68 
fetch_or(&self, val: u64, _: Ordering) -> u6469         pub fn fetch_or(&self, val: u64, _: Ordering) -> u64 {
70             let mut lock = self.inner.lock().unwrap();
71             let prev = *lock;
72             *lock = prev | val;
73             prev
74         }
75 
compare_and_swap(&self, old: u64, new: u64, _: Ordering) -> u6476         pub fn compare_and_swap(&self, old: u64, new: u64, _: Ordering) -> u64 {
77             let mut lock = self.inner.lock().unwrap();
78             let prev = *lock;
79 
80             if prev != old {
81                 return prev;
82             }
83 
84             *lock = new;
85             prev
86         }
87     }
88 }
89