Skip to main content

crossbeam_epoch/
atomic.rs

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