Skip to content

Commit 9563b35

Browse files
authored
Merge pull request #234 from japaric/pool-nonzero-tag
CAS (x86*) Pool: make the tag NonZeroU32
2 parents f76a8bd + 9de6055 commit 9563b35

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

src/pool/cas.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
use core::{
77
cell::UnsafeCell,
88
marker::PhantomData,
9-
num::NonZeroU64,
9+
num::{NonZeroU32, NonZeroU64},
1010
ptr::NonNull,
1111
sync::atomic::{AtomicU64, Ordering},
1212
};
@@ -107,24 +107,28 @@ impl<T> Clone for Ptr<T> {
107107

108108
impl<T> Copy for Ptr<T> {}
109109

110+
fn initial_tag_value() -> NonZeroU32 {
111+
NonZeroU32::new(1).unwrap()
112+
}
113+
110114
impl<T> Ptr<T> {
111115
#[cfg(target_arch = "x86_64")]
112116
pub fn new(p: *mut T) -> Option<Self> {
113117
use core::convert::TryFrom;
114118

115119
i32::try_from((p as isize).wrapping_sub(anchor::<T>() as isize))
116120
.ok()
117-
.map(|offset| unsafe { Ptr::from_parts(0, offset) })
121+
.map(|offset| unsafe { Ptr::from_parts(initial_tag_value(), offset) })
118122
}
119123

120124
#[cfg(target_arch = "x86")]
121125
pub fn new(p: *mut T) -> Option<Self> {
122-
Some(unsafe { Ptr::from_parts(0, p as i32) })
126+
Some(unsafe { Ptr::from_parts(initial_tag_value(), p as i32) })
123127
}
124128

125-
unsafe fn from_parts(tag: u32, offset: i32) -> Self {
129+
unsafe fn from_parts(tag: NonZeroU32, offset: i32) -> Self {
126130
Self {
127-
inner: NonZeroU64::new_unchecked((tag as u64) << 32 | (offset as u32 as u64)),
131+
inner: NonZeroU64::new_unchecked((tag.get() as u64) << 32 | (offset as u32 as u64)),
128132
_marker: PhantomData,
129133
}
130134
}
@@ -140,12 +144,15 @@ impl<T> Ptr<T> {
140144
self.inner.get()
141145
}
142146

143-
fn tag(&self) -> u32 {
144-
(self.inner.get() >> 32) as u32
147+
fn tag(&self) -> NonZeroU32 {
148+
let tag = (self.inner.get() >> 32) as u32;
149+
debug_assert_ne!(0, tag, "broken non-zero invariant");
150+
unsafe { NonZeroU32::new_unchecked(tag) }
145151
}
146152

147153
fn incr_tag(&mut self) {
148-
let tag = self.tag().wrapping_add(1);
154+
let maybe_zero_tag = self.tag().get().wrapping_add(1);
155+
let tag = NonZeroU32::new(maybe_zero_tag).unwrap_or(initial_tag_value());
149156
let offset = self.offset();
150157

151158
*self = unsafe { Ptr::from_parts(tag, offset) };
@@ -170,7 +177,7 @@ impl<T> Ptr<T> {
170177
}
171178

172179
pub fn dangling() -> Self {
173-
unsafe { Self::from_parts(0, 1) }
180+
unsafe { Self::from_parts(initial_tag_value(), 1) }
174181
}
175182

176183
pub unsafe fn as_ref(&self) -> &T {

0 commit comments

Comments
 (0)