/// Returns a bitmask containing the unused least significant bits of an aligned pointer to `T`. #[inline] fnlow_bits<T: ?Sized + Pointable>() ->usize { (1 << T::ALIGN.trailing_zeros()) - 1 }
/// Panics if the pointer is not properly unaligned. #[inline] fnensure_aligned<T: ?Sized + Pointable>(raw: *mut ()) { assert_eq!(raw asusize & low_bits::<T>(), 0, "unaligned pointer"); }
/// Given a tagged pointer `data`, returns the same pointer, but tagged with `tag`. /// /// `tag` is truncated to fit into the unused bits of the pointer to `T`. #[inline] fncompose_tag<T: ?Sized + Pointable>(ptr: *mut (), tag: usize) -> *mut () { (ptr asusize & !low_bits::<T>()) | (tag & low_bits::<T>()) }
/// Decomposes a tagged pointer `data` into the pointer and the tag. #[inline] fndecompose_tag<T: ?Sized + Pointable>(ptr: *mut ()) -> (*mut (), usize) { (ptr asusize & !low_bits::<T>(), ptr asusize & low_bits::<T>()) }
low_bits 函数返回一个位掩码,用来表示指向类型 T 的对齐指针的对齐位。例如 low_bits::<i32>() 会返回 b011,表示有两个比特位没有使用,这两个比特位就可以存储 tag。
ensure_aligned 函数判断 raw(不带 tag) 指针是否对齐,它将 low_bits::<T>() 的结果与 raw 做与运算,如果等于0,则说明 raw 指针是对齐的,反之说明没有对齐。
compose_tag 函数将 tag 保存到 ptr 指针中,通过 ptr as usize & !low_bits::<T>() 将 ptr 的对齐位清零。通过tag & low_bits::<T>() 把 tag 写到对齐位中,如果 tag 过大,则会被截断,因为 low_bits::<T>() 返回的结果除了对齐位其他的比特位都为0。将上述的两个位运算的结果再做一个或运算,就可以把 tag 写到 ptr 的对齐位中了。
decompose_tag 函数将 ptr 指针拆分成没有 tag 的 raw 指针和 tag 值。内部的操作与 compose_tag 类似。
pubtraitPointable { /// The alignment of pointer. const ALIGN: usize;
/// The type for initializers. typeInit;
/// Initializes a with the given initializer. /// /// # Safety /// /// The result should be a multiple of `ALIGN`. unsafefninit(init: Self::Init) -> *mut ();
/// Dereferences the given pointer. /// /// # Safety /// /// - The given `ptr` should have been initialized with [`Pointable::init`]. /// - `ptr` should not have yet been dropped by [`Pointable::drop`]. /// - `ptr` should not be mutably dereferenced by [`Pointable::deref_mut`] concurrently. unsafefnderef<'a>(ptr: *mut ()) -> &'aSelf;
/// Mutably dereferences the given pointer. /// /// # Safety /// /// - The given `ptr` should have been initialized with [`Pointable::init`]. /// - `ptr` should not have yet been dropped by [`Pointable::drop`]. /// - `ptr` should not be dereferenced by [`Pointable::deref`] or [`Pointable::deref_mut`] /// concurrently. unsafefnderef_mut<'a>(ptr: *mut ()) -> &'amutSelf;
/// Drops the object pointed to by the given pointer. /// /// # Safety /// /// - The given `ptr` should have been initialized with [`Pointable::init`]. /// - `ptr` should not have yet been dropped by [`Pointable::drop`]. /// - `ptr` should not be dereferenced by [`Pointable::deref`] or [`Pointable::deref_mut`] /// concurrently. unsafefndrop(ptr: *mut ()); }
/// Array with size. /// /// # Memory layout /// /// An array consisting of size and elements: /// /// ```text /// elements /// | /// | /// ------------------------------------ /// | size | 0 | 1 | 2 | 3 | 4 | 5 | 6 | /// ------------------------------------ /// ``` /// /// Its memory layout is different from that of `Box<[T]>` in that size is in the allocation (not /// along with pointer as in `Box<[T]>`). /// /// Elements are not present in the type, but they will be in the allocation. /// ``` #[repr(C)] structArray<T> { /// The number of elements (not the number of bytes). len: usize, elements: [MaybeUninit<T>; 0], }
impl<T> Pointable for [MaybeUninit<T>] { const ALIGN: usize = mem::align_of::<Array<T>>();
/// An atomic pointer that can be safely shared between threads. /// /// The pointer must be properly aligned. Since it is aligned, a tag can be stored into the unused /// least significant bits of the address. For example, the tag for a pointer to a sized type `T` /// should be less than `(1 << mem::align_of::<T>().trailing_zeros())`. /// /// Any method that loads the pointer must be passed a reference to a [`Guard`]. /// /// Crossbeam supports dynamically sized types. See [`Pointable`] for details. pubstructAtomic<T: ?Sized + Pointable> { data: AtomicPtr<()>, _marker: PhantomData<*mut T>, }
/// An owned heap-allocated object. /// /// This type is very similar to `Box<T>`. /// /// The pointer must be properly aligned. Since it is aligned, a tag can be stored into the unused /// least significant bits of the address. pubstructOwned<T: ?Sized + Pointable> { data: *mut (), _marker: PhantomData<Box<T>>, }
/// A pointer to an object protected by the epoch GC. /// /// The pointer is valid for use only during the lifetime `'g`. /// /// The pointer must be properly aligned. Since it is aligned, a tag can be stored into the unused /// least significant bits of the address. pubstructShared<'g, T: 'g + ?Sized + Pointable> { data: *mut (), _marker: PhantomData<(&'g (), *const T)>, }