Coverage Report

Created: 2021-01-22 16:54

crossbeam-utils/src/atomic/atomic_cell.rs
Line
Count
Source (jump to first uncovered line)
1
// Necessary for implementing atomic methods for `AtomicUnit`
2
#![allow(clippy::unit_arg)]
3
#![allow(clippy::let_unit_value)]
4
5
use crate::primitive::sync::atomic::{self, AtomicBool};
6
use core::cell::UnsafeCell;
7
use core::fmt;
8
use core::mem;
9
use core::sync::atomic::Ordering;
10
11
#[cfg(not(loom_crossbeam))]
12
use core::ptr;
13
14
#[cfg(feature = "std")]
15
use std::panic::{RefUnwindSafe, UnwindSafe};
16
17
#[cfg(not(loom_crossbeam))]
18
use super::seq_lock::SeqLock;
19
20
/// A thread-safe mutable memory location.
21
///
22
/// This type is equivalent to [`Cell`], except it can also be shared among multiple threads.
23
///
24
/// Operations on `AtomicCell`s use atomic instructions whenever possible, and synchronize using
25
/// global locks otherwise. You can call [`AtomicCell::<T>::is_lock_free()`] to check whether
26
/// atomic instructions or locks will be used.
27
///
28
/// Atomic loads use the [`Acquire`] ordering and atomic stores use the [`Release`] ordering.
29
///
30
/// [`Cell`]: std::cell::Cell
31
/// [`AtomicCell::<T>::is_lock_free()`]: AtomicCell::is_lock_free
32
/// [`Acquire`]: std::sync::atomic::Ordering::Acquire
33
/// [`Release`]: std::sync::atomic::Ordering::Release
34
#[repr(transparent)]
35
pub struct AtomicCell<T: ?Sized> {
36
    /// The inner value.
37
    ///
38
    /// If this value can be transmuted into a primitive atomic type, it will be treated as such.
39
    /// Otherwise, all potentially concurrent operations on this data will be protected by a global
40
    /// lock.
41
    value: UnsafeCell<T>,
42
}
43
44
unsafe impl<T: Send> Send for AtomicCell<T> {}
45
unsafe impl<T: Send> Sync for AtomicCell<T> {}
46
47
#[cfg(feature = "std")]
48
impl<T> UnwindSafe for AtomicCell<T> {}
49
#[cfg(feature = "std")]
50
impl<T> RefUnwindSafe for AtomicCell<T> {}
51
52
impl<T> AtomicCell<T> {
53
    /// Creates a new atomic cell initialized with `val`.
54
    ///
55
    /// # Examples
56
    ///
57
    /// ```
58
    /// use crossbeam_utils::atomic::AtomicCell;
59
    ///
60
    /// let a = AtomicCell::new(7);
61
    /// ```
62
30.2k
    pub const fn new(val: T) -> AtomicCell<T> {
63
30.2k
        AtomicCell {
64
30.2k
            value: UnsafeCell::new(val),
65
30.2k
        }
66
30.2k
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<std::time::Instant>>::new
Line
Count
Source
62
30.2k
    pub const fn new(val: T) -> AtomicCell<T> {
63
30.2k
        AtomicCell {
64
30.2k
            value: UnsafeCell::new(val),
65
30.2k
        }
66
30.2k
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::drops_unit::Foo>>::new
Line
Count
Source
62
1
    pub const fn new(val: T) -> AtomicCell<T> {
63
1
        AtomicCell {
64
1
            value: UnsafeCell::new(val),
65
1
        }
66
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::modular_usize::Foo>>::new
Line
Count
Source
62
1
    pub const fn new(val: T) -> AtomicCell<T> {
63
1
        AtomicCell {
64
1
            value: UnsafeCell::new(val),
65
1
        }
66
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::drops_u8::Foo>>::new
Line
Count
Source
62
1
    pub const fn new(val: T) -> AtomicCell<T> {
63
1
        AtomicCell {
64
1
            value: UnsafeCell::new(val),
65
1
        }
66
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::drops_usize::Foo>>::new
Line
Count
Source
62
1
    pub const fn new(val: T) -> AtomicCell<T> {
63
1
        AtomicCell {
64
1
            value: UnsafeCell::new(val),
65
1
        }
66
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::garbage_padding::Object>>::new
Line
Count
Source
62
1
    pub const fn new(val: T) -> AtomicCell<T> {
63
1
        AtomicCell {
64
1
            value: UnsafeCell::new(val),
65
1
        }
66
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::modular_u8::Foo>>::new
Line
Count
Source
62
1
    pub const fn new(val: T) -> AtomicCell<T> {
63
1
        AtomicCell {
64
1
            value: UnsafeCell::new(val),
65
1
        }
66
1
    }
67
68
    /// Consumes the atomic and returns the contained value.
69
    ///
70
    /// # Examples
71
    ///
72
    /// ```
73
    /// use crossbeam_utils::atomic::AtomicCell;
74
    ///
75
    /// let a = AtomicCell::new(7);
76
    /// let v = a.into_inner();
77
    ///
78
    /// assert_eq!(v, 7);
79
    /// ```
80
    pub fn into_inner(self) -> T {
81
        self.value.into_inner()
82
    }
83
84
    /// Returns `true` if operations on values of this type are lock-free.
85
    ///
86
    /// If the compiler or the platform doesn't support the necessary atomic instructions,
87
    /// `AtomicCell<T>` will use global locks for every potentially concurrent atomic operation.
88
    ///
89
    /// # Examples
90
    ///
91
    /// ```
92
    /// use crossbeam_utils::atomic::AtomicCell;
93
    ///
94
    /// // This type is internally represented as `AtomicUsize` so we can just use atomic
95
    /// // operations provided by it.
96
    /// assert_eq!(AtomicCell::<usize>::is_lock_free(), true);
97
    ///
98
    /// // A wrapper struct around `isize`.
99
    /// struct Foo {
100
    ///     bar: isize,
101
    /// }
102
    /// // `AtomicCell<Foo>` will be internally represented as `AtomicIsize`.
103
    /// assert_eq!(AtomicCell::<Foo>::is_lock_free(), true);
104
    ///
105
    /// // Operations on zero-sized types are always lock-free.
106
    /// assert_eq!(AtomicCell::<()>::is_lock_free(), true);
107
    ///
108
    /// // Very large types cannot be represented as any of the standard atomic types, so atomic
109
    /// // operations on them will have to use global locks for synchronization.
110
    /// assert_eq!(AtomicCell::<[u8; 1000]>::is_lock_free(), false);
111
    /// ```
112
8
    pub const fn is_lock_free() -> bool {
113
8
        atomic_is_lock_free::<T>()
114
8
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<u128>>::is_lock_free
Line
Count
Source
112
1
    pub const fn is_lock_free() -> bool {
113
1
        atomic_is_lock_free::<T>()
114
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<bool>>::is_lock_free
Line
Count
Source
112
1
    pub const fn is_lock_free() -> bool {
113
1
        atomic_is_lock_free::<T>()
114
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<usize>>::is_lock_free
Line
Count
Source
112
1
    pub const fn is_lock_free() -> bool {
113
1
        atomic_is_lock_free::<T>()
114
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<u8>>::is_lock_free
Line
Count
Source
112
1
    pub const fn is_lock_free() -> bool {
113
1
        atomic_is_lock_free::<T>()
114
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::is_lock_free::U8Wrap>>::is_lock_free
Line
Count
Source
112
1
    pub const fn is_lock_free() -> bool {
113
1
        atomic_is_lock_free::<T>()
114
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<isize>>::is_lock_free
Line
Count
Source
112
1
    pub const fn is_lock_free() -> bool {
113
1
        atomic_is_lock_free::<T>()
114
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::is_lock_free::UsizeWrap>>::is_lock_free
Line
Count
Source
112
1
    pub const fn is_lock_free() -> bool {
113
1
        atomic_is_lock_free::<T>()
114
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::is_lock_free::I16Wrap>>::is_lock_free
Line
Count
Source
112
1
    pub const fn is_lock_free() -> bool {
113
1
        atomic_is_lock_free::<T>()
114
1
    }
115
116
    /// Stores `val` into the atomic cell.
117
    ///
118
    /// # Examples
119
    ///
120
    /// ```
121
    /// use crossbeam_utils::atomic::AtomicCell;
122
    ///
123
    /// let a = AtomicCell::new(7);
124
    ///
125
    /// assert_eq!(a.load(), 7);
126
    /// a.store(8);
127
    /// assert_eq!(a.load(), 8);
128
    /// ```
129
6
    pub fn store(&self, val: T) {
130
6
        if mem::needs_drop::<T>() {
131
3
            drop(self.swap(val));
132
3
        } else {
133
3
            unsafe {
134
3
                atomic_store(self.value.get(), val);
135
3
            }
136
        }
137
6
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::drops_unit::Foo>>::store
Line
Count
Source
129
1
    pub fn store(&self, val: T) {
130
1
        if mem::needs_drop::<T>() {
131
1
            drop(self.swap(val));
132
1
        } else {
133
0
            unsafe {
134
0
                atomic_store(self.value.get(), val);
135
0
            }
136
        }
137
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<usize>>::store
Line
Count
Source
129
1
    pub fn store(&self, val: T) {
130
1
        if mem::needs_drop::<T>() {
131
0
            drop(self.swap(val));
132
0
        } else {
133
1
            unsafe {
134
1
                atomic_store(self.value.get(), val);
135
1
            }
136
        }
137
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::modular_u8::Foo>>::store
Line
Count
Source
129
1
    pub fn store(&self, val: T) {
130
1
        if mem::needs_drop::<T>() {
131
0
            drop(self.swap(val));
132
0
        } else {
133
1
            unsafe {
134
1
                atomic_store(self.value.get(), val);
135
1
            }
136
        }
137
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::drops_usize::Foo>>::store
Line
Count
Source
129
1
    pub fn store(&self, val: T) {
130
1
        if mem::needs_drop::<T>() {
131
1
            drop(self.swap(val));
132
1
        } else {
133
0
            unsafe {
134
0
                atomic_store(self.value.get(), val);
135
0
            }
136
        }
137
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::modular_usize::Foo>>::store
Line
Count
Source
129
1
    pub fn store(&self, val: T) {
130
1
        if mem::needs_drop::<T>() {
131
0
            drop(self.swap(val));
132
0
        } else {
133
1
            unsafe {
134
1
                atomic_store(self.value.get(), val);
135
1
            }
136
        }
137
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::drops_u8::Foo>>::store
Line
Count
Source
129
1
    pub fn store(&self, val: T) {
130
1
        if mem::needs_drop::<T>() {
131
1
            drop(self.swap(val));
132
1
        } else {
133
0
            unsafe {
134
0
                atomic_store(self.value.get(), val);
135
0
            }
136
        }
137
1
    }
138
139
    /// Stores `val` into the atomic cell and returns the previous value.
140
    ///
141
    /// # Examples
142
    ///
143
    /// ```
144
    /// use crossbeam_utils::atomic::AtomicCell;
145
    ///
146
    /// let a = AtomicCell::new(7);
147
    ///
148
    /// assert_eq!(a.load(), 7);
149
    /// assert_eq!(a.swap(8), 7);
150
    /// assert_eq!(a.load(), 8);
151
    /// ```
152
15
    pub fn swap(&self, val: T) -> T {
153
15
        unsafe { atomic_swap(self.value.get(), val) }
154
15
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::modular_usize::Foo>>::swap
Line
Count
Source
152
1
    pub fn swap(&self, val: T) -> T {
153
1
        unsafe { atomic_swap(self.value.get(), val) }
154
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::drops_u8::Foo>>::swap
Line
Count
Source
152
5
    pub fn swap(&self, val: T) -> T {
153
5
        unsafe { atomic_swap(self.value.get(), val) }
154
5
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::modular_u8::Foo>>::swap
Line
Count
Source
152
1
    pub fn swap(&self, val: T) -> T {
153
1
        unsafe { atomic_swap(self.value.get(), val) }
154
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::drops_usize::Foo>>::swap
Line
Count
Source
152
5
    pub fn swap(&self, val: T) -> T {
153
5
        unsafe { atomic_swap(self.value.get(), val) }
154
5
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::drops_unit::Foo>>::swap
Line
Count
Source
152
3
    pub fn swap(&self, val: T) -> T {
153
3
        unsafe { atomic_swap(self.value.get(), val) }
154
3
    }
155
}
156
157
impl<T: ?Sized> AtomicCell<T> {
158
    /// Returns a raw pointer to the underlying data in this atomic cell.
159
    ///
160
    /// # Examples
161
    ///
162
    /// ```
163
    /// use crossbeam_utils::atomic::AtomicCell;
164
    ///
165
    /// let a = AtomicCell::new(5);
166
    ///
167
    /// let ptr = a.as_ptr();
168
    /// ```
169
    #[inline]
170
    pub fn as_ptr(&self) -> *mut T {
171
        self.value.get()
172
    }
173
}
174
175
impl<T: Default> AtomicCell<T> {
176
    /// Takes the value of the atomic cell, leaving `Default::default()` in its place.
177
    ///
178
    /// # Examples
179
    ///
180
    /// ```
181
    /// use crossbeam_utils::atomic::AtomicCell;
182
    ///
183
    /// let a = AtomicCell::new(5);
184
    /// let five = a.take();
185
    ///
186
    /// assert_eq!(five, 5);
187
    /// assert_eq!(a.into_inner(), 0);
188
    /// ```
189
    pub fn take(&self) -> T {
190
        self.swap(Default::default())
191
    }
192
}
193
194
impl<T: Copy> AtomicCell<T> {
195
    /// Loads a value from the atomic cell.
196
    ///
197
    /// # Examples
198
    ///
199
    /// ```
200
    /// use crossbeam_utils::atomic::AtomicCell;
201
    ///
202
    /// let a = AtomicCell::new(7);
203
    ///
204
    /// assert_eq!(a.load(), 7);
205
    /// ```
206
31.6k
    pub fn load(&self) -> T {
207
31.6k
        unsafe { atomic_load(self.value.get()) }
208
31.6k
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<std::time::Instant>>::load
Line
Count
Source
206
2.58k
    pub fn load(&self) -> T {
207
2.58k
        unsafe { atomic_load(self.value.get()) }
208
2.58k
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<std::time::Instant>>::load
Line
Count
Source
206
10
    pub fn load(&self) -> T {
207
10
        unsafe { atomic_load(self.value.get()) }
208
10
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<std::time::Instant>>::load
Line
Count
Source
206
21.2k
    pub fn load(&self) -> T {
207
21.2k
        unsafe { atomic_load(self.value.get()) }
208
21.2k
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::modular_usize::Foo>>::load
Line
Count
Source
206
4
    pub fn load(&self) -> T {
207
4
        unsafe { atomic_load(self.value.get()) }
208
4
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<usize>>::load
Line
Count
Source
206
1
    pub fn load(&self) -> T {
207
1
        unsafe { atomic_load(self.value.get()) }
208
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::modular_u8::Foo>>::load
Line
Count
Source
206
4
    pub fn load(&self) -> T {
207
4
        unsafe { atomic_load(self.value.get()) }
208
4
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::garbage_padding::Object>>::load
Line
Count
Source
206
1
    pub fn load(&self) -> T {
207
1
        unsafe { atomic_load(self.value.get()) }
208
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<std::time::Instant>>::load
Line
Count
Source
206
14
    pub fn load(&self) -> T {
207
14
        unsafe { atomic_load(self.value.get()) }
208
14
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<std::time::Instant>>::load
Line
Count
Source
206
2.58k
    pub fn load(&self) -> T {
207
2.58k
        unsafe { atomic_load(self.value.get()) }
208
2.58k
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<std::time::Instant>>::load
Line
Count
Source
206
5.16k
    pub fn load(&self) -> T {
207
5.16k
        unsafe { atomic_load(self.value.get()) }
208
5.16k
    }
209
}
210
211
impl<T: Copy + Eq> AtomicCell<T> {
212
    /// If the current value equals `current`, stores `new` into the atomic cell.
213
    ///
214
    /// The return value is always the previous value. If it is equal to `current`, then the value
215
    /// was updated.
216
    ///
217
    /// # Examples
218
    ///
219
    /// ```
220
    /// # #![allow(deprecated)]
221
    /// use crossbeam_utils::atomic::AtomicCell;
222
    ///
223
    /// let a = AtomicCell::new(1);
224
    ///
225
    /// assert_eq!(a.compare_and_swap(2, 3), 1);
226
    /// assert_eq!(a.load(), 1);
227
    ///
228
    /// assert_eq!(a.compare_and_swap(1, 2), 1);
229
    /// assert_eq!(a.load(), 2);
230
    /// ```
231
    // TODO: remove in the next major version.
232
    #[deprecated(note = "Use `compare_exchange` instead")]
233
    pub fn compare_and_swap(&self, current: T, new: T) -> T {
234
        match self.compare_exchange(current, new) {
235
            Ok(v) => v,
236
            Err(v) => v,
237
        }
238
    }
239
240
    /// If the current value equals `current`, stores `new` into the atomic cell.
241
    ///
242
    /// The return value is a result indicating whether the new value was written and containing
243
    /// the previous value. On success this value is guaranteed to be equal to `current`.
244
    ///
245
    /// # Examples
246
    ///
247
    /// ```
248
    /// use crossbeam_utils::atomic::AtomicCell;
249
    ///
250
    /// let a = AtomicCell::new(1);
251
    ///
252
    /// assert_eq!(a.compare_exchange(2, 3), Err(1));
253
    /// assert_eq!(a.load(), 1);
254
    ///
255
    /// assert_eq!(a.compare_exchange(1, 2), Ok(1));
256
    /// assert_eq!(a.load(), 2);
257
    /// ```
258
11.3k
    pub fn compare_exchange(&self, current: T, new: T) -> Result<T, T> {
259
11.3k
        unsafe { atomic_compare_exchange_weak(self.value.get(), current, new) }
260
11.3k
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<std::time::Instant>>::compare_exchange
Line
Count
Source
258
2.58k
    pub fn compare_exchange(&self, current: T, new: T) -> Result<T, T> {
259
2.58k
        unsafe { atomic_compare_exchange_weak(self.value.get(), current, new) }
260
2.58k
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<std::time::Instant>>::compare_exchange
Line
Count
Source
258
10
    pub fn compare_exchange(&self, current: T, new: T) -> Result<T, T> {
259
10
        unsafe { atomic_compare_exchange_weak(self.value.get(), current, new) }
260
10
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<std::time::Instant>>::compare_exchange
Line
Count
Source
258
3.61k
    pub fn compare_exchange(&self, current: T, new: T) -> Result<T, T> {
259
3.61k
        unsafe { atomic_compare_exchange_weak(self.value.get(), current, new) }
260
3.61k
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::modular_usize::Foo>>::compare_exchange
Line
Count
Source
258
2
    pub fn compare_exchange(&self, current: T, new: T) -> Result<T, T> {
259
2
        unsafe { atomic_compare_exchange_weak(self.value.get(), current, new) }
260
2
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::garbage_padding::Object>>::compare_exchange
Line
Count
Source
258
1
    pub fn compare_exchange(&self, current: T, new: T) -> Result<T, T> {
259
1
        unsafe { atomic_compare_exchange_weak(self.value.get(), current, new) }
260
1
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<atomic_cell::modular_u8::Foo>>::compare_exchange
Line
Count
Source
258
2
    pub fn compare_exchange(&self, current: T, new: T) -> Result<T, T> {
259
2
        unsafe { atomic_compare_exchange_weak(self.value.get(), current, new) }
260
2
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<std::time::Instant>>::compare_exchange
Line
Count
Source
258
14
    pub fn compare_exchange(&self, current: T, new: T) -> Result<T, T> {
259
14
        unsafe { atomic_compare_exchange_weak(self.value.get(), current, new) }
260
14
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<std::time::Instant>>::compare_exchange
Line
Count
Source
258
2.58k
    pub fn compare_exchange(&self, current: T, new: T) -> Result<T, T> {
259
2.58k
        unsafe { atomic_compare_exchange_weak(self.value.get(), current, new) }
260
2.58k
    }
<crossbeam_utils::atomic::atomic_cell::AtomicCell<std::time::Instant>>::compare_exchange
Line
Count
Source
258
2.58k
    pub fn compare_exchange(&self, current: T, new: T) -> Result<T, T> {
259
2.58k
        unsafe { atomic_compare_exchange_weak(self.value.get(), current, new) }
260
2.58k
    }
261
}
262
263
macro_rules! impl_arithmetic {
264
    ($t:ty, $example:tt) => {
265
        impl AtomicCell<$t> {
266
            /// Increments the current value by `val` and returns the previous value.
267
            ///
268
            /// The addition wraps on overflow.
269
            ///
270
            /// # Examples
271
            ///
272
            /// ```
273
            /// use crossbeam_utils::atomic::AtomicCell;
274
            ///
275
            #[doc = $example]
276
            ///
277
            /// assert_eq!(a.fetch_add(3), 7);
278
            /// assert_eq!(a.load(), 10);
279
            /// ```
280
            #[inline]
281
            pub fn fetch_add(&self, val: $t) -> $t {
282
                if can_transmute::<$t, atomic::AtomicUsize>() {
283
                    let a = unsafe { &*(self.value.get() as *const atomic::AtomicUsize) };
284
                    a.fetch_add(val as usize, Ordering::AcqRel) as $t
285
                } else {
286
                    let _guard = lock(self.value.get() as usize).write();
287
                    let value = unsafe { &mut *(self.value.get()) };
288
                    let old = *value;
289
                    *value = value.wrapping_add(val);
290
                    old
291
                }
292
            }
293
294
            /// Decrements the current value by `val` and returns the previous value.
295
            ///
296
            /// The subtraction wraps on overflow.
297
            ///
298
            /// # Examples
299
            ///
300
            /// ```
301
            /// use crossbeam_utils::atomic::AtomicCell;
302
            ///
303
            #[doc = $example]
304
            ///
305
            /// assert_eq!(a.fetch_sub(3), 7);
306
            /// assert_eq!(a.load(), 4);
307
            /// ```
308
            #[inline]
309
            pub fn fetch_sub(&self, val: $t) -> $t {
310
                if can_transmute::<$t, atomic::AtomicUsize>() {
311
                    let a = unsafe { &*(self.value.get() as *const atomic::AtomicUsize) };
312
                    a.fetch_sub(val as usize, Ordering::AcqRel) as $t
313
                } else {
314
                    let _guard = lock(self.value.get() as usize).write();
315
                    let value = unsafe { &mut *(self.value.get()) };
316
                    let old = *value;
317
                    *value = value.wrapping_sub(val);
318
                    old
319
                }
320
            }
321
322
            /// Applies bitwise "and" to the current value and returns the previous value.
323
            ///
324
            /// # Examples
325
            ///
326
            /// ```
327
            /// use crossbeam_utils::atomic::AtomicCell;
328
            ///
329
            #[doc = $example]
330
            ///
331
            /// assert_eq!(a.fetch_and(3), 7);
332
            /// assert_eq!(a.load(), 3);
333
            /// ```
334
            #[inline]
335
            pub fn fetch_and(&self, val: $t) -> $t {
336
                if can_transmute::<$t, atomic::AtomicUsize>() {
337
                    let a = unsafe { &*(self.value.get() as *const atomic::AtomicUsize) };
338
                    a.fetch_and(val as usize, Ordering::AcqRel) as $t
339
                } else {
340
                    let _guard = lock(self.value.get() as usize).write();
341
                    let value = unsafe { &mut *(self.value.get()) };
342
                    let old = *value;
343
                    *value &= val;
344
                    old
345
                }
346
            }
347
348
            /// Applies bitwise "or" to the current value and returns the previous value.
349
            ///
350
            /// # Examples
351
            ///
352
            /// ```
353
            /// use crossbeam_utils::atomic::AtomicCell;
354
            ///
355
            #[doc = $example]
356
            ///
357
            /// assert_eq!(a.fetch_or(16), 7);
358
            /// assert_eq!(a.load(), 23);
359
            /// ```
360
            #[inline]
361
            pub fn fetch_or(&self, val: $t) -> $t {
362
                if can_transmute::<$t, atomic::AtomicUsize>() {
363
                    let a = unsafe { &*(self.value.get() as *const atomic::AtomicUsize) };
364
                    a.fetch_or(val as usize, Ordering::AcqRel) as $t
365
                } else {
366
                    let _guard = lock(self.value.get() as usize).write();
367
                    let value = unsafe { &mut *(self.value.get()) };
368
                    let old = *value;
369
                    *value |= val;
370
                    old
371
                }
372
            }
373
374
            /// Applies bitwise "xor" to the current value and returns the previous value.
375
            ///
376
            /// # Examples
377
            ///
378
            /// ```
379
            /// use crossbeam_utils::atomic::AtomicCell;
380
            ///
381
            #[doc = $example]
382
            ///
383
            /// assert_eq!(a.fetch_xor(2), 7);
384
            /// assert_eq!(a.load(), 5);
385
            /// ```
386
            #[inline]
387
            pub fn fetch_xor(&self, val: $t) -> $t {
388
                if can_transmute::<$t, atomic::AtomicUsize>() {
389
                    let a = unsafe { &*(self.value.get() as *const atomic::AtomicUsize) };
390
                    a.fetch_xor(val as usize, Ordering::AcqRel) as $t
391
                } else {
392
                    let _guard = lock(self.value.get() as usize).write();
393
                    let value = unsafe { &mut *(self.value.get()) };
394
                    let old = *value;
395
                    *value ^= val;
396
                    old
397
                }
398
            }
399
        }
400
    };
401
    ($t:ty, $atomic:ty, $example:tt) => {
402
        impl AtomicCell<$t> {
403
            /// Increments the current value by `val` and returns the previous value.
404
            ///
405
            /// The addition wraps on overflow.
406
            ///
407
            /// # Examples
408
            ///
409
            /// ```
410
            /// use crossbeam_utils::atomic::AtomicCell;
411
            ///
412
            #[doc = $example]
413
            ///
414
            /// assert_eq!(a.fetch_add(3), 7);
415
            /// assert_eq!(a.load(), 10);
416
            /// ```
417
            #[inline]
418
            pub fn fetch_add(&self, val: $t) -> $t {
419
                let a = unsafe { &*(self.value.get() as *const $atomic) };
420
                a.fetch_add(val, Ordering::AcqRel)
421
            }
422
423
            /// Decrements the current value by `val` and returns the previous value.
424
            ///
425
            /// The subtraction wraps on overflow.
426
            ///
427
            /// # Examples
428
            ///
429
            /// ```
430
            /// use crossbeam_utils::atomic::AtomicCell;
431
            ///
432
            #[doc = $example]
433
            ///
434
            /// assert_eq!(a.fetch_sub(3), 7);
435
            /// assert_eq!(a.load(), 4);
436
            /// ```
437
            #[inline]
438
            pub fn fetch_sub(&self, val: $t) -> $t {
439
                let a = unsafe { &*(self.value.get() as *const $atomic) };
440
                a.fetch_sub(val, Ordering::AcqRel)
441
            }
442
443
            /// Applies bitwise "and" to the current value and returns the previous value.
444
            ///
445
            /// # Examples
446
            ///
447
            /// ```
448
            /// use crossbeam_utils::atomic::AtomicCell;
449
            ///
450
            #[doc = $example]
451
            ///
452
            /// assert_eq!(a.fetch_and(3), 7);
453
            /// assert_eq!(a.load(), 3);
454
            /// ```
455
            #[inline]
456
            pub fn fetch_and(&self, val: $t) -> $t {
457
                let a = unsafe { &*(self.value.get() as *const $atomic) };
458
                a.fetch_and(val, Ordering::AcqRel)
459
            }
460
461
            /// Applies bitwise "or" to the current value and returns the previous value.
462
            ///
463
            /// # Examples
464
            ///
465
            /// ```
466
            /// use crossbeam_utils::atomic::AtomicCell;
467
            ///
468
            #[doc = $example]
469
            ///
470
            /// assert_eq!(a.fetch_or(16), 7);
471
            /// assert_eq!(a.load(), 23);
472
            /// ```
473
            #[inline]
474
            pub fn fetch_or(&self, val: $t) -> $t {
475
                let a = unsafe { &*(self.value.get() as *const $atomic) };
476
                a.fetch_or(val, Ordering::AcqRel)
477
            }
478
479
            /// Applies bitwise "xor" to the current value and returns the previous value.
480
            ///
481
            /// # Examples
482
            ///
483
            /// ```
484
            /// use crossbeam_utils::atomic::AtomicCell;
485
            ///
486
            #[doc = $example]
487
            ///
488
            /// assert_eq!(a.fetch_xor(2), 7);
489
            /// assert_eq!(a.load(), 5);
490
            /// ```
491
            #[inline]
492
            pub fn fetch_xor(&self, val: $t) -> $t {
493
                let a = unsafe { &*(self.value.get() as *const $atomic) };
494
                a.fetch_xor(val, Ordering::AcqRel)
495
            }
496
        }
497
    };
498
}
499
500
#[cfg(has_atomic_u8)]
501
impl_arithmetic!(u8, atomic::AtomicU8, "let a = AtomicCell::new(7u8);");
502
#[cfg(all(has_atomic_u8, not(loom_crossbeam)))]
503
impl_arithmetic!(i8, atomic::AtomicI8, "let a = AtomicCell::new(7i8);");
504
#[cfg(has_atomic_u16)]
505
impl_arithmetic!(u16, atomic::AtomicU16, "let a = AtomicCell::new(7u16);");
506
#[cfg(all(has_atomic_u16, not(loom_crossbeam)))]
507
impl_arithmetic!(i16, atomic::AtomicI16, "let a = AtomicCell::new(7i16);");
508
#[cfg(has_atomic_u32)]
509
impl_arithmetic!(u32, atomic::AtomicU32, "let a = AtomicCell::new(7u32);");
510
#[cfg(all(has_atomic_u32, not(loom_crossbeam)))]
511
impl_arithmetic!(i32, atomic::AtomicI32, "let a = AtomicCell::new(7i32);");
512
#[cfg(has_atomic_u64)]
513
impl_arithmetic!(u64, atomic::AtomicU64, "let a = AtomicCell::new(7u64);");
514
#[cfg(all(has_atomic_u64, not(loom_crossbeam)))]
515
impl_arithmetic!(i64, atomic::AtomicI64, "let a = AtomicCell::new(7i64);");
516
#[cfg(all(has_atomic_u128, not(loom_crossbeam)))]
517
impl_arithmetic!(u128, atomic::AtomicU128, "let a = AtomicCell::new(7u128);");
518
#[cfg(all(has_atomic_u128, not(loom_crossbeam)))]
519
impl_arithmetic!(i128, atomic::AtomicI128, "let  a = AtomicCell::new(7i128);");
520
521
impl_arithmetic!(
522
    usize,
523
    atomic::AtomicUsize,
524
    "let a = AtomicCell::new(7usize);"
525
);
526
#[cfg(not(loom_crossbeam))]
527
impl_arithmetic!(
528
    isize,
529
    atomic::AtomicIsize,
530
    "let a = AtomicCell::new(7isize);"
531
);
532
533
impl AtomicCell<bool> {
534
    /// Applies logical "and" to the current value and returns the previous value.
535
    ///
536
    /// # Examples
537
    ///
538
    /// ```
539
    /// use crossbeam_utils::atomic::AtomicCell;
540
    ///
541
    /// let a = AtomicCell::new(true);
542
    ///
543
    /// assert_eq!(a.fetch_and(true), true);
544
    /// assert_eq!(a.load(), true);
545
    ///
546
    /// assert_eq!(a.fetch_and(false), true);
547
    /// assert_eq!(a.load(), false);
548
    /// ```
549
    #[inline]
550
    pub fn fetch_and(&self, val: bool) -> bool {
551
        let a = unsafe { &*(self.value.get() as *const AtomicBool) };
552
        a.fetch_and(val, Ordering::AcqRel)
553
    }
554
555
    /// Applies logical "or" to the current value and returns the previous value.
556
    ///
557
    /// # Examples
558
    ///
559
    /// ```
560
    /// use crossbeam_utils::atomic::AtomicCell;
561
    ///
562
    /// let a = AtomicCell::new(false);
563
    ///
564
    /// assert_eq!(a.fetch_or(false), false);
565
    /// assert_eq!(a.load(), false);
566
    ///
567
    /// assert_eq!(a.fetch_or(true), false);
568
    /// assert_eq!(a.load(), true);
569
    /// ```
570
    #[inline]
571
    pub fn fetch_or(&self, val: bool) -> bool {
572
        let a = unsafe { &*(self.value.get() as *const AtomicBool) };
573
        a.fetch_or(val, Ordering::AcqRel)
574
    }
575
576
    /// Applies logical "xor" to the current value and returns the previous value.
577
    ///
578
    /// # Examples
579
    ///
580
    /// ```
581
    /// use crossbeam_utils::atomic::AtomicCell;
582
    ///
583
    /// let a = AtomicCell::new(true);
584
    ///
585
    /// assert_eq!(a.fetch_xor(false), true);
586
    /// assert_eq!(a.load(), true);
587
    ///
588
    /// assert_eq!(a.fetch_xor(true), true);
589
    /// assert_eq!(a.load(), false);
590
    /// ```
591
    #[inline]
592
    pub fn fetch_xor(&self, val: bool) -> bool {
593
        let a = unsafe { &*(self.value.get() as *const AtomicBool) };
594
        a.fetch_xor(val, Ordering::AcqRel)
595
    }
596
}
597
598
impl<T: Default> Default for AtomicCell<T> {
599
    fn default() -> AtomicCell<T> {
600
        AtomicCell::new(T::default())
601
    }
602
}
603
604
impl<T> From<T> for AtomicCell<T> {
605
    #[inline]
606
    fn from(val: T) -> AtomicCell<T> {
607
        AtomicCell::new(val)
608
    }
609
}
610
611
impl<T: Copy + fmt::Debug> fmt::Debug for AtomicCell<T> {
612
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
613
        f.debug_struct("AtomicCell")
614
            .field("value", &self.load())
615
            .finish()
616
    }
617
}
618
619
/// Returns `true` if values of type `A` can be transmuted into values of type `B`.
620
85.8k
const fn can_transmute<A, B>() -> bool {
621
85.8k
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
85.8k
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
85.8k
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<std::time::Instant, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
5.16k
const fn can_transmute<A, B>() -> bool {
621
5.16k
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
5.16k
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
5.16k
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<std::time::Instant, core::sync::atomic::AtomicUsize>
Line
Count
Source
620
5.16k
const fn can_transmute<A, B>() -> bool {
621
5.16k
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
5.16k
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
5.16k
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<std::time::Instant, core::sync::atomic::AtomicUsize>
Line
Count
Source
620
20
const fn can_transmute<A, B>() -> bool {
621
20
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
20
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
20
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<std::time::Instant, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
20
const fn can_transmute<A, B>() -> bool {
621
20
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
20
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
20
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<std::time::Instant, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
24.7k
const fn can_transmute<A, B>() -> bool {
621
24.7k
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
24.7k
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
24.7k
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<std::time::Instant, core::sync::atomic::AtomicUsize>
Line
Count
Source
620
24.7k
const fn can_transmute<A, B>() -> bool {
621
24.7k
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
24.7k
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
24.7k
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::is_lock_free::UsizeWrap, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<bool, core::sync::atomic::AtomicU32>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::drops_unit::Foo, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
3
const fn can_transmute<A, B>() -> bool {
621
3
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
3
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
3
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::garbage_padding::Object, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
2
const fn can_transmute<A, B>() -> bool {
621
2
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
2
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
2
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<u128, core::sync::atomic::AtomicU16>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::is_lock_free::UsizeWrap, core::sync::atomic::AtomicU8>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::is_lock_free::U8Wrap, core::sync::atomic::AtomicUsize>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<u128, core::sync::atomic::AtomicU64>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::is_lock_free::I16Wrap, core::sync::atomic::AtomicU32>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<bool, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::drops_u8::Foo, core::sync::atomic::AtomicUsize>
Line
Count
Source
620
5
const fn can_transmute<A, B>() -> bool {
621
5
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
5
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
5
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<bool, core::sync::atomic::AtomicU8>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::drops_u8::Foo, core::sync::atomic::AtomicU8>
Line
Count
Source
620
5
const fn can_transmute<A, B>() -> bool {
621
5
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
5
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
5
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<u128, core::sync::atomic::AtomicU8>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<u8, core::sync::atomic::AtomicU16>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<isize, core::sync::atomic::AtomicU8>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::is_lock_free::U8Wrap, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::garbage_padding::Object, core::sync::atomic::AtomicUsize>
Line
Count
Source
620
2
const fn can_transmute<A, B>() -> bool {
621
2
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
2
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
2
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<u128, core::sync::atomic::AtomicU32>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::drops_u8::Foo, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
5
const fn can_transmute<A, B>() -> bool {
621
5
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
5
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
5
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<u8, core::sync::atomic::AtomicU64>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<isize, core::sync::atomic::AtomicU32>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::is_lock_free::UsizeWrap, core::sync::atomic::AtomicU32>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<usize, core::sync::atomic::AtomicU8>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::is_lock_free::I16Wrap, core::sync::atomic::AtomicU64>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::garbage_padding::Object, core::sync::atomic::AtomicU32>
Line
Count
Source
620
2
const fn can_transmute<A, B>() -> bool {
621
2
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
2
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
2
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<bool, core::sync::atomic::AtomicUsize>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::modular_usize::Foo, core::sync::atomic::AtomicUsize>
Line
Count
Source
620
8
const fn can_transmute<A, B>() -> bool {
621
8
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
8
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
8
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<u128, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::modular_u8::Foo, core::sync::atomic::AtomicU8>
Line
Count
Source
620
8
const fn can_transmute<A, B>() -> bool {
621
8
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
8
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
8
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<bool, core::sync::atomic::AtomicU16>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<u8, core::sync::atomic::AtomicU8>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<isize, core::sync::atomic::AtomicUsize>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::modular_u8::Foo, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
8
const fn can_transmute<A, B>() -> bool {
621
8
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
8
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
8
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::is_lock_free::I16Wrap, core::sync::atomic::AtomicUsize>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<isize, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<usize, core::sync::atomic::AtomicU32>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<u8, core::sync::atomic::AtomicU32>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<isize, core::sync::atomic::AtomicU16>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<usize, core::sync::atomic::AtomicU16>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::is_lock_free::I16Wrap, core::sync::atomic::AtomicU16>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::garbage_padding::Object, core::sync::atomic::AtomicU8>
Line
Count
Source
620
2
const fn can_transmute<A, B>() -> bool {
621
2
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
2
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
2
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::is_lock_free::U8Wrap, core::sync::atomic::AtomicU8>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::garbage_padding::Object, core::sync::atomic::AtomicU16>
Line
Count
Source
620
2
const fn can_transmute<A, B>() -> bool {
621
2
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
2
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
2
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::is_lock_free::UsizeWrap, core::sync::atomic::AtomicU64>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::modular_usize::Foo, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
8
const fn can_transmute<A, B>() -> bool {
621
8
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
8
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
8
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::modular_u8::Foo, core::sync::atomic::AtomicUsize>
Line
Count
Source
620
8
const fn can_transmute<A, B>() -> bool {
621
8
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
8
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
8
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::is_lock_free::U8Wrap, core::sync::atomic::AtomicU32>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::garbage_padding::Object, core::sync::atomic::AtomicU64>
Line
Count
Source
620
2
const fn can_transmute<A, B>() -> bool {
621
2
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
2
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
2
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<u8, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<u128, core::sync::atomic::AtomicUsize>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::drops_usize::Foo, core::sync::atomic::AtomicUsize>
Line
Count
Source
620
5
const fn can_transmute<A, B>() -> bool {
621
5
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
5
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
5
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::is_lock_free::I16Wrap, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::is_lock_free::UsizeWrap, core::sync::atomic::AtomicUsize>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<bool, core::sync::atomic::AtomicU64>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::is_lock_free::I16Wrap, core::sync::atomic::AtomicU8>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::is_lock_free::UsizeWrap, core::sync::atomic::AtomicU16>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<isize, core::sync::atomic::AtomicU64>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::is_lock_free::U8Wrap, core::sync::atomic::AtomicU16>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<usize, core::sync::atomic::AtomicUsize>
Line
Count
Source
620
3
const fn can_transmute<A, B>() -> bool {
621
3
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
3
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
3
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::drops_usize::Foo, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
5
const fn can_transmute<A, B>() -> bool {
621
5
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
5
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
5
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<atomic_cell::is_lock_free::U8Wrap, core::sync::atomic::AtomicU64>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<u8, core::sync::atomic::AtomicUsize>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<usize, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
3
const fn can_transmute<A, B>() -> bool {
621
3
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
3
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
3
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<usize, core::sync::atomic::AtomicU64>
Line
Count
Source
620
1
const fn can_transmute<A, B>() -> bool {
621
1
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
1
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
1
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<std::time::Instant, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
28
const fn can_transmute<A, B>() -> bool {
621
28
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
28
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
28
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<std::time::Instant, core::sync::atomic::AtomicUsize>
Line
Count
Source
620
28
const fn can_transmute<A, B>() -> bool {
621
28
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
28
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
28
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<std::time::Instant, core::sync::atomic::AtomicUsize>
Line
Count
Source
620
5.16k
const fn can_transmute<A, B>() -> bool {
621
5.16k
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
5.16k
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
5.16k
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<std::time::Instant, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
5.16k
const fn can_transmute<A, B>() -> bool {
621
5.16k
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
5.16k
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
5.16k
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<std::time::Instant, crossbeam_utils::atomic::atomic_cell::AtomicUnit>
Line
Count
Source
620
7.74k
const fn can_transmute<A, B>() -> bool {
621
7.74k
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
7.74k
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
7.74k
}
crossbeam_utils::atomic::atomic_cell::can_transmute::<std::time::Instant, core::sync::atomic::AtomicUsize>
Line
Count
Source
620
7.74k
const fn can_transmute<A, B>() -> bool {
621
7.74k
    // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`.
622
7.74k
    (mem::size_of::<A>() == mem::size_of::<B>()) & (mem::align_of::<A>() >= mem::align_of::<B>())
623
7.74k
}
624
625
/// Returns a reference to the global lock associated with the `AtomicCell` at address `addr`.
626
///
627
/// This function is used to protect atomic data which doesn't fit into any of the primitive atomic
628
/// types in `std::sync::atomic`. Operations on such atomics must therefore use a global lock.
629
///
630
/// However, there is not only one global lock but an array of many locks, and one of them is
631
/// picked based on the given address. Having many locks reduces contention and improves
632
/// scalability.
633
#[inline]
634
#[must_use]
635
#[cfg(not(loom_crossbeam))]
636
2
fn lock(addr: usize) -> &'static SeqLock {
637
2
    // The number of locks is a prime number because we want to make sure `addr % LEN` gets
638
2
    // dispersed across all locks.
639
2
    //
640
2
    // Note that addresses are always aligned to some power of 2, depending on type `T` in
641
2
    // `AtomicCell<T>`. If `LEN` was an even number, then `addr % LEN` would be an even number,
642
2
    // too, which means only half of the locks would get utilized!
643
2
    //
644
2
    // It is also possible for addresses to accidentally get aligned to a number that is not a
645
2
    // power of 2. Consider this example:
646
2
    //
647
2
    // ```
648
2
    // #[repr(C)]
649
2
    // struct Foo {
650
2
    //     a: AtomicCell<u8>,
651
2
    //     b: u8,
652
2
    //     c: u8,
653
2
    // }
654
2
    // ```
655
2
    //
656
2
    // Now, if we have a slice of type `&[Foo]`, it is possible that field `a` in all items gets
657
2
    // stored at addresses that are multiples of 3. It'd be too bad if `LEN` was divisible by 3.
658
2
    // In order to protect from such cases, we simply choose a large prime number for `LEN`.
659
2
    const LEN: usize = 97;
660
2
661
2
    static LOCKS: [SeqLock; LEN] = [
662
2
        SeqLock::new(),
663
2
        SeqLock::new(),
664
2
        SeqLock::new(),
665
2
        SeqLock::new(),
666
2
        SeqLock::new(),
667
2
        SeqLock::new(),
668
2
        SeqLock::new(),
669
2
        SeqLock::new(),
670
2
        SeqLock::new(),
671
2
        SeqLock::new(),
672
2
        SeqLock::new(),
673
2
        SeqLock::new(),
674
2
        SeqLock::new(),
675
2
        SeqLock::new(),
676
2
        SeqLock::new(),
677
2
        SeqLock::new(),
678
2
        SeqLock::new(),
679
2
        SeqLock::new(),
680
2
        SeqLock::new(),
681
2
        SeqLock::new(),
682
2
        SeqLock::new(),
683
2
        SeqLock::new(),
684
2
        SeqLock::new(),
685
2
        SeqLock::new(),
686
2
        SeqLock::new(),
687
2
        SeqLock::new(),
688
2
        SeqLock::new(),
689
2
        SeqLock::new(),
690
2
        SeqLock::new(),
691
2
        SeqLock::new(),
692
2
        SeqLock::new(),
693
2
        SeqLock::new(),
694
2
        SeqLock::new(),
695
2
        SeqLock::new(),
696
2
        SeqLock::new(),
697
2
        SeqLock::new(),
698
2
        SeqLock::new(),
699
2
        SeqLock::new(),
700
2
        SeqLock::new(),
701
2
        SeqLock::new(),
702
2
        SeqLock::new(),
703
2
        SeqLock::new(),
704
2
        SeqLock::new(),
705
2
        SeqLock::new(),
706
2
        SeqLock::new(),
707
2
        SeqLock::new(),
708
2
        SeqLock::new(),
709
2
        SeqLock::new(),
710
2
        SeqLock::new(),
711
2
        SeqLock::new(),
712
2
        SeqLock::new(),
713
2
        SeqLock::new(),
714
2
        SeqLock::new(),
715
2
        SeqLock::new(),
716
2
        SeqLock::new(),
717
2
        SeqLock::new(),
718
2
        SeqLock::new(),
719
2
        SeqLock::new(),
720
2
        SeqLock::new(),
721
2
        SeqLock::new(),
722
2
        SeqLock::new(),
723
2
        SeqLock::new(),
724
2
        SeqLock::new(),
725
2
        SeqLock::new(),
726
2
        SeqLock::new(),
727
2
        SeqLock::new(),
728
2
        SeqLock::new(),
729
2
        SeqLock::new(),
730
2
        SeqLock::new(),
731
2
        SeqLock::new(),
732
2
        SeqLock::new(),
733
2
        SeqLock::new(),
734
2
        SeqLock::new(),
735
2
        SeqLock::new(),
736
2
        SeqLock::new(),
737
2
        SeqLock::new(),
738
2
        SeqLock::new(),
739
2
        SeqLock::new(),
740
2
        SeqLock::new(),
741
2
        SeqLock::new(),
742
2
        SeqLock::new(),
743
2
        SeqLock::new(),
744
2
        SeqLock::new(),
745
2
        SeqLock::new(),
746
2
        SeqLock::new(),
747
2
        SeqLock::new(),
748
2
        SeqLock::new(),
749
2
        SeqLock::new(),
750
2
        SeqLock::new(),
751
2
        SeqLock::new(),
752
2
        SeqLock::new(),
753
2
        SeqLock::new(),
754
2
        SeqLock::new(),
755
2
        SeqLock::new(),
756
2
        SeqLock::new(),
757
2
        SeqLock::new(),
758
2
        SeqLock::new(),
759
2
    ];
760
2
761
2
    // If the modulus is a constant number, the compiler will use crazy math to transform this into
762
2
    // a sequence of cheap arithmetic operations rather than using the slow modulo instruction.
763
2
    &LOCKS[addr % LEN]
764
2
}
765
766
/// An atomic `()`.
767
///
768
/// All operations are noops.
769
struct AtomicUnit;
770
771
impl AtomicUnit {
772
    #[inline]
773
    fn load(&self, _order: Ordering) {}
774
775
    #[inline]
776
    fn store(&self, _val: (), _order: Ordering) {}
777
778
    #[inline]
779
3
    fn swap(&self, _val: (), _order: Ordering) {}
780
781
    #[inline]
782
    fn compare_exchange_weak(
783
        &self,
784
        _current: (),
785
        _new: (),
786
        _success: Ordering,
787
        _failure: Ordering,
788
    ) -> Result<(), ()> {
789
        Ok(())
790
    }
791
}
792
793
macro_rules! atomic {
794
    // If values of type `$t` can be transmuted into values of the primitive atomic type `$atomic`,
795
    // declares variable `$a` of type `$atomic` and executes `$atomic_op`, breaking out of the loop.
796
    (@check, $t:ty, $atomic:ty, $a:ident, $atomic_op:expr) => {
797
        if can_transmute::<$t, $atomic>() {
798
            let $a: &$atomic;
799
            break $atomic_op;
800
        }
801
    };
802
803
    // If values of type `$t` can be transmuted into values of a primitive atomic type, declares
804
    // variable `$a` of that type and executes `$atomic_op`. Otherwise, just executes
805
    // `$fallback_op`.
806
    ($t:ty, $a:ident, $atomic_op:expr, $fallback_op:expr) => {
807
        loop {
808
            atomic!(@check, $t, AtomicUnit, $a, $atomic_op);
809
            atomic!(@check, $t, atomic::AtomicUsize, $a, $atomic_op);
810
811
            #[cfg(has_atomic_u8)]
812
            atomic!(@check, $t, atomic::AtomicU8, $a, $atomic_op);
813
            #[cfg(has_atomic_u16)]
814
            atomic!(@check, $t, atomic::AtomicU16, $a, $atomic_op);
815
            #[cfg(has_atomic_u32)]
816
            atomic!(@check, $t, atomic::AtomicU32, $a, $atomic_op);
817
            #[cfg(has_atomic_u64)]
818
            atomic!(@check, $t, atomic::AtomicU64, $a, $atomic_op);
819
            #[cfg(has_atomic_u128)]
820
            atomic!(@check, $t, atomic::AtomicU128, $a, $atomic_op);
821
822
            #[cfg(loom_crossbeam)]
823
            unimplemented!("loom does not support non-atomic atomic ops");
824
            #[cfg(not(loom_crossbeam))]
825
            break $fallback_op;
826
        }
827
    };
828
}
829
830
/// Returns `true` if operations on `AtomicCell<T>` are lock-free.
831
8
const fn atomic_is_lock_free<T>() -> bool {
832
8
    // HACK(taiki-e): This is equivalent to `atomic! { T, _a, true, false }`, but can be used in const fn even in Rust 1.36.
833
8
    let is_lock_free = can_transmute::<T, AtomicUnit>() | can_transmute::<T, atomic::AtomicUsize>();
834
8
    #[cfg(has_atomic_u8)]
835
8
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU8>();
836
8
    #[cfg(has_atomic_u16)]
837
8
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU16>();
838
8
    #[cfg(has_atomic_u32)]
839
8
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU32>();
840
8
    #[cfg(has_atomic_u64)]
841
8
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU64>();
842
8
    #[cfg(has_atomic_u128)]
843
8
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU128>();
844
8
    is_lock_free
845
8
}
crossbeam_utils::atomic::atomic_cell::atomic_is_lock_free::<u128>
Line
Count
Source
831
1
const fn atomic_is_lock_free<T>() -> bool {
832
1
    // HACK(taiki-e): This is equivalent to `atomic! { T, _a, true, false }`, but can be used in const fn even in Rust 1.36.
833
1
    let is_lock_free = can_transmute::<T, AtomicUnit>() | can_transmute::<T, atomic::AtomicUsize>();
834
1
    #[cfg(has_atomic_u8)]
835
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU8>();
836
1
    #[cfg(has_atomic_u16)]
837
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU16>();
838
1
    #[cfg(has_atomic_u32)]
839
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU32>();
840
1
    #[cfg(has_atomic_u64)]
841
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU64>();
842
1
    #[cfg(has_atomic_u128)]
843
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU128>();
844
1
    is_lock_free
845
1
}
crossbeam_utils::atomic::atomic_cell::atomic_is_lock_free::<atomic_cell::is_lock_free::I16Wrap>
Line
Count
Source
831
1
const fn atomic_is_lock_free<T>() -> bool {
832
1
    // HACK(taiki-e): This is equivalent to `atomic! { T, _a, true, false }`, but can be used in const fn even in Rust 1.36.
833
1
    let is_lock_free = can_transmute::<T, AtomicUnit>() | can_transmute::<T, atomic::AtomicUsize>();
834
1
    #[cfg(has_atomic_u8)]
835
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU8>();
836
1
    #[cfg(has_atomic_u16)]
837
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU16>();
838
1
    #[cfg(has_atomic_u32)]
839
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU32>();
840
1
    #[cfg(has_atomic_u64)]
841
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU64>();
842
1
    #[cfg(has_atomic_u128)]
843
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU128>();
844
1
    is_lock_free
845
1
}
crossbeam_utils::atomic::atomic_cell::atomic_is_lock_free::<atomic_cell::is_lock_free::UsizeWrap>
Line
Count
Source
831
1
const fn atomic_is_lock_free<T>() -> bool {
832
1
    // HACK(taiki-e): This is equivalent to `atomic! { T, _a, true, false }`, but can be used in const fn even in Rust 1.36.
833
1
    let is_lock_free = can_transmute::<T, AtomicUnit>() | can_transmute::<T, atomic::AtomicUsize>();
834
1
    #[cfg(has_atomic_u8)]
835
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU8>();
836
1
    #[cfg(has_atomic_u16)]
837
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU16>();
838
1
    #[cfg(has_atomic_u32)]
839
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU32>();
840
1
    #[cfg(has_atomic_u64)]
841
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU64>();
842
1
    #[cfg(has_atomic_u128)]
843
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU128>();
844
1
    is_lock_free
845
1
}
crossbeam_utils::atomic::atomic_cell::atomic_is_lock_free::<isize>
Line
Count
Source
831
1
const fn atomic_is_lock_free<T>() -> bool {
832
1
    // HACK(taiki-e): This is equivalent to `atomic! { T, _a, true, false }`, but can be used in const fn even in Rust 1.36.
833
1
    let is_lock_free = can_transmute::<T, AtomicUnit>() | can_transmute::<T, atomic::AtomicUsize>();
834
1
    #[cfg(has_atomic_u8)]
835
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU8>();
836
1
    #[cfg(has_atomic_u16)]
837
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU16>();
838
1
    #[cfg(has_atomic_u32)]
839
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU32>();
840
1
    #[cfg(has_atomic_u64)]
841
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU64>();
842
1
    #[cfg(has_atomic_u128)]
843
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU128>();
844
1
    is_lock_free
845
1
}
crossbeam_utils::atomic::atomic_cell::atomic_is_lock_free::<atomic_cell::is_lock_free::U8Wrap>
Line
Count
Source
831
1
const fn atomic_is_lock_free<T>() -> bool {
832
1
    // HACK(taiki-e): This is equivalent to `atomic! { T, _a, true, false }`, but can be used in const fn even in Rust 1.36.
833
1
    let is_lock_free = can_transmute::<T, AtomicUnit>() | can_transmute::<T, atomic::AtomicUsize>();
834
1
    #[cfg(has_atomic_u8)]
835
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU8>();
836
1
    #[cfg(has_atomic_u16)]
837
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU16>();
838
1
    #[cfg(has_atomic_u32)]
839
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU32>();
840
1
    #[cfg(has_atomic_u64)]
841
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU64>();
842
1
    #[cfg(has_atomic_u128)]
843
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU128>();
844
1
    is_lock_free
845
1
}
crossbeam_utils::atomic::atomic_cell::atomic_is_lock_free::<u8>
Line
Count
Source
831
1
const fn atomic_is_lock_free<T>() -> bool {
832
1
    // HACK(taiki-e): This is equivalent to `atomic! { T, _a, true, false }`, but can be used in const fn even in Rust 1.36.
833
1
    let is_lock_free = can_transmute::<T, AtomicUnit>() | can_transmute::<T, atomic::AtomicUsize>();
834
1
    #[cfg(has_atomic_u8)]
835
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU8>();
836
1
    #[cfg(has_atomic_u16)]
837
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU16>();
838
1
    #[cfg(has_atomic_u32)]
839
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU32>();
840
1
    #[cfg(has_atomic_u64)]
841
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU64>();
842
1
    #[cfg(has_atomic_u128)]
843
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU128>();
844
1
    is_lock_free
845
1
}
crossbeam_utils::atomic::atomic_cell::atomic_is_lock_free::<bool>
Line
Count
Source
831
1
const fn atomic_is_lock_free<T>() -> bool {
832
1
    // HACK(taiki-e): This is equivalent to `atomic! { T, _a, true, false }`, but can be used in const fn even in Rust 1.36.
833
1
    let is_lock_free = can_transmute::<T, AtomicUnit>() | can_transmute::<T, atomic::AtomicUsize>();
834
1
    #[cfg(has_atomic_u8)]
835
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU8>();
836
1
    #[cfg(has_atomic_u16)]
837
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU16>();
838
1
    #[cfg(has_atomic_u32)]
839
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU32>();
840
1
    #[cfg(has_atomic_u64)]
841
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU64>();
842
1
    #[cfg(has_atomic_u128)]
843
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU128>();
844
1
    is_lock_free
845
1
}
crossbeam_utils::atomic::atomic_cell::atomic_is_lock_free::<usize>
Line
Count
Source
831
1
const fn atomic_is_lock_free<T>() -> bool {
832
1
    // HACK(taiki-e): This is equivalent to `atomic! { T, _a, true, false }`, but can be used in const fn even in Rust 1.36.
833
1
    let is_lock_free = can_transmute::<T, AtomicUnit>() | can_transmute::<T, atomic::AtomicUsize>();
834
1
    #[cfg(has_atomic_u8)]
835
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU8>();
836
1
    #[cfg(has_atomic_u16)]
837
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU16>();
838
1
    #[cfg(has_atomic_u32)]
839
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU32>();
840
1
    #[cfg(has_atomic_u64)]
841
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU64>();
842
1
    #[cfg(has_atomic_u128)]
843
1
    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU128>();
844
1
    is_lock_free
845
1
}
846
847
/// Atomically reads data from `src`.
848
///
849
/// This operation uses the `Acquire` ordering. If possible, an atomic instructions is used, and a
850
/// global lock otherwise.
851
unsafe fn atomic_load<T>(src: *mut T) -> T
852
where
853
    T: Copy,
854
{
855
    atomic! {
856
        T, a,
857
        {
858
31.6k
            a = &*(src as *const _ as *const _);
859
31.6k
            mem::transmute_copy(&a.load(Ordering::Acquire))
860
        },
861
        {
862
1
            let lock = lock(src as usize);
863
864
            // Try doing an optimistic read first.
865
1
            if let Some(stamp) = lock.optimistic_read() {
866
                // We need a volatile read here because other threads might concurrently modify the
867
                // value. In theory, data races are *always* UB, even if we use volatile reads and
868
                // discard the data when a data race is detected. The proper solution would be to
869
                // do atomic reads and atomic writes, but we can't atomically read and write all
870
                // kinds of data since `AtomicU8` is not available on stable Rust yet.
871
1
                let val = ptr::read_volatile(src);
872
1
873
1
                if lock.validate_read(stamp) {
874
1
                    return val;
875
0
                }
876
0
            }
877
878
            // Grab a regular write lock so that writers don't starve this load.
879
0
            let guard = lock.write();
880
0
            let val = ptr::read(src);
881
0
            // The value hasn't been changed. Drop the guard without incrementing the stamp.
882
0
            guard.abort();
883
0
            val
884
        }
885
    }
886
31.6k
}
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_load::<std::time::Instant>
crossbeam_utils::atomic::atomic_cell::atomic_load::<std::time::Instant>
Line
Count
Source
858
2.58k
            a = &*(src as *const _ as *const _);
859
2.58k
            mem::transmute_copy(&a.load(Ordering::Acquire))
860
        },
861
        {
862
0
            let lock = lock(src as usize);
863
864
            // Try doing an optimistic read first.
865
0
            if let Some(stamp) = lock.optimistic_read() {
866
                // We need a volatile read here because other threads might concurrently modify the
867
                // value. In theory, data races are *always* UB, even if we use volatile reads and
868
                // discard the data when a data race is detected. The proper solution would be to
869
                // do atomic reads and atomic writes, but we can't atomically read and write all
870
                // kinds of data since `AtomicU8` is not available on stable Rust yet.
871
0
                let val = ptr::read_volatile(src);
872
0
873
0
                if lock.validate_read(stamp) {
874
0
                    return val;
875
0
                }
876
0
            }
877
878
            // Grab a regular write lock so that writers don't starve this load.
879
0
            let guard = lock.write();
880
0
            let val = ptr::read(src);
881
0
            // The value hasn't been changed. Drop the guard without incrementing the stamp.
882
0
            guard.abort();
883
0
            val
884
        }
885
    }
886
2.58k
}
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_load::<std::time::Instant>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_load::<std::time::Instant>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_load::<std::time::Instant>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_load::<std::time::Instant>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_load::<std::time::Instant>
crossbeam_utils::atomic::atomic_cell::atomic_load::<std::time::Instant>
Line
Count
Source
858
10
            a = &*(src as *const _ as *const _);
859
10
            mem::transmute_copy(&a.load(Ordering::Acquire))
860
        },
861
        {
862
0
            let lock = lock(src as usize);
863
864
            // Try doing an optimistic read first.
865
0
            if let Some(stamp) = lock.optimistic_read() {
866
                // We need a volatile read here because other threads might concurrently modify the
867
                // value. In theory, data races are *always* UB, even if we use volatile reads and
868
                // discard the data when a data race is detected. The proper solution would be to
869
                // do atomic reads and atomic writes, but we can't atomically read and write all
870
                // kinds of data since `AtomicU8` is not available on stable Rust yet.
871
0
                let val = ptr::read_volatile(src);
872
0
873
0
                if lock.validate_read(stamp) {
874
0
                    return val;
875
0
                }
876
0
            }
877
878
            // Grab a regular write lock so that writers don't starve this load.
879
0
            let guard = lock.write();
880
0
            let val = ptr::read(src);
881
0
            // The value hasn't been changed. Drop the guard without incrementing the stamp.
882
0
            guard.abort();
883
0
            val
884
        }
885
    }
886
10
}
crossbeam_utils::atomic::atomic_cell::atomic_load::<std::time::Instant>
Line
Count
Source
858
21.2k
            a = &*(src as *const _ as *const _);
859
21.2k
            mem::transmute_copy(&a.load(Ordering::Acquire))
860
        },
861
        {
862
0
            let lock = lock(src as usize);
863
864
            // Try doing an optimistic read first.
865
0
            if let Some(stamp) = lock.optimistic_read() {
866
                // We need a volatile read here because other threads might concurrently modify the
867
                // value. In theory, data races are *always* UB, even if we use volatile reads and
868
                // discard the data when a data race is detected. The proper solution would be to
869
                // do atomic reads and atomic writes, but we can't atomically read and write all
870
                // kinds of data since `AtomicU8` is not available on stable Rust yet.
871
0
                let val = ptr::read_volatile(src);
872
0
873
0
                if lock.validate_read(stamp) {
874
0
                    return val;
875
0
                }
876
0
            }
877
878
            // Grab a regular write lock so that writers don't starve this load.
879
0
            let guard = lock.write();
880
0
            let val = ptr::read(src);
881
0
            // The value hasn't been changed. Drop the guard without incrementing the stamp.
882
0
            guard.abort();
883
0
            val
884
        }
885
    }
886
21.2k
}
crossbeam_utils::atomic::atomic_cell::atomic_load::<usize>
Line
Count
Source
858
1
            a = &*(src as *const _ as *const _);
859
1
            mem::transmute_copy(&a.load(Ordering::Acquire))
860
        },
861
        {
862
0
            let lock = lock(src as usize);
863
864
            // Try doing an optimistic read first.
865
0
            if let Some(stamp) = lock.optimistic_read() {
866
                // We need a volatile read here because other threads might concurrently modify the
867
                // value. In theory, data races are *always* UB, even if we use volatile reads and
868
                // discard the data when a data race is detected. The proper solution would be to
869
                // do atomic reads and atomic writes, but we can't atomically read and write all
870
                // kinds of data since `AtomicU8` is not available on stable Rust yet.
871
0
                let val = ptr::read_volatile(src);
872
0
873
0
                if lock.validate_read(stamp) {
874
0
                    return val;
875
0
                }
876
0
            }
877
878
            // Grab a regular write lock so that writers don't starve this load.
879
0
            let guard = lock.write();
880
0
            let val = ptr::read(src);
881
0
            // The value hasn't been changed. Drop the guard without incrementing the stamp.
882
0
            guard.abort();
883
0
            val
884
        }
885
    }
886
1
}
crossbeam_utils::atomic::atomic_cell::atomic_load::<atomic_cell::modular_usize::Foo>
Line
Count
Source
858
4
            a = &*(src as *const _ as *const _);
859
4
            mem::transmute_copy(&a.load(Ordering::Acquire))
860
        },
861
        {
862
0
            let lock = lock(src as usize);
863
864
            // Try doing an optimistic read first.
865
0
            if let Some(stamp) = lock.optimistic_read() {
866
                // We need a volatile read here because other threads might concurrently modify the
867
                // value. In theory, data races are *always* UB, even if we use volatile reads and
868
                // discard the data when a data race is detected. The proper solution would be to
869
                // do atomic reads and atomic writes, but we can't atomically read and write all
870
                // kinds of data since `AtomicU8` is not available on stable Rust yet.
871
0
                let val = ptr::read_volatile(src);
872
0
873
0
                if lock.validate_read(stamp) {
874
0
                    return val;
875
0
                }
876
0
            }
877
878
            // Grab a regular write lock so that writers don't starve this load.
879
0
            let guard = lock.write();
880
0
            let val = ptr::read(src);
881
0
            // The value hasn't been changed. Drop the guard without incrementing the stamp.
882
0
            guard.abort();
883
0
            val
884
        }
885
    }
886
4
}
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_load::<atomic_cell::modular_u8::Foo>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_load::<atomic_cell::garbage_padding::Object>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_load::<std::time::Instant>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_load::<std::time::Instant>
crossbeam_utils::atomic::atomic_cell::atomic_load::<std::time::Instant>
Line
Count
Source
858
14
            a = &*(src as *const _ as *const _);
859
14
            mem::transmute_copy(&a.load(Ordering::Acquire))
860
        },
861
        {
862
0
            let lock = lock(src as usize);
863
864
            // Try doing an optimistic read first.
865
0
            if let Some(stamp) = lock.optimistic_read() {
866
                // We need a volatile read here because other threads might concurrently modify the
867
                // value. In theory, data races are *always* UB, even if we use volatile reads and
868
                // discard the data when a data race is detected. The proper solution would be to
869
                // do atomic reads and atomic writes, but we can't atomically read and write all
870
                // kinds of data since `AtomicU8` is not available on stable Rust yet.
871
0
                let val = ptr::read_volatile(src);
872
0
873
0
                if lock.validate_read(stamp) {
874
0
                    return val;
875
0
                }
876
0
            }
877
878
            // Grab a regular write lock so that writers don't starve this load.
879
0
            let guard = lock.write();
880
0
            let val = ptr::read(src);
881
0
            // The value hasn't been changed. Drop the guard without incrementing the stamp.
882
0
            guard.abort();
883
0
            val
884
        }
885
    }
886
14
}
crossbeam_utils::atomic::atomic_cell::atomic_load::<std::time::Instant>
Line
Count
Source
858
2.58k
            a = &*(src as *const _ as *const _);
859
2.58k
            mem::transmute_copy(&a.load(Ordering::Acquire))
860
        },
861
        {
862
0
            let lock = lock(src as usize);
863
864
            // Try doing an optimistic read first.
865
0
            if let Some(stamp) = lock.optimistic_read() {
866
                // We need a volatile read here because other threads might concurrently modify the
867
                // value. In theory, data races are *always* UB, even if we use volatile reads and
868
                // discard the data when a data race is detected. The proper solution would be to
869
                // do atomic reads and atomic writes, but we can't atomically read and write all
870
                // kinds of data since `AtomicU8` is not available on stable Rust yet.
871
0
                let val = ptr::read_volatile(src);
872
0
873
0
                if lock.validate_read(stamp) {
874
0
                    return val;
875
0
                }
876
0
            }
877
878
            // Grab a regular write lock so that writers don't starve this load.
879
0
            let guard = lock.write();
880
0
            let val = ptr::read(src);
881
0
            // The value hasn't been changed. Drop the guard without incrementing the stamp.
882
0
            guard.abort();
883
0
            val
884
        }
885
    }
886
2.58k
}
crossbeam_utils::atomic::atomic_cell::atomic_load::<std::time::Instant>
Line
Count
Source
858
5.16k
            a = &*(src as *const _ as *const _);
859
5.16k
            mem::transmute_copy(&a.load(Ordering::Acquire))
860
        },
861
        {
862
0
            let lock = lock(src as usize);
863
864
            // Try doing an optimistic read first.
865
0
            if let Some(stamp) = lock.optimistic_read() {
866
                // We need a volatile read here because other threads might concurrently modify the
867
                // value. In theory, data races are *always* UB, even if we use volatile reads and
868
                // discard the data when a data race is detected. The proper solution would be to
869
                // do atomic reads and atomic writes, but we can't atomically read and write all
870
                // kinds of data since `AtomicU8` is not available on stable Rust yet.
871
0
                let val = ptr::read_volatile(src);
872
0
873
0
                if lock.validate_read(stamp) {
874
0
                    return val;
875
0
                }
876
0
            }
877
878
            // Grab a regular write lock so that writers don't starve this load.
879
0
            let guard = lock.write();
880
0
            let val = ptr::read(src);
881
0
            // The value hasn't been changed. Drop the guard without incrementing the stamp.
882
0
            guard.abort();
883
0
            val
884
        }
885
    }
886
5.16k
}
887
888
/// Atomically writes `val` to `dst`.
889
///
890
/// This operation uses the `Release` ordering. If possible, an atomic instructions is used, and a
891
/// global lock otherwise.
892
unsafe fn atomic_store<T>(dst: *mut T, val: T) {
893
    atomic! {
894
        T, a,
895
        {
896
3
            a = &*(dst as *const _ as *const _);
897
3
            a.store(mem::transmute_copy(&val), Ordering::Release);
898
3
            mem::forget(val);
899
        },
900
0
        {
901
0
            let _guard = lock(dst as usize).write();
902
0
            ptr::write(dst, val);
903
0
        }
904
    }
905
3
}
crossbeam_utils::atomic::atomic_cell::atomic_store::<atomic_cell::modular_usize::Foo>
Line
Count
Source
896
1
            a = &*(dst as *const _ as *const _);
897
1
            a.store(mem::transmute_copy(&val), Ordering::Release);
898
1
            mem::forget(val);
899
        },
900
0
        {
901
0
            let _guard = lock(dst as usize).write();
902
0
            ptr::write(dst, val);
903
0
        }
904
    }
905
1
}
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_store::<atomic_cell::drops_u8::Foo>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_store::<atomic_cell::drops_usize::Foo>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_store::<atomic_cell::modular_u8::Foo>
crossbeam_utils::atomic::atomic_cell::atomic_store::<usize>
Line
Count
Source
896
1
            a = &*(dst as *const _ as *const _);
897
1
            a.store(mem::transmute_copy(&val), Ordering::Release);
898
1
            mem::forget(val);
899
        },
900
0
        {
901
0
            let _guard = lock(dst as usize).write();
902
0
            ptr::write(dst, val);
903
0
        }
904
    }
905
1
}
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_store::<atomic_cell::drops_unit::Foo>
906
907
/// Atomically swaps data at `dst` with `val`.
908
///
909
/// This operation uses the `AcqRel` ordering. If possible, an atomic instructions is used, and a
910
/// global lock otherwise.
911
unsafe fn atomic_swap<T>(dst: *mut T, val: T) -> T {
912
    atomic! {
913
        T, a,
914
        {
915
15
            a = &*(dst as *const _ as *const _);
916
15
            let res = mem::transmute_copy(&a.swap(mem::transmute_copy(&val), Ordering::AcqRel));
917
15
            mem::forget(val);
918
15
            res
919
        },
920
        {
921
0
            let _guard = lock(dst as usize).write();
922
0
            ptr::replace(dst, val)
923
        }
924
    }
925
15
}
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_swap::<atomic_cell::modular_u8::Foo>
crossbeam_utils::atomic::atomic_cell::atomic_swap::<atomic_cell::drops_usize::Foo>
Line
Count
Source
915
5
            a = &*(dst as *const _ as *const _);
916
5
            let res = mem::transmute_copy(&a.swap(mem::transmute_copy(&val), Ordering::AcqRel));
917
5
            mem::forget(val);
918
5
            res
919
        },
920
        {
921
0
            let _guard = lock(dst as usize).write();
922
0
            ptr::replace(dst, val)
923
        }
924
    }
925
5
}
crossbeam_utils::atomic::atomic_cell::atomic_swap::<atomic_cell::modular_usize::Foo>
Line
Count
Source
915
1
            a = &*(dst as *const _ as *const _);
916
1
            let res = mem::transmute_copy(&a.swap(mem::transmute_copy(&val), Ordering::AcqRel));
917
1
            mem::forget(val);
918
1
            res
919
        },
920
        {
921
0
            let _guard = lock(dst as usize).write();
922
0
            ptr::replace(dst, val)
923
        }
924
    }
925
1
}
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_swap::<atomic_cell::drops_u8::Foo>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_swap::<atomic_cell::drops_unit::Foo>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_swap::<usize>
926
927
/// Atomically compares data at `dst` to `current` and, if equal byte-for-byte, exchanges data at
928
/// `dst` with `new`.
929
///
930
/// Returns the old value on success, or the current value at `dst` on failure.
931
///
932
/// This operation uses the `AcqRel` ordering. If possible, an atomic instructions is used, and a
933
/// global lock otherwise.
934
unsafe fn atomic_compare_exchange_weak<T>(dst: *mut T, mut current: T, new: T) -> Result<T, T>
935
where
936
    T: Copy + Eq,
937
{
938
    atomic! {
939
        T, a,
940
        {
941
11.4k
            a = &*(dst as *const _ as *const _);
942
11.4k
            let mut current_raw = mem::transmute_copy(&current);
943
11.4k
            let new_raw = mem::transmute_copy(&new);
944
945
            loop {
946
11.4k
                match a.compare_exchange_weak(
947
11.4k
                    current_raw,
948
11.4k
                    new_raw,
949
11.4k
                    Ordering::AcqRel,
950
11.4k
                    Ordering::Acquire,
951
                ) {
952
11.4k
                    
Ok(_)11.4k
=> break Ok(current),
953
18.4E
                    Err(previous_raw) => {
954
18.4E
                        let previous = mem::transmute_copy(&previous_raw);
955
956
18.4E
                        if !T::eq(&previous, &current) {
957
9
                            break Err(previous);
958
2
                        }
959
960
                        // The compare-exchange operation has failed and didn't store `new`. The
961
                        // failure is either spurious, or `previous` was semantically equal to
962
                        // `current` but not byte-equal. Let's retry with `previous` as the new
963
                        // `current`.
964
2
                        current = previous;
965
2
                        current_raw = previous_raw;
966
                    }
967
                }
968
            }
969
        },
970
        {
971
1
            let guard = lock(dst as usize).write();
972
1
973
1
            if T::eq(&*dst, &current) {
974
1
                Ok(ptr::replace(dst, new))
975
            } else {
976
0
                let val = ptr::read(dst);
977
0
                // The value hasn't been changed. Drop the guard without incrementing the stamp.
978
0
                guard.abort();
979
0
                Err(val)
980
            }
981
        }
982
    }
983
11.4k
}
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_compare_exchange_weak::<std::time::Instant>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_compare_exchange_weak::<std::time::Instant>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_compare_exchange_weak::<std::time::Instant>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_compare_exchange_weak::<std::time::Instant>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_compare_exchange_weak::<std::time::Instant>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_compare_exchange_weak::<std::time::Instant>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_compare_exchange_weak::<std::time::Instant>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_compare_exchange_weak::<std::time::Instant>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_compare_exchange_weak::<std::time::Instant>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_compare_exchange_weak::<atomic_cell::modular_usize::Foo>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_compare_exchange_weak::<atomic_cell::modular_u8::Foo>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_compare_exchange_weak::<atomic_cell::garbage_padding::Object>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_compare_exchange_weak::<std::time::Instant>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_compare_exchange_weak::<std::time::Instant>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_compare_exchange_weak::<std::time::Instant>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_compare_exchange_weak::<std::time::Instant>
Unexecuted instantiation: crossbeam_utils::atomic::atomic_cell::atomic_compare_exchange_weak::<std::time::Instant>