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    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        pub const fn null() -> Atomic<T> {
352            Self {
353                data: AtomicUsize::new(0),
354                _marker: PhantomData,
355            }
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    pub fn load<'g>(&self, ord: Ordering, _: &'g Guard) -> Shared<'g, T> {
376        unsafe { Shared::from_usize(self.data.load(ord)) }
377    }
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    pub fn load_consume<'g>(&self, _: &'g Guard) -> Shared<'g, T> {
402        unsafe { Shared::from_usize(self.data.load_consume()) }
403    }
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    pub fn store<P: Pointer<T>>(&self, new: P, ord: Ordering) {
423        self.data.store(new.into_usize(), ord);
424    }
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    pub fn swap<'g, P: Pointer<T>>(&self, new: P, ord: Ordering, _: &'g Guard) -> Shared<'g, T> {
444        unsafe { Shared::from_usize(self.data.swap(new.into_usize(), ord)) }
445    }
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    pub fn compare_exchange<'g, P>(
479        &self,
480        current: Shared<'_, T>,
481        new: P,
482        success: Ordering,
483        failure: Ordering,
484        _: &'g Guard,
485    ) -> Result<Shared<'g, T>, CompareExchangeError<'g, T, P>>
486    where
487        P: Pointer<T>,
488    {
489        let new = new.into_usize();
490        self.data
491            .compare_exchange(current.into_usize(), new, success, failure)
492            .map(|_| unsafe { Shared::from_usize(new) })
493            .map_err(|current| unsafe {
494                CompareExchangeError {
495                    current: Shared::from_usize(current),
496                    new: P::from_usize(new),
497                }
498            })
499    }
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    pub fn compare_exchange_weak<'g, P>(
556        &self,
557        current: Shared<'_, T>,
558        new: P,
559        success: Ordering,
560        failure: Ordering,
561        _: &'g Guard,
562    ) -> Result<Shared<'g, T>, CompareExchangeError<'g, T, P>>
563    where
564        P: Pointer<T>,
565    {
566        let new = new.into_usize();
567        self.data
568            .compare_exchange_weak(current.into_usize(), new, success, failure)
569            .map(|_| unsafe { Shared::from_usize(new) })
570            .map_err(|current| unsafe {
571                CompareExchangeError {
572                    current: Shared::from_usize(current),
573                    new: P::from_usize(new),
574                }
575            })
576    }
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    pub fn fetch_update<'g, F>(
619        &self,
620        set_order: Ordering,
621        fail_order: Ordering,
622        guard: &'g Guard,
623        mut func: F,
624    ) -> Result<Shared<'g, T>, Shared<'g, T>>
625    where
626        F: FnMut(Shared<'g, T>) -> Option<Shared<'g, T>>,
627    {
628        let mut prev = self.load(fail_order, guard);
629        while let Some(next) = func(prev) {
630            match self.compare_exchange_weak(prev, next, set_order, fail_order, guard) {
631                Ok(_result) => return Ok(prev),
632                Err(next_prev) => prev = next_prev.current,
633            }
634        }
635        Err(prev)
636    }
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    pub fn compare_and_set<'g, O, P>(
681        &self,
682        current: Shared<'_, T>,
683        new: P,
684        ord: O,
685        guard: &'g Guard,
686    ) -> Result<Shared<'g, T>, CompareAndSetError<'g, T, P>>
687    where
688        O: CompareAndSetOrdering,
689        P: Pointer<T>,
690    {
691        self.compare_exchange(current, new, ord.success(), ord.failure(), guard)
692    }
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    pub fn compare_and_set_weak<'g, O, P>(
760        &self,
761        current: Shared<'_, T>,
762        new: P,
763        ord: O,
764        guard: &'g Guard,
765    ) -> Result<Shared<'g, T>, CompareAndSetError<'g, T, P>>
766    where
767        O: CompareAndSetOrdering,
768        P: Pointer<T>,
769    {
770        self.compare_exchange_weak(current, new, ord.success(), ord.failure(), guard)
771    }
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    pub fn fetch_and<'g>(&self, val: usize, ord: Ordering, _: &'g Guard) -> Shared<'g, T> {
793        unsafe { Shared::from_usize(self.data.fetch_and(val | !low_bits::<T>(), ord)) }
794    }
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    pub fn fetch_or<'g>(&self, val: usize, ord: Ordering, _: &'g Guard) -> Shared<'g, T> {
816        unsafe { Shared::from_usize(self.data.fetch_or(val & low_bits::<T>(), ord)) }
817    }
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    pub fn fetch_xor<'g>(&self, val: usize, ord: Ordering, _: &'g Guard) -> Shared<'g, T> {
839        unsafe { Shared::from_usize(self.data.fetch_xor(val & low_bits::<T>(), ord)) }
840    }
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    pub unsafe fn into_owned(self) -> Owned<T> {
877        Owned::from_usize(self.data.into_inner())
878    }
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    pub unsafe fn try_into_owned(self) -> Option<Owned<T>> {
914        let data = self.data.into_inner();
915        if decompose_tag::<T>(data).0 == 0 {
916            None
917        } else {
918            Some(Owned::from_usize(data))
919        }
920    }
921}
922
923impl<T: ?Sized + Pointable> fmt::Debug for Atomic<T> {
924    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
925        let data = self.data.load(Ordering::SeqCst);
926        let (raw, tag) = decompose_tag::<T>(data);
927
928        f.debug_struct("Atomic")
929            .field("raw", &raw)
930            .field("tag", &tag)
931            .finish()
932    }
933}
934
935impl<T: ?Sized + Pointable> fmt::Pointer for Atomic<T> {
936    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
937        let data = self.data.load(Ordering::SeqCst);
938        let (raw, _) = decompose_tag::<T>(data);
939        fmt::Pointer::fmt(&(raw as *const ()), f)
940    }
941}
942
943impl<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    fn clone(&self) -> Self {
949        let data = self.data.load(Ordering::Relaxed);
950        Atomic::from_usize(data)
951    }
952}
953
954impl<T: ?Sized + Pointable> Default for Atomic<T> {
955    fn default() -> Self {
956        Atomic::null()
957    }
958}
959
960impl<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    fn from(owned: Owned<T>) -> Self {
972        let data = owned.data;
973        mem::forget(owned);
974        Self::from_usize(data)
975    }
976}
977
978impl<T> From<Box<T>> for Atomic<T> {
979    fn from(b: Box<T>) -> Self {
980        Self::from(Owned::from(b))
981    }
982}
983
984impl<T> From<T> for Atomic<T> {
985    fn from(t: T) -> Self {
986        Self::new(t)
987    }
988}
989
990impl<'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    fn from(ptr: Shared<'g, T>) -> Self {
1001        Self::from_usize(ptr.data)
1002    }
1003}
1004
1005impl<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    fn from(raw: *const T) -> Self {
1017        Self::from_usize(raw as usize)
1018    }
1019}
1020
1021/// A trait for either `Owned` or `Shared` pointers.
1022pub 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.
1041pub struct Owned<T: ?Sized + Pointable> {
1042    data: usize,
1043    _marker: PhantomData<Box<T>>,
1044}
1045
1046impl<T: ?Sized + Pointable> Pointer<T> for Owned<T> {
1047    #[inline]
1048    fn into_usize(self) -> usize {
1049        let data = self.data;
1050        mem::forget(self);
1051        data
1052    }
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    unsafe fn from_usize(data: usize) -> Self {
1061        debug_assert!(data != 0, "converting zero into `Owned`");
1062        Owned {
1063            data,
1064            _marker: PhantomData,
1065        }
1066    }
1067}
1068
1069impl<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    pub unsafe fn from_raw(raw: *mut T) -> Owned<T> {
1093        let raw = raw as usize;
1094        ensure_aligned::<T>(raw);
1095        Self::from_usize(raw)
1096    }
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    pub fn into_box(self) -> Box<T> {
1110        let (raw, _) = decompose_tag::<T>(self.data);
1111        mem::forget(self);
1112        unsafe { Box::from_raw(raw as *mut _) }
1113    }
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    pub fn new(init: T) -> Owned<T> {
1125        Self::init(init)
1126    }
1127}
1128
1129impl<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    pub fn init(init: T::Init) -> Owned<T> {
1140        unsafe { Self::from_usize(T::init(init)) }
1141    }
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    pub fn into_shared<'g>(self, _: &'g Guard) -> Shared<'g, T> {
1157        unsafe { Shared::from_usize(self.into_usize()) }
1158    }
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    pub fn tag(&self) -> usize {
1170        let (_, tag) = decompose_tag::<T>(self.data);
1171        tag
1172    }
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    pub fn with_tag(self, tag: usize) -> Owned<T> {
1188        let data = self.into_usize();
1189        unsafe { Self::from_usize(compose_tag::<T>(data, tag)) }
1190    }
1191}
1192
1193impl<T: ?Sized + Pointable> Drop for Owned<T> {
1194    fn drop(&mut self) {
1195        let (raw, _) = decompose_tag::<T>(self.data);
1196        unsafe {
1197            T::drop(raw);
1198        }
1199    }
1200}
1201
1202impl<T: ?Sized + Pointable> fmt::Debug for Owned<T> {
1203    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1204        let (raw, tag) = decompose_tag::<T>(self.data);
1205
1206        f.debug_struct("Owned")
1207            .field("raw", &raw)
1208            .field("tag", &tag)
1209            .finish()
1210    }
1211}
1212
1213impl<T: Clone> Clone for Owned<T> {
1214    fn clone(&self) -> Self {
1215        Owned::new((**self).clone()).with_tag(self.tag())
1216    }
1217}
1218
1219impl<T: ?Sized + Pointable> Deref for Owned<T> {
1220    type Target = T;
1221
1222    fn deref(&self) -> &T {
1223        let (raw, _) = decompose_tag::<T>(self.data);
1224        unsafe { T::deref(raw) }
1225    }
1226}
1227
1228impl<T: ?Sized + Pointable> DerefMut for Owned<T> {
1229    fn deref_mut(&mut self) -> &mut T {
1230        let (raw, _) = decompose_tag::<T>(self.data);
1231        unsafe { T::deref_mut(raw) }
1232    }
1233}
1234
1235impl<T> From<T> for Owned<T> {
1236    fn from(t: T) -> Self {
1237        Owned::new(t)
1238    }
1239}
1240
1241impl<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    fn from(b: Box<T>) -> Self {
1256        unsafe { Self::from_raw(Box::into_raw(b)) }
1257    }
1258}
1259
1260impl<T: ?Sized + Pointable> Borrow<T> for Owned<T> {
1261    fn borrow(&self) -> &T {
1262        self.deref()
1263    }
1264}
1265
1266impl<T: ?Sized + Pointable> BorrowMut<T> for Owned<T> {
1267    fn borrow_mut(&mut self) -> &mut T {
1268        self.deref_mut()
1269    }
1270}
1271
1272impl<T: ?Sized + Pointable> AsRef<T> for Owned<T> {
1273    fn as_ref(&self) -> &T {
1274        self.deref()
1275    }
1276}
1277
1278impl<T: ?Sized + Pointable> AsMut<T> for Owned<T> {
1279    fn as_mut(&mut self) -> &mut T {
1280        self.deref_mut()
1281    }
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.
1290pub struct Shared<'g, T: 'g + ?Sized + Pointable> {
1291    data: usize,
1292    _marker: PhantomData<(&'g (), *const T)>,
1293}
1294
1295impl<T: ?Sized + Pointable> Clone for Shared<'_, T> {
1296    fn clone(&self) -> Self {
1297        *self
1298    }
1299}
1300
1301impl<T: ?Sized + Pointable> Copy for Shared<'_, T> {}
1302
1303impl<T: ?Sized + Pointable> Pointer<T> for Shared<'_, T> {
1304    #[inline]
1305    fn into_usize(self) -> usize {
1306        self.data
1307    }
1308
1309    #[inline]
1310    unsafe fn from_usize(data: usize) -> Self {
1311        Shared {
1312            data,
1313            _marker: PhantomData,
1314        }
1315    }
1316}
1317
1318impl<'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    pub fn as_raw(&self) -> *const T {
1337        let (raw, _) = decompose_tag::<T>(self.data);
1338        raw as *const _
1339    }
1340}
1341
1342impl<'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    pub const fn null() -> Shared<'g, T> {
1354        Shared {
1355            data: 0,
1356            _marker: PhantomData,
1357        }
1358    }
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    pub fn is_null(&self) -> bool {
1376        let (raw, _) = decompose_tag::<T>(self.data);
1377        raw == 0
1378    }
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    pub unsafe fn deref(&self) -> &'g T {
1413        let (raw, _) = decompose_tag::<T>(self.data);
1414        T::deref(raw)
1415    }
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    pub unsafe fn deref_mut(&mut self) -> &'g mut T {
1455        let (raw, _) = decompose_tag::<T>(self.data);
1456        T::deref_mut(raw)
1457    }
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    pub unsafe fn as_ref(&self) -> Option<&'g T> {
1492        let (raw, _) = decompose_tag::<T>(self.data);
1493        if raw == 0 {
1494            None
1495        } else {
1496            Some(T::deref(raw))
1497        }
1498    }
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    pub unsafe fn into_owned(self) -> Owned<T> {
1525        debug_assert!(!self.is_null(), "converting a null `Shared` into `Owned`");
1526        Owned::from_usize(self.data)
1527    }
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    pub unsafe fn try_into_owned(self) -> Option<Owned<T>> {
1552        if self.is_null() {
1553            None
1554        } else {
1555            Some(Owned::from_usize(self.data))
1556        }
1557    }
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    pub fn tag(&self) -> usize {
1574        let (_, tag) = decompose_tag::<T>(self.data);
1575        tag
1576    }
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    pub fn with_tag(&self, tag: usize) -> Shared<'g, T> {
1598        unsafe { Self::from_usize(compose_tag::<T>(self.data, tag)) }
1599    }
1600}
1601
1602impl<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    fn from(raw: *const T) -> Self {
1619        let raw = raw as usize;
1620        ensure_aligned::<T>(raw);
1621        unsafe { Self::from_usize(raw) }
1622    }
1623}
1624
1625impl<'g, T: ?Sized + Pointable> PartialEq<Shared<'g, T>> for Shared<'g, T> {
1626    fn eq(&self, other: &Self) -> bool {
1627        self.data == other.data
1628    }
1629}
1630
1631impl<T: ?Sized + Pointable> Eq for Shared<'_, T> {}
1632
1633impl<'g, T: ?Sized + Pointable> PartialOrd<Shared<'g, T>> for Shared<'g, T> {
1634    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
1635        self.data.partial_cmp(&other.data)
1636    }
1637}
1638
1639impl<T: ?Sized + Pointable> Ord for Shared<'_, T> {
1640    fn cmp(&self, other: &Self) -> cmp::Ordering {
1641        self.data.cmp(&other.data)
1642    }
1643}
1644
1645impl<T: ?Sized + Pointable> fmt::Debug for Shared<'_, T> {
1646    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1647        let (raw, tag) = decompose_tag::<T>(self.data);
1648
1649        f.debug_struct("Shared")
1650            .field("raw", &raw)
1651            .field("tag", &tag)
1652            .finish()
1653    }
1654}
1655
1656impl<T: ?Sized + Pointable> fmt::Pointer for Shared<'_, T> {
1657    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1658        let (raw, _) = decompose_tag::<T>(self.data);
1659        fmt::Pointer::fmt(&(raw as *const ()), f)
1660    }
1661}
1662
1663impl<T: ?Sized + Pointable> Default for Shared<'_, T> {
1664    fn default() -> Self {
1665        Shared::null()
1666    }
1667}
1668
1669#[cfg(all(test, not(crossbeam_loom)))]
1670mod 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}