# atomic_u64.rs - source
Source of the Rust file `/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.4.0/src/loom/std/atomic_u64.rs`.
Keywords: rust, rustlang, rust-lang

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75

    //! Implementation of an atomic u64 cell. On 64 bit platforms, this is a
    //! re-export of `AtomicU64`. On 32 bit platforms, this is implemented using a
    //! `Mutex`.

    pub(crate) use self::imp::AtomicU64;

    // `AtomicU64` can only be used on targets with `target_has_atomic` is 64 or greater.
    // Once `cfg_target_has_atomic` feature is stable, we can replace it with
    // `#[cfg(target_has_atomic = "64")]`.
    // Refs: https://github.com/rust-lang/rust/tree/master/src/librustc_target
    #[cfg(not(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc")))]
    mod imp {
        pub(crate) use std::sync::atomic::AtomicU64;
    }

    #[cfg(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc"))]
    mod imp {
        use std::sync::atomic::Ordering;
        use std::sync::Mutex;

        #[derive(Debug)]
        pub(crate) struct AtomicU64 {
            inner: Mutex<u64>,
        }

        impl AtomicU64 {
            pub(crate) fn new(val: u64) -> Self {
                Self {
                    inner: Mutex::new(val),
                }
            }

            pub(crate) fn load(&self, _: Ordering) -> u64 {
                *self.inner.lock().unwrap()
            }

            pub(crate) fn store(&self, val: u64, _: Ordering) {
                *self.inner.lock().unwrap() = val;
            }

            pub(crate) fn fetch_or(&self, val: u64, _: Ordering) -> u64 {
                let mut lock = self.inner.lock().unwrap();
                let prev = *lock;
                *lock = prev | val;
                prev
            }

            pub(crate) fn compare_exchange(
                &self,
                current: u64,
                new: u64,
                _success: Ordering,
                _failure: Ordering,
            ) -> Result<u64, u64> {
                let mut lock = self.inner.lock().unwrap();

                if *lock == current {
                    *lock = new;
                    Ok(current)
                } else {
                    Err(*lock)
                }
            }

            pub(crate) fn compare_exchange_weak(
                &self,
                current: u64,
                new: u64,
                success: Ordering,
                failure: Ordering,
            ) -> Result<u64, u64> {
                self.compare_exchange(current, new, success, failure)
            }
        }
    }