Coverage Report

Created: 2026-09-14 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/crossbeam-epoch-0.9.21/src/atomic.rs
Line
Count
Source
1
use alloc::boxed::Box;
2
use core::alloc::Layout;
3
use core::borrow::{Borrow, BorrowMut};
4
use core::cmp;
5
use core::fmt;
6
use core::marker::PhantomData;
7
use core::mem::{self, MaybeUninit};
8
use core::ops::{Deref, DerefMut};
9
use core::ptr;
10
use core::slice;
11
12
use crate::guard::Guard;
13
use crate::primitive::sync::atomic::{AtomicUsize, Ordering};
14
use crossbeam_utils::atomic::AtomicConsume;
15
16
/// Given ordering for the success case in a compare-exchange operation, returns the strongest
17
/// appropriate ordering for the failure case.
18
#[inline]
19
0
fn strongest_failure_ordering(ord: Ordering) -> Ordering {
20
    use self::Ordering::*;
21
0
    match ord {
22
0
        Relaxed | Release => Relaxed,
23
0
        Acquire | AcqRel => Acquire,
24
0
        _ => SeqCst,
25
    }
26
0
}
27
28
/// The error returned on failed compare-and-set operation.
29
// TODO: remove in the next major version.
30
#[deprecated(note = "Use `CompareExchangeError` instead")]
31
pub type CompareAndSetError<'g, T, P> = CompareExchangeError<'g, T, P>;
32
33
/// The error returned on failed compare-and-swap operation.
34
pub struct CompareExchangeError<'g, T: ?Sized + Pointable, P: Pointer<T>> {
35
    /// The value in the atomic pointer at the time of the failed operation.
36
    pub current: Shared<'g, T>,
37
38
    /// The new value, which the operation failed to store.
39
    pub new: P,
40
}
41
42
impl<T, P: Pointer<T> + fmt::Debug> fmt::Debug for CompareExchangeError<'_, T, P> {
43
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44
0
        f.debug_struct("CompareExchangeError")
45
0
            .field("current", &self.current)
46
0
            .field("new", &self.new)
47
0
            .finish()
48
0
    }
49
}
50
51
/// Memory orderings for compare-and-set operations.
52
///
53
/// A compare-and-set operation can have different memory orderings depending on whether it
54
/// succeeds or fails. This trait generalizes different ways of specifying memory orderings.
55
///
56
/// The two ways of specifying orderings for compare-and-set are:
57
///
58
/// 1. Just one `Ordering` for the success case. In case of failure, the strongest appropriate
59
///    ordering is chosen.
60
/// 2. A pair of `Ordering`s. The first one is for the success case, while the second one is
61
///    for the failure case.
62
// TODO: remove in the next major version.
63
#[deprecated(
64
    note = "`compare_and_set` and `compare_and_set_weak` that use this trait are deprecated, \
65
            use `compare_exchange` or `compare_exchange_weak instead`"
66
)]
67
pub trait CompareAndSetOrdering {
68
    /// The ordering of the operation when it succeeds.
69
    fn success(&self) -> Ordering;
70
71
    /// The ordering of the operation when it fails.
72
    ///
73
    /// The failure ordering can't be `Release` or `AcqRel` and must be equivalent or weaker than
74
    /// the success ordering.
75
    fn failure(&self) -> Ordering;
76
}
77
78
#[allow(deprecated)]
79
impl CompareAndSetOrdering for Ordering {
80
    #[inline]
81
0
    fn success(&self) -> Ordering {
82
0
        *self
83
0
    }
84
85
    #[inline]
86
0
    fn failure(&self) -> Ordering {
87
0
        strongest_failure_ordering(*self)
88
0
    }
89
}
90
91
#[allow(deprecated)]
92
impl CompareAndSetOrdering for (Ordering, Ordering) {
93
    #[inline]
94
0
    fn success(&self) -> Ordering {
95
0
        self.0
96
0
    }
97
98
    #[inline]
99
0
    fn failure(&self) -> Ordering {
100
0
        self.1
101
0
    }
102
}
103
104
/// Returns a bitmask containing the unused least significant bits of an aligned pointer to `T`.
105
#[inline]
106
0
fn low_bits<T: ?Sized + Pointable>() -> usize {
107
0
    (1 << T::ALIGN.trailing_zeros()) - 1
108
0
}
Unexecuted instantiation: crossbeam_epoch::atomic::low_bits::<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>>
Unexecuted instantiation: crossbeam_epoch::atomic::low_bits::<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>
Unexecuted instantiation: crossbeam_epoch::atomic::low_bits::<crossbeam_epoch::internal::Local>
Unexecuted instantiation: crossbeam_epoch::atomic::low_bits::<crossbeam_epoch::sync::list::Entry>
109
110
/// Panics if the pointer is not properly unaligned.
111
#[inline]
112
0
fn ensure_aligned<T: ?Sized + Pointable>(raw: usize) {
113
0
    assert_eq!(raw & low_bits::<T>(), 0, "unaligned pointer");
114
0
}
Unexecuted instantiation: crossbeam_epoch::atomic::ensure_aligned::<crossbeam_epoch::internal::Local>
Unexecuted instantiation: crossbeam_epoch::atomic::ensure_aligned::<crossbeam_epoch::sync::list::Entry>
115
116
/// Given a tagged pointer `data`, returns the same pointer, but tagged with `tag`.
117
///
118
/// `tag` is truncated to fit into the unused bits of the pointer to `T`.
119
#[inline]
120
0
fn compose_tag<T: ?Sized + Pointable>(data: usize, tag: usize) -> usize {
121
0
    (data & !low_bits::<T>()) | (tag & low_bits::<T>())
122
0
}
123
124
/// Decomposes a tagged pointer `data` into the pointer and the tag.
125
#[inline]
126
0
fn decompose_tag<T: ?Sized + Pointable>(data: usize) -> (usize, usize) {
127
0
    (data & !low_bits::<T>(), data & low_bits::<T>())
128
0
}
Unexecuted instantiation: crossbeam_epoch::atomic::decompose_tag::<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>>
Unexecuted instantiation: crossbeam_epoch::atomic::decompose_tag::<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>
Unexecuted instantiation: crossbeam_epoch::atomic::decompose_tag::<crossbeam_epoch::internal::Local>
Unexecuted instantiation: crossbeam_epoch::atomic::decompose_tag::<crossbeam_epoch::sync::list::Entry>
129
130
/// Types that are pointed to by a single word.
131
///
132
/// In concurrent programming, it is necessary to represent an object within a word because atomic
133
/// operations (e.g., reads, writes, read-modify-writes) support only single words.  This trait
134
/// qualifies such types that are pointed to by a single word.
135
///
136
/// The trait generalizes `Box<T>` for a sized type `T`.  In a box, an object of type `T` is
137
/// allocated in heap and it is owned by a single-word pointer.  This trait is also implemented for
138
/// `[MaybeUninit<T>]` by storing its size along with its elements and pointing to the pair of array
139
/// size and elements.
140
///
141
/// Pointers to `Pointable` types can be stored in [`Atomic`], [`Owned`], and [`Shared`].  In
142
/// particular, Crossbeam supports dynamically sized slices as follows.
143
///
144
/// ```
145
/// use std::mem::MaybeUninit;
146
/// use crossbeam_epoch::Owned;
147
///
148
/// let o = Owned::<[MaybeUninit<i32>]>::init(10); // allocating [i32; 10]
149
/// ```
150
pub trait Pointable {
151
    /// The alignment of pointer.
152
    const ALIGN: usize;
153
154
    /// The type for initializers.
155
    type Init;
156
157
    /// Initializes a with the given initializer.
158
    ///
159
    /// # Safety
160
    ///
161
    /// The result should be a multiple of `ALIGN`.
162
    unsafe fn init(init: Self::Init) -> usize;
163
164
    /// Dereferences the given pointer.
165
    ///
166
    /// # Safety
167
    ///
168
    /// - The given `ptr` should have been initialized with [`Pointable::init`].
169
    /// - `ptr` should not have yet been dropped by [`Pointable::drop`].
170
    /// - `ptr` should not be mutably dereferenced by [`Pointable::deref_mut`] concurrently.
171
    unsafe fn deref<'a>(ptr: usize) -> &'a Self;
172
173
    /// Mutably dereferences the given pointer.
174
    ///
175
    /// # Safety
176
    ///
177
    /// - The given `ptr` should have been initialized with [`Pointable::init`].
178
    /// - `ptr` should not have yet been dropped by [`Pointable::drop`].
179
    /// - `ptr` should not be dereferenced by [`Pointable::deref`] or [`Pointable::deref_mut`]
180
    ///   concurrently.
181
    unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut Self;
182
183
    /// Drops the object pointed to by the given pointer.
184
    ///
185
    /// # Safety
186
    ///
187
    /// - The given `ptr` should have been initialized with [`Pointable::init`].
188
    /// - `ptr` should not have yet been dropped by [`Pointable::drop`].
189
    /// - `ptr` should not be dereferenced by [`Pointable::deref`] or [`Pointable::deref_mut`]
190
    ///   concurrently.
191
    unsafe fn drop(ptr: usize);
192
}
193
194
impl<T> Pointable for T {
195
    const ALIGN: usize = mem::align_of::<T>();
196
197
    type Init = T;
198
199
0
    unsafe fn init(init: Self::Init) -> usize {
200
0
        Box::into_raw(Box::new(init)) as usize
201
0
    }
Unexecuted instantiation: <crossbeam_deque::deque::Buffer<rayon_core::job::JobRef> as crossbeam_epoch::atomic::Pointable>::init
Unexecuted instantiation: <crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag> as crossbeam_epoch::atomic::Pointable>::init
Unexecuted instantiation: <crossbeam_epoch::internal::Local as crossbeam_epoch::atomic::Pointable>::init
202
203
0
    unsafe fn deref<'a>(ptr: usize) -> &'a Self {
204
0
        &*(ptr as *const T)
205
0
    }
Unexecuted instantiation: <crossbeam_deque::deque::Buffer<rayon_core::job::JobRef> as crossbeam_epoch::atomic::Pointable>::deref
Unexecuted instantiation: <crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag> as crossbeam_epoch::atomic::Pointable>::deref
Unexecuted instantiation: <crossbeam_epoch::internal::Local as crossbeam_epoch::atomic::Pointable>::deref
Unexecuted instantiation: <crossbeam_epoch::sync::list::Entry as crossbeam_epoch::atomic::Pointable>::deref
206
207
0
    unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut Self {
208
0
        &mut *(ptr as *mut T)
209
0
    }
210
211
0
    unsafe fn drop(ptr: usize) {
212
0
        drop(Box::from_raw(ptr as *mut T));
213
0
    }
Unexecuted instantiation: <crossbeam_deque::deque::Buffer<rayon_core::job::JobRef> as crossbeam_epoch::atomic::Pointable>::drop
Unexecuted instantiation: <crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag> as crossbeam_epoch::atomic::Pointable>::drop
Unexecuted instantiation: <crossbeam_epoch::internal::Local as crossbeam_epoch::atomic::Pointable>::drop
214
}
215
216
/// Array with size.
217
///
218
/// # Memory layout
219
///
220
/// An array consisting of size and elements:
221
///
222
/// ```text
223
///          elements
224
///          |
225
///          |
226
/// ------------------------------------
227
/// | size | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
228
/// ------------------------------------
229
/// ```
230
///
231
/// Its memory layout is different from that of `Box<[T]>` in that size is in the allocation (not
232
/// along with pointer as in `Box<[T]>`).
233
///
234
/// Elements are not present in the type, but they will be in the allocation.
235
#[repr(C)]
236
struct Array<T> {
237
    /// The number of elements (not the number of bytes).
238
    len: usize,
239
    elements: [MaybeUninit<T>; 0],
240
}
241
242
impl<T> Array<T> {
243
0
    fn layout(len: usize) -> Layout {
244
0
        Layout::new::<Self>()
245
0
            .extend(Layout::array::<MaybeUninit<T>>(len).unwrap())
246
0
            .unwrap()
247
0
            .0
248
0
            .pad_to_align()
249
0
    }
250
}
251
252
impl<T> Pointable for [MaybeUninit<T>] {
253
    const ALIGN: usize = mem::align_of::<Array<T>>();
254
255
    type Init = usize;
256
257
0
    unsafe fn init(len: Self::Init) -> usize {
258
0
        let layout = Array::<T>::layout(len);
259
0
        let ptr = alloc::alloc::alloc(layout).cast::<Array<T>>();
260
0
        if ptr.is_null() {
261
0
            alloc::alloc::handle_alloc_error(layout);
262
0
        }
263
0
        ptr::addr_of_mut!((*ptr).len).write(len);
264
0
        ptr as usize
265
0
    }
266
267
0
    unsafe fn deref<'a>(ptr: usize) -> &'a Self {
268
0
        let array = &*(ptr as *const Array<T>);
269
0
        slice::from_raw_parts(array.elements.as_ptr() as *const _, array.len)
270
0
    }
271
272
0
    unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut Self {
273
0
        let array = &*(ptr as *mut Array<T>);
274
0
        slice::from_raw_parts_mut(array.elements.as_ptr() as *mut _, array.len)
275
0
    }
276
277
0
    unsafe fn drop(ptr: usize) {
278
0
        let len = (*(ptr as *mut Array<T>)).len;
279
0
        let layout = Array::<T>::layout(len);
280
0
        alloc::alloc::dealloc(ptr as *mut u8, layout);
281
0
    }
282
}
283
284
/// An atomic pointer that can be safely shared between threads.
285
///
286
/// The pointer must be properly aligned. Since it is aligned, a tag can be stored into the unused
287
/// least significant bits of the address. For example, the tag for a pointer to a sized type `T`
288
/// should be less than `(1 << mem::align_of::<T>().trailing_zeros())`.
289
///
290
/// Any method that loads the pointer must be passed a reference to a [`Guard`].
291
///
292
/// Crossbeam supports dynamically sized types.  See [`Pointable`] for details.
293
pub struct Atomic<T: ?Sized + Pointable> {
294
    data: AtomicUsize,
295
    _marker: PhantomData<*mut T>,
296
}
297
298
unsafe impl<T: ?Sized + Pointable + Send + Sync> Send for Atomic<T> {}
299
unsafe impl<T: ?Sized + Pointable + Send + Sync> Sync for Atomic<T> {}
300
301
impl<T> Atomic<T> {
302
    /// Allocates `value` on the heap and returns a new atomic pointer pointing to it.
303
    ///
304
    /// # Examples
305
    ///
306
    /// ```
307
    /// use crossbeam_epoch::Atomic;
308
    ///
309
    /// let a = Atomic::new(1234);
310
    /// # unsafe { drop(a.into_owned()); } // avoid leak
311
    /// ```
312
0
    pub fn new(init: T) -> Atomic<T> {
313
0
        Self::init(init)
314
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>>>::new
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<_>>::new
315
}
316
317
impl<T: ?Sized + Pointable> Atomic<T> {
318
    /// Allocates `value` on the heap and returns a new atomic pointer pointing to it.
319
    ///
320
    /// # Examples
321
    ///
322
    /// ```
323
    /// use crossbeam_epoch::Atomic;
324
    ///
325
    /// let a = Atomic::<i32>::init(1234);
326
    /// # unsafe { drop(a.into_owned()); } // avoid leak
327
    /// ```
328
0
    pub fn init(init: T::Init) -> Atomic<T> {
329
0
        Self::from(Owned::init(init))
330
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>>>::init
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<_>>::init
331
332
    /// Returns a new atomic pointer pointing to the tagged pointer `data`.
333
0
    fn from_usize(data: usize) -> Self {
334
0
        Self {
335
0
            data: AtomicUsize::new(data),
336
0
            _marker: PhantomData,
337
0
        }
338
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>>>::from_usize
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<_>>::from_usize
339
340
    const_fn! {
341
        const_if: #[cfg(not(crossbeam_loom))];
342
        /// Returns a new null atomic pointer.
343
        ///
344
        /// # Examples
345
        ///
346
        /// ```
347
        /// use crossbeam_epoch::Atomic;
348
        ///
349
        /// let a = Atomic::<i32>::null();
350
        /// ```
351
0
        pub const fn null() -> Atomic<T> {
352
0
            Self {
353
0
                data: AtomicUsize::new(0),
354
0
                _marker: PhantomData,
355
0
            }
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>::null
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<crossbeam_epoch::sync::list::Entry>>::null
356
        }
357
    }
358
359
    /// Loads a `Shared` from the atomic pointer.
360
    ///
361
    /// This method takes an [`Ordering`] argument which describes the memory ordering of this
362
    /// operation.
363
    ///
364
    /// # Examples
365
    ///
366
    /// ```
367
    /// use crossbeam_epoch::{self as epoch, Atomic};
368
    /// use std::sync::atomic::Ordering::SeqCst;
369
    ///
370
    /// let a = Atomic::new(1234);
371
    /// let guard = &epoch::pin();
372
    /// let p = a.load(SeqCst, guard);
373
    /// # unsafe { drop(a.into_owned()); } // avoid leak
374
    /// ```
375
0
    pub fn load<'g>(&self, ord: Ordering, _: &'g Guard) -> Shared<'g, T> {
376
0
        unsafe { Shared::from_usize(self.data.load(ord)) }
377
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>>>::load
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>::load
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<crossbeam_epoch::sync::list::Entry>>::load
378
379
    /// Loads a `Shared` from the atomic pointer using a "consume" memory ordering.
380
    ///
381
    /// This is similar to the "acquire" ordering, except that an ordering is
382
    /// only guaranteed with operations that "depend on" the result of the load.
383
    /// However consume loads are usually much faster than acquire loads on
384
    /// architectures with a weak memory model since they don't require memory
385
    /// fence instructions.
386
    ///
387
    /// The exact definition of "depend on" is a bit vague, but it works as you
388
    /// would expect in practice since a lot of software, especially the Linux
389
    /// kernel, rely on this behavior.
390
    ///
391
    /// # Examples
392
    ///
393
    /// ```
394
    /// use crossbeam_epoch::{self as epoch, Atomic};
395
    ///
396
    /// let a = Atomic::new(1234);
397
    /// let guard = &epoch::pin();
398
    /// let p = a.load_consume(guard);
399
    /// # unsafe { drop(a.into_owned()); } // avoid leak
400
    /// ```
401
0
    pub fn load_consume<'g>(&self, _: &'g Guard) -> Shared<'g, T> {
402
0
        unsafe { Shared::from_usize(self.data.load_consume()) }
403
0
    }
404
405
    /// Stores a `Shared` or `Owned` pointer into the atomic pointer.
406
    ///
407
    /// This method takes an [`Ordering`] argument which describes the memory ordering of this
408
    /// operation.
409
    ///
410
    /// # Examples
411
    ///
412
    /// ```
413
    /// use crossbeam_epoch::{Atomic, Owned, Shared};
414
    /// use std::sync::atomic::Ordering::SeqCst;
415
    ///
416
    /// let a = Atomic::new(1234);
417
    /// # unsafe { drop(a.load(SeqCst, &crossbeam_epoch::pin()).into_owned()); } // avoid leak
418
    /// a.store(Shared::null(), SeqCst);
419
    /// a.store(Owned::new(1234), SeqCst);
420
    /// # unsafe { drop(a.into_owned()); } // avoid leak
421
    /// ```
422
0
    pub fn store<P: Pointer<T>>(&self, new: P, ord: Ordering) {
423
0
        self.data.store(new.into_usize(), ord);
424
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>::store::<crossbeam_epoch::atomic::Shared<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<crossbeam_epoch::sync::list::Entry>>::store::<crossbeam_epoch::atomic::Shared<crossbeam_epoch::sync::list::Entry>>
425
426
    /// Stores a `Shared` or `Owned` pointer into the atomic pointer, returning the previous
427
    /// `Shared`.
428
    ///
429
    /// This method takes an [`Ordering`] argument which describes the memory ordering of this
430
    /// operation.
431
    ///
432
    /// # Examples
433
    ///
434
    /// ```
435
    /// use crossbeam_epoch::{self as epoch, Atomic, Shared};
436
    /// use std::sync::atomic::Ordering::SeqCst;
437
    ///
438
    /// let a = Atomic::new(1234);
439
    /// let guard = &epoch::pin();
440
    /// let p = a.swap(Shared::null(), SeqCst, guard);
441
    /// # unsafe { drop(p.into_owned()); } // avoid leak
442
    /// ```
443
0
    pub fn swap<'g, P: Pointer<T>>(&self, new: P, ord: Ordering, _: &'g Guard) -> Shared<'g, T> {
444
0
        unsafe { Shared::from_usize(self.data.swap(new.into_usize(), ord)) }
445
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>>>::swap::<crossbeam_epoch::atomic::Shared<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>>>
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<_>>::swap::<_>
446
447
    /// Stores the pointer `new` (either `Shared` or `Owned`) into the atomic pointer if the current
448
    /// value is the same as `current`. The tag is also taken into account, so two pointers to the
449
    /// same object, but with different tags, will not be considered equal.
450
    ///
451
    /// The return value is a result indicating whether the new pointer was written. On success the
452
    /// pointer that was written is returned. On failure the actual current value and `new` are
453
    /// returned.
454
    ///
455
    /// This method takes two `Ordering` arguments to describe the memory
456
    /// ordering of this operation. `success` describes the required ordering for the
457
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
458
    /// `failure` describes the required ordering for the load operation that takes place when
459
    /// the comparison fails. Using `Acquire` as success ordering makes the store part
460
    /// of this operation `Relaxed`, and using `Release` makes the successful load
461
    /// `Relaxed`. The failure ordering can only be `SeqCst`, `Acquire` or `Relaxed`
462
    /// and must be equivalent to or weaker than the success ordering.
463
    ///
464
    /// # Examples
465
    ///
466
    /// ```
467
    /// use crossbeam_epoch::{self as epoch, Atomic, Owned, Shared};
468
    /// use std::sync::atomic::Ordering::SeqCst;
469
    ///
470
    /// let a = Atomic::new(1234);
471
    ///
472
    /// let guard = &epoch::pin();
473
    /// let curr = a.load(SeqCst, guard);
474
    /// let res1 = a.compare_exchange(curr, Shared::null(), SeqCst, SeqCst, guard);
475
    /// let res2 = a.compare_exchange(curr, Owned::new(5678), SeqCst, SeqCst, guard);
476
    /// # unsafe { drop(curr.into_owned()); } // avoid leak
477
    /// ```
478
0
    pub fn compare_exchange<'g, P>(
479
0
        &self,
480
0
        current: Shared<'_, T>,
481
0
        new: P,
482
0
        success: Ordering,
483
0
        failure: Ordering,
484
0
        _: &'g Guard,
485
0
    ) -> Result<Shared<'g, T>, CompareExchangeError<'g, T, P>>
486
0
    where
487
0
        P: Pointer<T>,
488
    {
489
0
        let new = new.into_usize();
490
0
        self.data
491
0
            .compare_exchange(current.into_usize(), new, success, failure)
492
0
            .map(|_| unsafe { Shared::from_usize(new) })
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>::compare_exchange::<crossbeam_epoch::atomic::Shared<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>::{closure#0}
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<crossbeam_epoch::sync::list::Entry>>::compare_exchange::<crossbeam_epoch::atomic::Shared<crossbeam_epoch::sync::list::Entry>>::{closure#0}
493
0
            .map_err(|current| unsafe {
494
0
                CompareExchangeError {
495
0
                    current: Shared::from_usize(current),
496
0
                    new: P::from_usize(new),
497
0
                }
498
0
            })
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>::compare_exchange::<crossbeam_epoch::atomic::Shared<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>::{closure#1}
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<crossbeam_epoch::sync::list::Entry>>::compare_exchange::<crossbeam_epoch::atomic::Shared<crossbeam_epoch::sync::list::Entry>>::{closure#1}
499
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>::compare_exchange::<crossbeam_epoch::atomic::Shared<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<crossbeam_epoch::sync::list::Entry>>::compare_exchange::<crossbeam_epoch::atomic::Shared<crossbeam_epoch::sync::list::Entry>>
500
501
    /// Stores the pointer `new` (either `Shared` or `Owned`) into the atomic pointer if the current
502
    /// value is the same as `current`. The tag is also taken into account, so two pointers to the
503
    /// same object, but with different tags, will not be considered equal.
504
    ///
505
    /// Unlike [`compare_exchange`], this method is allowed to spuriously fail even when comparison
506
    /// succeeds, which can result in more efficient code on some platforms.  The return value is a
507
    /// result indicating whether the new pointer was written. On success the pointer that was
508
    /// written is returned. On failure the actual current value and `new` are returned.
509
    ///
510
    /// This method takes two `Ordering` arguments to describe the memory
511
    /// ordering of this operation. `success` describes the required ordering for the
512
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
513
    /// `failure` describes the required ordering for the load operation that takes place when
514
    /// the comparison fails. Using `Acquire` as success ordering makes the store part
515
    /// of this operation `Relaxed`, and using `Release` makes the successful load
516
    /// `Relaxed`. The failure ordering can only be `SeqCst`, `Acquire` or `Relaxed`
517
    /// and must be equivalent to or weaker than the success ordering.
518
    ///
519
    /// [`compare_exchange`]: Atomic::compare_exchange
520
    ///
521
    /// # Examples
522
    ///
523
    /// ```
524
    /// use crossbeam_epoch::{self as epoch, Atomic, Owned, Shared};
525
    /// use std::sync::atomic::Ordering::SeqCst;
526
    ///
527
    /// let a = Atomic::new(1234);
528
    /// let guard = &epoch::pin();
529
    ///
530
    /// let mut new = Owned::new(5678);
531
    /// let mut ptr = a.load(SeqCst, guard);
532
    /// # unsafe { drop(a.load(SeqCst, guard).into_owned()); } // avoid leak
533
    /// loop {
534
    ///     match a.compare_exchange_weak(ptr, new, SeqCst, SeqCst, guard) {
535
    ///         Ok(p) => {
536
    ///             ptr = p;
537
    ///             break;
538
    ///         }
539
    ///         Err(err) => {
540
    ///             ptr = err.current;
541
    ///             new = err.new;
542
    ///         }
543
    ///     }
544
    /// }
545
    ///
546
    /// let mut curr = a.load(SeqCst, guard);
547
    /// loop {
548
    ///     match a.compare_exchange_weak(curr, Shared::null(), SeqCst, SeqCst, guard) {
549
    ///         Ok(_) => break,
550
    ///         Err(err) => curr = err.current,
551
    ///     }
552
    /// }
553
    /// # unsafe { drop(curr.into_owned()); } // avoid leak
554
    /// ```
555
0
    pub fn compare_exchange_weak<'g, P>(
556
0
        &self,
557
0
        current: Shared<'_, T>,
558
0
        new: P,
559
0
        success: Ordering,
560
0
        failure: Ordering,
561
0
        _: &'g Guard,
562
0
    ) -> Result<Shared<'g, T>, CompareExchangeError<'g, T, P>>
563
0
    where
564
0
        P: Pointer<T>,
565
    {
566
0
        let new = new.into_usize();
567
0
        self.data
568
0
            .compare_exchange_weak(current.into_usize(), new, success, failure)
569
0
            .map(|_| unsafe { Shared::from_usize(new) })
570
0
            .map_err(|current| unsafe {
571
0
                CompareExchangeError {
572
0
                    current: Shared::from_usize(current),
573
0
                    new: P::from_usize(new),
574
0
                }
575
0
            })
576
0
    }
577
578
    /// Fetches the pointer, and then applies a function to it that returns a new value.
579
    /// Returns a `Result` of `Ok(previous_value)` if the function returned `Some`, else `Err(_)`.
580
    ///
581
    /// Note that the given function may be called multiple times if the value has been changed by
582
    /// other threads in the meantime, as long as the function returns `Some(_)`, but the function
583
    /// will have been applied only once to the stored value.
584
    ///
585
    /// `fetch_update` takes two [`Ordering`] arguments to describe the memory
586
    /// ordering of this operation. The first describes the required ordering for
587
    /// when the operation finally succeeds while the second describes the
588
    /// required ordering for loads. These correspond to the success and failure
589
    /// orderings of [`Atomic::compare_exchange`] respectively.
590
    ///
591
    /// Using [`Acquire`] as success ordering makes the store part of this
592
    /// operation [`Relaxed`], and using [`Release`] makes the final successful
593
    /// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`],
594
    /// [`Acquire`] or [`Relaxed`] and must be equivalent to or weaker than the
595
    /// success ordering.
596
    ///
597
    /// [`Relaxed`]: Ordering::Relaxed
598
    /// [`Acquire`]: Ordering::Acquire
599
    /// [`Release`]: Ordering::Release
600
    /// [`SeqCst`]: Ordering::SeqCst
601
    ///
602
    /// # Examples
603
    ///
604
    /// ```
605
    /// use crossbeam_epoch::{self as epoch, Atomic};
606
    /// use std::sync::atomic::Ordering::SeqCst;
607
    ///
608
    /// let a = Atomic::new(1234);
609
    /// let guard = &epoch::pin();
610
    ///
611
    /// let res1 = a.fetch_update(SeqCst, SeqCst, guard, |x| Some(x.with_tag(1)));
612
    /// assert!(res1.is_ok());
613
    ///
614
    /// let res2 = a.fetch_update(SeqCst, SeqCst, guard, |x| None);
615
    /// assert!(res2.is_err());
616
    /// # unsafe { drop(a.into_owned()); } // avoid leak
617
    /// ```
618
0
    pub fn fetch_update<'g, F>(
619
0
        &self,
620
0
        set_order: Ordering,
621
0
        fail_order: Ordering,
622
0
        guard: &'g Guard,
623
0
        mut func: F,
624
0
    ) -> Result<Shared<'g, T>, Shared<'g, T>>
625
0
    where
626
0
        F: FnMut(Shared<'g, T>) -> Option<Shared<'g, T>>,
627
    {
628
0
        let mut prev = self.load(fail_order, guard);
629
0
        while let Some(next) = func(prev) {
630
0
            match self.compare_exchange_weak(prev, next, set_order, fail_order, guard) {
631
0
                Ok(_result) => return Ok(prev),
632
0
                Err(next_prev) => prev = next_prev.current,
633
            }
634
        }
635
0
        Err(prev)
636
0
    }
637
638
    /// Stores the pointer `new` (either `Shared` or `Owned`) into the atomic pointer if the current
639
    /// value is the same as `current`. The tag is also taken into account, so two pointers to the
640
    /// same object, but with different tags, will not be considered equal.
641
    ///
642
    /// The return value is a result indicating whether the new pointer was written. On success the
643
    /// pointer that was written is returned. On failure the actual current value and `new` are
644
    /// returned.
645
    ///
646
    /// This method takes a [`CompareAndSetOrdering`] argument which describes the memory
647
    /// ordering of this operation.
648
    ///
649
    /// # Migrating to `compare_exchange`
650
    ///
651
    /// `compare_and_set` is equivalent to `compare_exchange` with the following mapping for
652
    /// memory orderings:
653
    ///
654
    /// Original | Success | Failure
655
    /// -------- | ------- | -------
656
    /// Relaxed  | Relaxed | Relaxed
657
    /// Acquire  | Acquire | Acquire
658
    /// Release  | Release | Relaxed
659
    /// AcqRel   | AcqRel  | Acquire
660
    /// SeqCst   | SeqCst  | SeqCst
661
    ///
662
    /// # Examples
663
    ///
664
    /// ```
665
    /// # #![allow(deprecated)]
666
    /// use crossbeam_epoch::{self as epoch, Atomic, Owned, Shared};
667
    /// use std::sync::atomic::Ordering::SeqCst;
668
    ///
669
    /// let a = Atomic::new(1234);
670
    ///
671
    /// let guard = &epoch::pin();
672
    /// let curr = a.load(SeqCst, guard);
673
    /// let res1 = a.compare_and_set(curr, Shared::null(), SeqCst, guard);
674
    /// let res2 = a.compare_and_set(curr, Owned::new(5678), SeqCst, guard);
675
    /// # unsafe { drop(curr.into_owned()); } // avoid leak
676
    /// ```
677
    // TODO: remove in the next major version.
678
    #[allow(deprecated)]
679
    #[deprecated(note = "Use `compare_exchange` instead")]
680
0
    pub fn compare_and_set<'g, O, P>(
681
0
        &self,
682
0
        current: Shared<'_, T>,
683
0
        new: P,
684
0
        ord: O,
685
0
        guard: &'g Guard,
686
0
    ) -> Result<Shared<'g, T>, CompareAndSetError<'g, T, P>>
687
0
    where
688
0
        O: CompareAndSetOrdering,
689
0
        P: Pointer<T>,
690
    {
691
0
        self.compare_exchange(current, new, ord.success(), ord.failure(), guard)
692
0
    }
693
694
    /// Stores the pointer `new` (either `Shared` or `Owned`) into the atomic pointer if the current
695
    /// value is the same as `current`. The tag is also taken into account, so two pointers to the
696
    /// same object, but with different tags, will not be considered equal.
697
    ///
698
    /// Unlike [`compare_and_set`], this method is allowed to spuriously fail even when comparison
699
    /// succeeds, which can result in more efficient code on some platforms.  The return value is a
700
    /// result indicating whether the new pointer was written. On success the pointer that was
701
    /// written is returned. On failure the actual current value and `new` are returned.
702
    ///
703
    /// This method takes a [`CompareAndSetOrdering`] argument which describes the memory
704
    /// ordering of this operation.
705
    ///
706
    /// [`compare_and_set`]: Atomic::compare_and_set
707
    ///
708
    /// # Migrating to `compare_exchange_weak`
709
    ///
710
    /// `compare_and_set_weak` is equivalent to `compare_exchange_weak` with the following mapping for
711
    /// memory orderings:
712
    ///
713
    /// Original | Success | Failure
714
    /// -------- | ------- | -------
715
    /// Relaxed  | Relaxed | Relaxed
716
    /// Acquire  | Acquire | Acquire
717
    /// Release  | Release | Relaxed
718
    /// AcqRel   | AcqRel  | Acquire
719
    /// SeqCst   | SeqCst  | SeqCst
720
    ///
721
    /// # Examples
722
    ///
723
    /// ```
724
    /// # #![allow(deprecated)]
725
    /// use crossbeam_epoch::{self as epoch, Atomic, Owned, Shared};
726
    /// use std::sync::atomic::Ordering::SeqCst;
727
    ///
728
    /// let a = Atomic::new(1234);
729
    /// let guard = &epoch::pin();
730
    ///
731
    /// let mut new = Owned::new(5678);
732
    /// let mut ptr = a.load(SeqCst, guard);
733
    /// # unsafe { drop(a.load(SeqCst, guard).into_owned()); } // avoid leak
734
    /// loop {
735
    ///     match a.compare_and_set_weak(ptr, new, SeqCst, guard) {
736
    ///         Ok(p) => {
737
    ///             ptr = p;
738
    ///             break;
739
    ///         }
740
    ///         Err(err) => {
741
    ///             ptr = err.current;
742
    ///             new = err.new;
743
    ///         }
744
    ///     }
745
    /// }
746
    ///
747
    /// let mut curr = a.load(SeqCst, guard);
748
    /// loop {
749
    ///     match a.compare_and_set_weak(curr, Shared::null(), SeqCst, guard) {
750
    ///         Ok(_) => break,
751
    ///         Err(err) => curr = err.current,
752
    ///     }
753
    /// }
754
    /// # unsafe { drop(curr.into_owned()); } // avoid leak
755
    /// ```
756
    // TODO: remove in the next major version.
757
    #[allow(deprecated)]
758
    #[deprecated(note = "Use `compare_exchange_weak` instead")]
759
0
    pub fn compare_and_set_weak<'g, O, P>(
760
0
        &self,
761
0
        current: Shared<'_, T>,
762
0
        new: P,
763
0
        ord: O,
764
0
        guard: &'g Guard,
765
0
    ) -> Result<Shared<'g, T>, CompareAndSetError<'g, T, P>>
766
0
    where
767
0
        O: CompareAndSetOrdering,
768
0
        P: Pointer<T>,
769
    {
770
0
        self.compare_exchange_weak(current, new, ord.success(), ord.failure(), guard)
771
0
    }
772
773
    /// Bitwise "and" with the current tag.
774
    ///
775
    /// Performs a bitwise "and" operation on the current tag and the argument `val`, and sets the
776
    /// new tag to the result. Returns the previous pointer.
777
    ///
778
    /// This method takes an [`Ordering`] argument which describes the memory ordering of this
779
    /// operation.
780
    ///
781
    /// # Examples
782
    ///
783
    /// ```
784
    /// use crossbeam_epoch::{self as epoch, Atomic, Shared};
785
    /// use std::sync::atomic::Ordering::SeqCst;
786
    ///
787
    /// let a = Atomic::<i32>::from(Shared::null().with_tag(3));
788
    /// let guard = &epoch::pin();
789
    /// assert_eq!(a.fetch_and(2, SeqCst, guard).tag(), 3);
790
    /// assert_eq!(a.load(SeqCst, guard).tag(), 2);
791
    /// ```
792
0
    pub fn fetch_and<'g>(&self, val: usize, ord: Ordering, _: &'g Guard) -> Shared<'g, T> {
793
0
        unsafe { Shared::from_usize(self.data.fetch_and(val | !low_bits::<T>(), ord)) }
794
0
    }
795
796
    /// Bitwise "or" with the current tag.
797
    ///
798
    /// Performs a bitwise "or" operation on the current tag and the argument `val`, and sets the
799
    /// new tag to the result. Returns the previous pointer.
800
    ///
801
    /// This method takes an [`Ordering`] argument which describes the memory ordering of this
802
    /// operation.
803
    ///
804
    /// # Examples
805
    ///
806
    /// ```
807
    /// use crossbeam_epoch::{self as epoch, Atomic, Shared};
808
    /// use std::sync::atomic::Ordering::SeqCst;
809
    ///
810
    /// let a = Atomic::<i32>::from(Shared::null().with_tag(1));
811
    /// let guard = &epoch::pin();
812
    /// assert_eq!(a.fetch_or(2, SeqCst, guard).tag(), 1);
813
    /// assert_eq!(a.load(SeqCst, guard).tag(), 3);
814
    /// ```
815
0
    pub fn fetch_or<'g>(&self, val: usize, ord: Ordering, _: &'g Guard) -> Shared<'g, T> {
816
0
        unsafe { Shared::from_usize(self.data.fetch_or(val & low_bits::<T>(), ord)) }
817
0
    }
818
819
    /// Bitwise "xor" with the current tag.
820
    ///
821
    /// Performs a bitwise "xor" operation on the current tag and the argument `val`, and sets the
822
    /// new tag to the result. Returns the previous pointer.
823
    ///
824
    /// This method takes an [`Ordering`] argument which describes the memory ordering of this
825
    /// operation.
826
    ///
827
    /// # Examples
828
    ///
829
    /// ```
830
    /// use crossbeam_epoch::{self as epoch, Atomic, Shared};
831
    /// use std::sync::atomic::Ordering::SeqCst;
832
    ///
833
    /// let a = Atomic::<i32>::from(Shared::null().with_tag(1));
834
    /// let guard = &epoch::pin();
835
    /// assert_eq!(a.fetch_xor(3, SeqCst, guard).tag(), 1);
836
    /// assert_eq!(a.load(SeqCst, guard).tag(), 2);
837
    /// ```
838
0
    pub fn fetch_xor<'g>(&self, val: usize, ord: Ordering, _: &'g Guard) -> Shared<'g, T> {
839
0
        unsafe { Shared::from_usize(self.data.fetch_xor(val & low_bits::<T>(), ord)) }
840
0
    }
841
842
    /// Takes ownership of the pointee.
843
    ///
844
    /// This consumes the atomic and converts it into [`Owned`]. As [`Atomic`] doesn't have a
845
    /// destructor and doesn't drop the pointee while [`Owned`] does, this is suitable for
846
    /// destructors of data structures.
847
    ///
848
    /// # Panics
849
    ///
850
    /// Panics if this pointer is null, but only in debug mode.
851
    ///
852
    /// # Safety
853
    ///
854
    /// This method may be called only if the pointer is valid and nobody else is holding a
855
    /// reference to the same object.
856
    ///
857
    /// # Examples
858
    ///
859
    /// ```rust
860
    /// # use std::mem;
861
    /// # use crossbeam_epoch::Atomic;
862
    /// struct DataStructure {
863
    ///     ptr: Atomic<usize>,
864
    /// }
865
    ///
866
    /// impl Drop for DataStructure {
867
    ///     fn drop(&mut self) {
868
    ///         // By now the DataStructure lives only in our thread and we are sure we don't hold
869
    ///         // any Shared or & to it ourselves.
870
    ///         unsafe {
871
    ///             drop(mem::replace(&mut self.ptr, Atomic::null()).into_owned());
872
    ///         }
873
    ///     }
874
    /// }
875
    /// ```
876
0
    pub unsafe fn into_owned(self) -> Owned<T> {
877
0
        Owned::from_usize(self.data.into_inner())
878
0
    }
879
880
    /// Takes ownership of the pointee if it is non-null.
881
    ///
882
    /// This consumes the atomic and converts it into [`Owned`]. As [`Atomic`] doesn't have a
883
    /// destructor and doesn't drop the pointee while [`Owned`] does, this is suitable for
884
    /// destructors of data structures.
885
    ///
886
    /// # Safety
887
    ///
888
    /// This method may be called only if the pointer is valid and nobody else is holding a
889
    /// reference to the same object, or the pointer is null.
890
    ///
891
    /// # Examples
892
    ///
893
    /// ```rust
894
    /// # use std::mem;
895
    /// # use crossbeam_epoch::Atomic;
896
    /// struct DataStructure {
897
    ///     ptr: Atomic<usize>,
898
    /// }
899
    ///
900
    /// impl Drop for DataStructure {
901
    ///     fn drop(&mut self) {
902
    ///         // By now the DataStructure lives only in our thread and we are sure we don't hold
903
    ///         // any Shared or & to it ourselves, but it may be null, so we have to be careful.
904
    ///         let old = mem::replace(&mut self.ptr, Atomic::null());
905
    ///         unsafe {
906
    ///             if let Some(x) = old.try_into_owned() {
907
    ///                 drop(x)
908
    ///             }
909
    ///         }
910
    ///     }
911
    /// }
912
    /// ```
913
0
    pub unsafe fn try_into_owned(self) -> Option<Owned<T>> {
914
0
        let data = self.data.into_inner();
915
0
        if decompose_tag::<T>(data).0 == 0 {
916
0
            None
917
        } else {
918
0
            Some(Owned::from_usize(data))
919
        }
920
0
    }
921
}
922
923
impl<T: ?Sized + Pointable> fmt::Debug for Atomic<T> {
924
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
925
0
        let data = self.data.load(Ordering::SeqCst);
926
0
        let (raw, tag) = decompose_tag::<T>(data);
927
928
0
        f.debug_struct("Atomic")
929
0
            .field("raw", &raw)
930
0
            .field("tag", &tag)
931
0
            .finish()
932
0
    }
933
}
934
935
impl<T: ?Sized + Pointable> fmt::Pointer for Atomic<T> {
936
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
937
0
        let data = self.data.load(Ordering::SeqCst);
938
0
        let (raw, _) = decompose_tag::<T>(data);
939
0
        fmt::Pointer::fmt(&(raw as *const ()), f)
940
0
    }
941
}
942
943
impl<T: ?Sized + Pointable> Clone for Atomic<T> {
944
    /// Returns a copy of the atomic value.
945
    ///
946
    /// Note that a `Relaxed` load is used here. If you need synchronization, use it with other
947
    /// atomics or fences.
948
0
    fn clone(&self) -> Self {
949
0
        let data = self.data.load(Ordering::Relaxed);
950
0
        Atomic::from_usize(data)
951
0
    }
952
}
953
954
impl<T: ?Sized + Pointable> Default for Atomic<T> {
955
0
    fn default() -> Self {
956
0
        Atomic::null()
957
0
    }
958
}
959
960
impl<T: ?Sized + Pointable> From<Owned<T>> for Atomic<T> {
961
    /// Returns a new atomic pointer pointing to `owned`.
962
    ///
963
    /// # Examples
964
    ///
965
    /// ```
966
    /// use crossbeam_epoch::{Atomic, Owned};
967
    ///
968
    /// let a = Atomic::<i32>::from(Owned::new(1234));
969
    /// # unsafe { drop(a.into_owned()); } // avoid leak
970
    /// ```
971
0
    fn from(owned: Owned<T>) -> Self {
972
0
        let data = owned.data;
973
0
        mem::forget(owned);
974
0
        Self::from_usize(data)
975
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>> as core::convert::From<crossbeam_epoch::atomic::Owned<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>>>>::from
Unexecuted instantiation: <crossbeam_epoch::atomic::Atomic<_> as core::convert::From<crossbeam_epoch::atomic::Owned<_>>>::from
976
}
977
978
impl<T> From<Box<T>> for Atomic<T> {
979
0
    fn from(b: Box<T>) -> Self {
980
0
        Self::from(Owned::from(b))
981
0
    }
982
}
983
984
impl<T> From<T> for Atomic<T> {
985
0
    fn from(t: T) -> Self {
986
0
        Self::new(t)
987
0
    }
988
}
989
990
impl<'g, T: ?Sized + Pointable> From<Shared<'g, T>> for Atomic<T> {
991
    /// Returns a new atomic pointer pointing to `ptr`.
992
    ///
993
    /// # Examples
994
    ///
995
    /// ```
996
    /// use crossbeam_epoch::{Atomic, Shared};
997
    ///
998
    /// let a = Atomic::<i32>::from(Shared::<i32>::null());
999
    /// ```
1000
0
    fn from(ptr: Shared<'g, T>) -> Self {
1001
0
        Self::from_usize(ptr.data)
1002
0
    }
1003
}
1004
1005
impl<T> From<*const T> for Atomic<T> {
1006
    /// Returns a new atomic pointer pointing to `raw`.
1007
    ///
1008
    /// # Examples
1009
    ///
1010
    /// ```
1011
    /// use std::ptr;
1012
    /// use crossbeam_epoch::Atomic;
1013
    ///
1014
    /// let a = Atomic::<i32>::from(ptr::null::<i32>());
1015
    /// ```
1016
0
    fn from(raw: *const T) -> Self {
1017
0
        Self::from_usize(raw as usize)
1018
0
    }
1019
}
1020
1021
/// A trait for either `Owned` or `Shared` pointers.
1022
pub trait Pointer<T: ?Sized + Pointable> {
1023
    /// Returns the machine representation of the pointer.
1024
    fn into_usize(self) -> usize;
1025
1026
    /// Returns a new pointer pointing to the tagged pointer `data`.
1027
    ///
1028
    /// # Safety
1029
    ///
1030
    /// The given `data` should have been created by `Pointer::into_usize()`, and one `data` should
1031
    /// not be converted back by `Pointer::from_usize()` multiple times.
1032
    unsafe fn from_usize(data: usize) -> Self;
1033
}
1034
1035
/// An owned heap-allocated object.
1036
///
1037
/// This type is very similar to `Box<T>`.
1038
///
1039
/// The pointer must be properly aligned. Since it is aligned, a tag can be stored into the unused
1040
/// least significant bits of the address.
1041
pub struct Owned<T: ?Sized + Pointable> {
1042
    data: usize,
1043
    _marker: PhantomData<Box<T>>,
1044
}
1045
1046
impl<T: ?Sized + Pointable> Pointer<T> for Owned<T> {
1047
    #[inline]
1048
0
    fn into_usize(self) -> usize {
1049
0
        let data = self.data;
1050
0
        mem::forget(self);
1051
0
        data
1052
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>> as crossbeam_epoch::atomic::Pointer<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>>>::into_usize
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>> as crossbeam_epoch::atomic::Pointer<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>::into_usize
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<crossbeam_epoch::internal::Local> as crossbeam_epoch::atomic::Pointer<crossbeam_epoch::internal::Local>>::into_usize
1053
1054
    /// Returns a new pointer pointing to the tagged pointer `data`.
1055
    ///
1056
    /// # Panics
1057
    ///
1058
    /// Panics if the data is zero in debug mode.
1059
    #[inline]
1060
0
    unsafe fn from_usize(data: usize) -> Self {
1061
0
        debug_assert!(data != 0, "converting zero into `Owned`");
1062
0
        Owned {
1063
0
            data,
1064
0
            _marker: PhantomData,
1065
0
        }
1066
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>> as crossbeam_epoch::atomic::Pointer<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>>>::from_usize
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>> as crossbeam_epoch::atomic::Pointer<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>::from_usize
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<crossbeam_epoch::internal::Local> as crossbeam_epoch::atomic::Pointer<crossbeam_epoch::internal::Local>>::from_usize
1067
}
1068
1069
impl<T> Owned<T> {
1070
    /// Returns a new owned pointer pointing to `raw`.
1071
    ///
1072
    /// This function is unsafe because improper use may lead to memory problems. Argument `raw`
1073
    /// must be a valid pointer. Also, a double-free may occur if the function is called twice on
1074
    /// the same raw pointer.
1075
    ///
1076
    /// # Panics
1077
    ///
1078
    /// Panics if `raw` is not properly aligned.
1079
    ///
1080
    /// # Safety
1081
    ///
1082
    /// The given `raw` should have been derived from `Owned`, and one `raw` should not be converted
1083
    /// back by `Owned::from_raw()` multiple times.
1084
    ///
1085
    /// # Examples
1086
    ///
1087
    /// ```
1088
    /// use crossbeam_epoch::Owned;
1089
    ///
1090
    /// let o = unsafe { Owned::from_raw(Box::into_raw(Box::new(1234))) };
1091
    /// ```
1092
0
    pub unsafe fn from_raw(raw: *mut T) -> Owned<T> {
1093
0
        let raw = raw as usize;
1094
0
        ensure_aligned::<T>(raw);
1095
0
        Self::from_usize(raw)
1096
0
    }
1097
1098
    /// Converts the owned pointer into a `Box`.
1099
    ///
1100
    /// # Examples
1101
    ///
1102
    /// ```
1103
    /// use crossbeam_epoch::Owned;
1104
    ///
1105
    /// let o = Owned::new(1234);
1106
    /// let b: Box<i32> = o.into_box();
1107
    /// assert_eq!(*b, 1234);
1108
    /// ```
1109
0
    pub fn into_box(self) -> Box<T> {
1110
0
        let (raw, _) = decompose_tag::<T>(self.data);
1111
0
        mem::forget(self);
1112
0
        unsafe { Box::from_raw(raw as *mut _) }
1113
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>>>::into_box
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<_>>::into_box
1114
1115
    /// Allocates `value` on the heap and returns a new owned pointer pointing to it.
1116
    ///
1117
    /// # Examples
1118
    ///
1119
    /// ```
1120
    /// use crossbeam_epoch::Owned;
1121
    ///
1122
    /// let o = Owned::new(1234);
1123
    /// ```
1124
0
    pub fn new(init: T) -> Owned<T> {
1125
0
        Self::init(init)
1126
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>>>::new
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>::new
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<crossbeam_epoch::internal::Local>>::new
1127
}
1128
1129
impl<T: ?Sized + Pointable> Owned<T> {
1130
    /// Allocates `value` on the heap and returns a new owned pointer pointing to it.
1131
    ///
1132
    /// # Examples
1133
    ///
1134
    /// ```
1135
    /// use crossbeam_epoch::Owned;
1136
    ///
1137
    /// let o = Owned::<i32>::init(1234);
1138
    /// ```
1139
0
    pub fn init(init: T::Init) -> Owned<T> {
1140
0
        unsafe { Self::from_usize(T::init(init)) }
1141
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>>>::init
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>::init
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<crossbeam_epoch::internal::Local>>::init
1142
1143
    /// Converts the owned pointer into a [`Shared`].
1144
    ///
1145
    /// # Examples
1146
    ///
1147
    /// ```
1148
    /// use crossbeam_epoch::{self as epoch, Owned};
1149
    ///
1150
    /// let o = Owned::new(1234);
1151
    /// let guard = &epoch::pin();
1152
    /// let p = o.into_shared(guard);
1153
    /// # unsafe { drop(p.into_owned()); } // avoid leak
1154
    /// ```
1155
    #[allow(clippy::needless_lifetimes)]
1156
0
    pub fn into_shared<'g>(self, _: &'g Guard) -> Shared<'g, T> {
1157
0
        unsafe { Shared::from_usize(self.into_usize()) }
1158
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>>>::into_shared
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>::into_shared
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<crossbeam_epoch::internal::Local>>::into_shared
1159
1160
    /// Returns the tag stored within the pointer.
1161
    ///
1162
    /// # Examples
1163
    ///
1164
    /// ```
1165
    /// use crossbeam_epoch::Owned;
1166
    ///
1167
    /// assert_eq!(Owned::new(1234).tag(), 0);
1168
    /// ```
1169
0
    pub fn tag(&self) -> usize {
1170
0
        let (_, tag) = decompose_tag::<T>(self.data);
1171
0
        tag
1172
0
    }
1173
1174
    /// Returns the same pointer, but tagged with `tag`. `tag` is truncated to be fit into the
1175
    /// unused bits of the pointer to `T`.
1176
    ///
1177
    /// # Examples
1178
    ///
1179
    /// ```
1180
    /// use crossbeam_epoch::Owned;
1181
    ///
1182
    /// let o = Owned::new(0u64);
1183
    /// assert_eq!(o.tag(), 0);
1184
    /// let o = o.with_tag(2);
1185
    /// assert_eq!(o.tag(), 2);
1186
    /// ```
1187
0
    pub fn with_tag(self, tag: usize) -> Owned<T> {
1188
0
        let data = self.into_usize();
1189
0
        unsafe { Self::from_usize(compose_tag::<T>(data, tag)) }
1190
0
    }
1191
}
1192
1193
impl<T: ?Sized + Pointable> Drop for Owned<T> {
1194
0
    fn drop(&mut self) {
1195
0
        let (raw, _) = decompose_tag::<T>(self.data);
1196
0
        unsafe {
1197
0
            T::drop(raw);
1198
0
        }
1199
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>> as core::ops::drop::Drop>::drop
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>> as core::ops::drop::Drop>::drop
Unexecuted instantiation: <crossbeam_epoch::atomic::Owned<crossbeam_epoch::internal::Local> as core::ops::drop::Drop>::drop
1200
}
1201
1202
impl<T: ?Sized + Pointable> fmt::Debug for Owned<T> {
1203
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1204
0
        let (raw, tag) = decompose_tag::<T>(self.data);
1205
1206
0
        f.debug_struct("Owned")
1207
0
            .field("raw", &raw)
1208
0
            .field("tag", &tag)
1209
0
            .finish()
1210
0
    }
1211
}
1212
1213
impl<T: Clone> Clone for Owned<T> {
1214
0
    fn clone(&self) -> Self {
1215
0
        Owned::new((**self).clone()).with_tag(self.tag())
1216
0
    }
1217
}
1218
1219
impl<T: ?Sized + Pointable> Deref for Owned<T> {
1220
    type Target = T;
1221
1222
0
    fn deref(&self) -> &T {
1223
0
        let (raw, _) = decompose_tag::<T>(self.data);
1224
0
        unsafe { T::deref(raw) }
1225
0
    }
1226
}
1227
1228
impl<T: ?Sized + Pointable> DerefMut for Owned<T> {
1229
0
    fn deref_mut(&mut self) -> &mut T {
1230
0
        let (raw, _) = decompose_tag::<T>(self.data);
1231
0
        unsafe { T::deref_mut(raw) }
1232
0
    }
1233
}
1234
1235
impl<T> From<T> for Owned<T> {
1236
0
    fn from(t: T) -> Self {
1237
0
        Owned::new(t)
1238
0
    }
1239
}
1240
1241
impl<T> From<Box<T>> for Owned<T> {
1242
    /// Returns a new owned pointer pointing to `b`.
1243
    ///
1244
    /// # Panics
1245
    ///
1246
    /// Panics if the pointer (the `Box`) is not properly aligned.
1247
    ///
1248
    /// # Examples
1249
    ///
1250
    /// ```
1251
    /// use crossbeam_epoch::Owned;
1252
    ///
1253
    /// let o = unsafe { Owned::from_raw(Box::into_raw(Box::new(1234))) };
1254
    /// ```
1255
0
    fn from(b: Box<T>) -> Self {
1256
0
        unsafe { Self::from_raw(Box::into_raw(b)) }
1257
0
    }
1258
}
1259
1260
impl<T: ?Sized + Pointable> Borrow<T> for Owned<T> {
1261
0
    fn borrow(&self) -> &T {
1262
0
        self.deref()
1263
0
    }
1264
}
1265
1266
impl<T: ?Sized + Pointable> BorrowMut<T> for Owned<T> {
1267
0
    fn borrow_mut(&mut self) -> &mut T {
1268
0
        self.deref_mut()
1269
0
    }
1270
}
1271
1272
impl<T: ?Sized + Pointable> AsRef<T> for Owned<T> {
1273
0
    fn as_ref(&self) -> &T {
1274
0
        self.deref()
1275
0
    }
1276
}
1277
1278
impl<T: ?Sized + Pointable> AsMut<T> for Owned<T> {
1279
0
    fn as_mut(&mut self) -> &mut T {
1280
0
        self.deref_mut()
1281
0
    }
1282
}
1283
1284
/// A pointer to an object protected by the epoch GC.
1285
///
1286
/// The pointer is valid for use only during the lifetime `'g`.
1287
///
1288
/// The pointer must be properly aligned. Since it is aligned, a tag can be stored into the unused
1289
/// least significant bits of the address.
1290
pub struct Shared<'g, T: 'g + ?Sized + Pointable> {
1291
    data: usize,
1292
    _marker: PhantomData<(&'g (), *const T)>,
1293
}
1294
1295
impl<T: ?Sized + Pointable> Clone for Shared<'_, T> {
1296
0
    fn clone(&self) -> Self {
1297
0
        *self
1298
0
    }
1299
}
1300
1301
impl<T: ?Sized + Pointable> Copy for Shared<'_, T> {}
1302
1303
impl<T: ?Sized + Pointable> Pointer<T> for Shared<'_, T> {
1304
    #[inline]
1305
0
    fn into_usize(self) -> usize {
1306
0
        self.data
1307
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>> as crossbeam_epoch::atomic::Pointer<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>>>::into_usize
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>> as crossbeam_epoch::atomic::Pointer<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>::into_usize
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_epoch::sync::list::Entry> as crossbeam_epoch::atomic::Pointer<crossbeam_epoch::sync::list::Entry>>::into_usize
1308
1309
    #[inline]
1310
0
    unsafe fn from_usize(data: usize) -> Self {
1311
0
        Shared {
1312
0
            data,
1313
0
            _marker: PhantomData,
1314
0
        }
1315
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>> as crossbeam_epoch::atomic::Pointer<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>>>::from_usize
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>> as crossbeam_epoch::atomic::Pointer<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>::from_usize
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_epoch::internal::Local> as crossbeam_epoch::atomic::Pointer<crossbeam_epoch::internal::Local>>::from_usize
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_epoch::sync::list::Entry> as crossbeam_epoch::atomic::Pointer<crossbeam_epoch::sync::list::Entry>>::from_usize
1316
}
1317
1318
impl<'g, T> Shared<'g, T> {
1319
    /// Converts the pointer to a raw pointer (without the tag).
1320
    ///
1321
    /// # Examples
1322
    ///
1323
    /// ```
1324
    /// use crossbeam_epoch::{self as epoch, Atomic, Owned};
1325
    /// use std::sync::atomic::Ordering::SeqCst;
1326
    ///
1327
    /// let o = Owned::new(1234);
1328
    /// let raw = &*o as *const _;
1329
    /// let a = Atomic::from(o);
1330
    ///
1331
    /// let guard = &epoch::pin();
1332
    /// let p = a.load(SeqCst, guard);
1333
    /// assert_eq!(p.as_raw(), raw);
1334
    /// # unsafe { drop(a.into_owned()); } // avoid leak
1335
    /// ```
1336
0
    pub fn as_raw(&self) -> *const T {
1337
0
        let (raw, _) = decompose_tag::<T>(self.data);
1338
0
        raw as *const _
1339
0
    }
1340
}
1341
1342
impl<'g, T: ?Sized + Pointable> Shared<'g, T> {
1343
    /// Returns a new null pointer.
1344
    ///
1345
    /// # Examples
1346
    ///
1347
    /// ```
1348
    /// use crossbeam_epoch::Shared;
1349
    ///
1350
    /// let p = Shared::<i32>::null();
1351
    /// assert!(p.is_null());
1352
    /// ```
1353
0
    pub const fn null() -> Shared<'g, T> {
1354
0
        Shared {
1355
0
            data: 0,
1356
0
            _marker: PhantomData,
1357
0
        }
1358
0
    }
1359
1360
    /// Returns `true` if the pointer is null.
1361
    ///
1362
    /// # Examples
1363
    ///
1364
    /// ```
1365
    /// use crossbeam_epoch::{self as epoch, Atomic, Owned};
1366
    /// use std::sync::atomic::Ordering::SeqCst;
1367
    ///
1368
    /// let a = Atomic::null();
1369
    /// let guard = &epoch::pin();
1370
    /// assert!(a.load(SeqCst, guard).is_null());
1371
    /// a.store(Owned::new(1234), SeqCst);
1372
    /// assert!(!a.load(SeqCst, guard).is_null());
1373
    /// # unsafe { drop(a.into_owned()); } // avoid leak
1374
    /// ```
1375
0
    pub fn is_null(&self) -> bool {
1376
0
        let (raw, _) = decompose_tag::<T>(self.data);
1377
0
        raw == 0
1378
0
    }
1379
1380
    /// Dereferences the pointer.
1381
    ///
1382
    /// Returns a reference to the pointee that is valid during the lifetime `'g`.
1383
    ///
1384
    /// # Safety
1385
    ///
1386
    /// Dereferencing a pointer is unsafe because it could be pointing to invalid memory.
1387
    ///
1388
    /// Another concern is the possibility of data races due to lack of proper synchronization.
1389
    /// For example, consider the following scenario:
1390
    ///
1391
    /// 1. A thread creates a new object: `a.store(Owned::new(10), Relaxed)`
1392
    /// 2. Another thread reads it: `*a.load(Relaxed, guard).as_ref().unwrap()`
1393
    ///
1394
    /// The problem is that relaxed orderings don't synchronize initialization of the object with
1395
    /// the read from the second thread. This is a data race. A possible solution would be to use
1396
    /// `Release` and `Acquire` orderings.
1397
    ///
1398
    /// # Examples
1399
    ///
1400
    /// ```
1401
    /// use crossbeam_epoch::{self as epoch, Atomic};
1402
    /// use std::sync::atomic::Ordering::SeqCst;
1403
    ///
1404
    /// let a = Atomic::new(1234);
1405
    /// let guard = &epoch::pin();
1406
    /// let p = a.load(SeqCst, guard);
1407
    /// unsafe {
1408
    ///     assert_eq!(p.deref(), &1234);
1409
    /// }
1410
    /// # unsafe { drop(a.into_owned()); } // avoid leak
1411
    /// ```
1412
0
    pub unsafe fn deref(&self) -> &'g T {
1413
0
        let (raw, _) = decompose_tag::<T>(self.data);
1414
0
        T::deref(raw)
1415
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>>>::deref
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>::deref
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_epoch::internal::Local>>::deref
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_epoch::sync::list::Entry>>::deref
1416
1417
    /// Dereferences the pointer.
1418
    ///
1419
    /// Returns a mutable reference to the pointee that is valid during the lifetime `'g`.
1420
    ///
1421
    /// # Safety
1422
    ///
1423
    /// * There is no guarantee that there are no more threads attempting to read/write from/to the
1424
    ///   actual object at the same time.
1425
    ///
1426
    ///   The user must know that there are no concurrent accesses towards the object itself.
1427
    ///
1428
    /// * Other than the above, all safety concerns of `deref()` applies here.
1429
    ///
1430
    /// # Examples
1431
    ///
1432
    /// ```
1433
    /// use crossbeam_epoch::{self as epoch, Atomic};
1434
    /// use std::sync::atomic::Ordering::SeqCst;
1435
    ///
1436
    /// let a = Atomic::new(vec![1, 2, 3, 4]);
1437
    /// let guard = &epoch::pin();
1438
    ///
1439
    /// let mut p = a.load(SeqCst, guard);
1440
    /// unsafe {
1441
    ///     assert!(!p.is_null());
1442
    ///     let b = p.deref_mut();
1443
    ///     assert_eq!(b, &vec![1, 2, 3, 4]);
1444
    ///     b.push(5);
1445
    ///     assert_eq!(b, &vec![1, 2, 3, 4, 5]);
1446
    /// }
1447
    ///
1448
    /// let p = a.load(SeqCst, guard);
1449
    /// unsafe {
1450
    ///     assert_eq!(p.deref(), &vec![1, 2, 3, 4, 5]);
1451
    /// }
1452
    /// # unsafe { drop(a.into_owned()); } // avoid leak
1453
    /// ```
1454
0
    pub unsafe fn deref_mut(&mut self) -> &'g mut T {
1455
0
        let (raw, _) = decompose_tag::<T>(self.data);
1456
0
        T::deref_mut(raw)
1457
0
    }
1458
1459
    /// Converts the pointer to a reference.
1460
    ///
1461
    /// Returns `None` if the pointer is null, or else a reference to the object wrapped in `Some`.
1462
    ///
1463
    /// # Safety
1464
    ///
1465
    /// Dereferencing a pointer is unsafe because it could be pointing to invalid memory.
1466
    ///
1467
    /// Another concern is the possibility of data races due to lack of proper synchronization.
1468
    /// For example, consider the following scenario:
1469
    ///
1470
    /// 1. A thread creates a new object: `a.store(Owned::new(10), Relaxed)`
1471
    /// 2. Another thread reads it: `*a.load(Relaxed, guard).as_ref().unwrap()`
1472
    ///
1473
    /// The problem is that relaxed orderings don't synchronize initialization of the object with
1474
    /// the read from the second thread. This is a data race. A possible solution would be to use
1475
    /// `Release` and `Acquire` orderings.
1476
    ///
1477
    /// # Examples
1478
    ///
1479
    /// ```
1480
    /// use crossbeam_epoch::{self as epoch, Atomic};
1481
    /// use std::sync::atomic::Ordering::SeqCst;
1482
    ///
1483
    /// let a = Atomic::new(1234);
1484
    /// let guard = &epoch::pin();
1485
    /// let p = a.load(SeqCst, guard);
1486
    /// unsafe {
1487
    ///     assert_eq!(p.as_ref(), Some(&1234));
1488
    /// }
1489
    /// # unsafe { drop(a.into_owned()); } // avoid leak
1490
    /// ```
1491
0
    pub unsafe fn as_ref(&self) -> Option<&'g T> {
1492
0
        let (raw, _) = decompose_tag::<T>(self.data);
1493
0
        if raw == 0 {
1494
0
            None
1495
        } else {
1496
0
            Some(T::deref(raw))
1497
        }
1498
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>::as_ref
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_epoch::sync::list::Entry>>::as_ref
1499
1500
    /// Takes ownership of the pointee.
1501
    ///
1502
    /// # Panics
1503
    ///
1504
    /// Panics if this pointer is null, but only in debug mode.
1505
    ///
1506
    /// # Safety
1507
    ///
1508
    /// This method may be called only if the pointer is valid and nobody else is holding a
1509
    /// reference to the same object.
1510
    ///
1511
    /// # Examples
1512
    ///
1513
    /// ```
1514
    /// use crossbeam_epoch::{self as epoch, Atomic};
1515
    /// use std::sync::atomic::Ordering::SeqCst;
1516
    ///
1517
    /// let a = Atomic::new(1234);
1518
    /// unsafe {
1519
    ///     let guard = &epoch::unprotected();
1520
    ///     let p = a.load(SeqCst, guard);
1521
    ///     drop(p.into_owned());
1522
    /// }
1523
    /// ```
1524
0
    pub unsafe fn into_owned(self) -> Owned<T> {
1525
0
        debug_assert!(!self.is_null(), "converting a null `Shared` into `Owned`");
1526
0
        Owned::from_usize(self.data)
1527
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>>>::into_owned
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>>>::into_owned
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_epoch::internal::Local>>::into_owned
1528
1529
    /// Takes ownership of the pointee if it is not null.
1530
    ///
1531
    /// # Safety
1532
    ///
1533
    /// This method may be called only if the pointer is valid and nobody else is holding a
1534
    /// reference to the same object, or if the pointer is null.
1535
    ///
1536
    /// # Examples
1537
    ///
1538
    /// ```
1539
    /// use crossbeam_epoch::{self as epoch, Atomic};
1540
    /// use std::sync::atomic::Ordering::SeqCst;
1541
    ///
1542
    /// let a = Atomic::new(1234);
1543
    /// unsafe {
1544
    ///     let guard = &epoch::unprotected();
1545
    ///     let p = a.load(SeqCst, guard);
1546
    ///     if let Some(x) = p.try_into_owned() {
1547
    ///         drop(x);
1548
    ///     }
1549
    /// }
1550
    /// ```
1551
0
    pub unsafe fn try_into_owned(self) -> Option<Owned<T>> {
1552
0
        if self.is_null() {
1553
0
            None
1554
        } else {
1555
0
            Some(Owned::from_usize(self.data))
1556
        }
1557
0
    }
1558
1559
    /// Returns the tag stored within the pointer.
1560
    ///
1561
    /// # Examples
1562
    ///
1563
    /// ```
1564
    /// use crossbeam_epoch::{self as epoch, Atomic, Owned};
1565
    /// use std::sync::atomic::Ordering::SeqCst;
1566
    ///
1567
    /// let a = Atomic::<u64>::from(Owned::new(0u64).with_tag(2));
1568
    /// let guard = &epoch::pin();
1569
    /// let p = a.load(SeqCst, guard);
1570
    /// assert_eq!(p.tag(), 2);
1571
    /// # unsafe { drop(a.into_owned()); } // avoid leak
1572
    /// ```
1573
0
    pub fn tag(&self) -> usize {
1574
0
        let (_, tag) = decompose_tag::<T>(self.data);
1575
0
        tag
1576
0
    }
1577
1578
    /// Returns the same pointer, but tagged with `tag`. `tag` is truncated to be fit into the
1579
    /// unused bits of the pointer to `T`.
1580
    ///
1581
    /// # Examples
1582
    ///
1583
    /// ```
1584
    /// use crossbeam_epoch::{self as epoch, Atomic};
1585
    /// use std::sync::atomic::Ordering::SeqCst;
1586
    ///
1587
    /// let a = Atomic::new(0u64);
1588
    /// let guard = &epoch::pin();
1589
    /// let p1 = a.load(SeqCst, guard);
1590
    /// let p2 = p1.with_tag(2);
1591
    ///
1592
    /// assert_eq!(p1.tag(), 0);
1593
    /// assert_eq!(p2.tag(), 2);
1594
    /// assert_eq!(p1.as_raw(), p2.as_raw());
1595
    /// # unsafe { drop(a.into_owned()); } // avoid leak
1596
    /// ```
1597
0
    pub fn with_tag(&self, tag: usize) -> Shared<'g, T> {
1598
0
        unsafe { Self::from_usize(compose_tag::<T>(self.data, tag)) }
1599
0
    }
1600
}
1601
1602
impl<T> From<*const T> for Shared<'_, T> {
1603
    /// Returns a new pointer pointing to `raw`.
1604
    ///
1605
    /// # Panics
1606
    ///
1607
    /// Panics if `raw` is not properly aligned.
1608
    ///
1609
    /// # Examples
1610
    ///
1611
    /// ```
1612
    /// use crossbeam_epoch::Shared;
1613
    ///
1614
    /// let p = Shared::from(Box::into_raw(Box::new(1234)) as *const _);
1615
    /// assert!(!p.is_null());
1616
    /// # unsafe { drop(p.into_owned()); } // avoid leak
1617
    /// ```
1618
0
    fn from(raw: *const T) -> Self {
1619
0
        let raw = raw as usize;
1620
0
        ensure_aligned::<T>(raw);
1621
0
        unsafe { Self::from_usize(raw) }
1622
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_epoch::internal::Local> as core::convert::From<*const crossbeam_epoch::internal::Local>>::from
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_epoch::sync::list::Entry> as core::convert::From<*const crossbeam_epoch::sync::list::Entry>>::from
1623
}
1624
1625
impl<'g, T: ?Sized + Pointable> PartialEq<Shared<'g, T>> for Shared<'g, T> {
1626
0
    fn eq(&self, other: &Self) -> bool {
1627
0
        self.data == other.data
1628
0
    }
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_deque::deque::Buffer<rayon_core::job::JobRef>> as core::cmp::PartialEq>::eq
Unexecuted instantiation: <crossbeam_epoch::atomic::Shared<crossbeam_epoch::sync::queue::Node<crossbeam_epoch::internal::SealedBag>> as core::cmp::PartialEq>::eq
1629
}
1630
1631
impl<T: ?Sized + Pointable> Eq for Shared<'_, T> {}
1632
1633
impl<'g, T: ?Sized + Pointable> PartialOrd<Shared<'g, T>> for Shared<'g, T> {
1634
0
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
1635
0
        self.data.partial_cmp(&other.data)
1636
0
    }
1637
}
1638
1639
impl<T: ?Sized + Pointable> Ord for Shared<'_, T> {
1640
0
    fn cmp(&self, other: &Self) -> cmp::Ordering {
1641
0
        self.data.cmp(&other.data)
1642
0
    }
1643
}
1644
1645
impl<T: ?Sized + Pointable> fmt::Debug for Shared<'_, T> {
1646
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1647
0
        let (raw, tag) = decompose_tag::<T>(self.data);
1648
1649
0
        f.debug_struct("Shared")
1650
0
            .field("raw", &raw)
1651
0
            .field("tag", &tag)
1652
0
            .finish()
1653
0
    }
1654
}
1655
1656
impl<T: ?Sized + Pointable> fmt::Pointer for Shared<'_, T> {
1657
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1658
0
        let (raw, _) = decompose_tag::<T>(self.data);
1659
0
        fmt::Pointer::fmt(&(raw as *const ()), f)
1660
0
    }
1661
}
1662
1663
impl<T: ?Sized + Pointable> Default for Shared<'_, T> {
1664
0
    fn default() -> Self {
1665
0
        Shared::null()
1666
0
    }
1667
}
1668
1669
#[cfg(all(test, not(crossbeam_loom)))]
1670
mod tests {
1671
    use super::{Atomic, Owned, Shared};
1672
    use std::{format, mem::MaybeUninit};
1673
1674
    #[test]
1675
    fn valid_tag_i8() {
1676
        Shared::<i8>::null().with_tag(0);
1677
    }
1678
1679
    #[test]
1680
    fn valid_tag_i64() {
1681
        Shared::<i64>::null().with_tag(7);
1682
    }
1683
1684
    #[test]
1685
    fn const_null() {
1686
        use super::{Atomic, Shared};
1687
        static _A: Atomic<u8> = Atomic::<u8>::null();
1688
        static _S: () = {
1689
            let _shared = Shared::<u8>::null();
1690
        };
1691
    }
1692
1693
    #[test]
1694
    fn array_init() {
1695
        let mut owned = Owned::<[MaybeUninit<usize>]>::init(10);
1696
        let arr: &mut [MaybeUninit<usize>] = &mut owned;
1697
        arr[arr.len() - 1].write(20);
1698
        assert_eq!(arr.len(), 10);
1699
    }
1700
1701
    #[test]
1702
    fn format_null() {
1703
        let atomic = Atomic::<usize>::null();
1704
        assert_eq!(format!("{atomic:p}"), "0x0");
1705
        let atomic = Atomic::<[MaybeUninit<usize>]>::null();
1706
        assert_eq!(format!("{atomic:p}"), "0x0");
1707
1708
        let shared = Shared::<usize>::null();
1709
        assert_eq!(format!("{shared:p}"), "0x0");
1710
        let shared = Shared::<[MaybeUninit<usize>]>::null();
1711
        assert_eq!(format!("{shared:p}"), "0x0");
1712
    }
1713
}