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