Merge pull request #234 from japaric/pool-nonzero-tag

CAS (x86*) Pool: make the tag NonZeroU32
This commit is contained in:
Emil Fresk 2021-08-26 13:01:55 +02:00 committed by GitHub
commit 9563b3546c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -6,7 +6,7 @@
use core::{ use core::{
cell::UnsafeCell, cell::UnsafeCell,
marker::PhantomData, marker::PhantomData,
num::NonZeroU64, num::{NonZeroU32, NonZeroU64},
ptr::NonNull, ptr::NonNull,
sync::atomic::{AtomicU64, Ordering}, sync::atomic::{AtomicU64, Ordering},
}; };
@ -107,6 +107,10 @@ impl<T> Clone for Ptr<T> {
impl<T> Copy for Ptr<T> {} impl<T> Copy for Ptr<T> {}
fn initial_tag_value() -> NonZeroU32 {
NonZeroU32::new(1).unwrap()
}
impl<T> Ptr<T> { impl<T> Ptr<T> {
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
pub fn new(p: *mut T) -> Option<Self> { pub fn new(p: *mut T) -> Option<Self> {
@ -114,17 +118,17 @@ impl<T> Ptr<T> {
i32::try_from((p as isize).wrapping_sub(anchor::<T>() as isize)) i32::try_from((p as isize).wrapping_sub(anchor::<T>() as isize))
.ok() .ok()
.map(|offset| unsafe { Ptr::from_parts(0, offset) }) .map(|offset| unsafe { Ptr::from_parts(initial_tag_value(), offset) })
} }
#[cfg(target_arch = "x86")] #[cfg(target_arch = "x86")]
pub fn new(p: *mut T) -> Option<Self> { pub fn new(p: *mut T) -> Option<Self> {
Some(unsafe { Ptr::from_parts(0, p as i32) }) Some(unsafe { Ptr::from_parts(initial_tag_value(), p as i32) })
} }
unsafe fn from_parts(tag: u32, offset: i32) -> Self { unsafe fn from_parts(tag: NonZeroU32, offset: i32) -> Self {
Self { Self {
inner: NonZeroU64::new_unchecked((tag as u64) << 32 | (offset as u32 as u64)), inner: NonZeroU64::new_unchecked((tag.get() as u64) << 32 | (offset as u32 as u64)),
_marker: PhantomData, _marker: PhantomData,
} }
} }
@ -140,12 +144,15 @@ impl<T> Ptr<T> {
self.inner.get() self.inner.get()
} }
fn tag(&self) -> u32 { fn tag(&self) -> NonZeroU32 {
(self.inner.get() >> 32) as u32 let tag = (self.inner.get() >> 32) as u32;
debug_assert_ne!(0, tag, "broken non-zero invariant");
unsafe { NonZeroU32::new_unchecked(tag) }
} }
fn incr_tag(&mut self) { fn incr_tag(&mut self) {
let tag = self.tag().wrapping_add(1); let maybe_zero_tag = self.tag().get().wrapping_add(1);
let tag = NonZeroU32::new(maybe_zero_tag).unwrap_or(initial_tag_value());
let offset = self.offset(); let offset = self.offset();
*self = unsafe { Ptr::from_parts(tag, offset) }; *self = unsafe { Ptr::from_parts(tag, offset) };
@ -170,7 +177,7 @@ impl<T> Ptr<T> {
} }
pub fn dangling() -> Self { pub fn dangling() -> Self {
unsafe { Self::from_parts(0, 1) } unsafe { Self::from_parts(initial_tag_value(), 1) }
} }
pub unsafe fn as_ref(&self) -> &T { pub unsafe fn as_ref(&self) -> &T {