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