Skip to content

Commit f4a8f41

Browse files
committed
Store pointer bytes in pointers
1 parent 30e562c commit f4a8f41

File tree

2 files changed

+32
-26
lines changed

2 files changed

+32
-26
lines changed

src/native/arc_list.rs

+18-12
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33
use std::marker;
44
use std::ops::Deref;
55
use std::sync::atomic::Ordering::SeqCst;
6-
use std::sync::atomic::{AtomicBool, AtomicUsize};
6+
use std::sync::atomic::{AtomicBool, AtomicPtr};
77
use std::sync::Arc;
88

99
pub struct ArcList<T> {
10-
list: AtomicUsize,
10+
list: AtomicPtr<Node<T>>,
1111
_marker: marker::PhantomData<T>,
1212
}
1313

1414
impl<T> ArcList<T> {
1515
pub fn new() -> ArcList<T> {
1616
ArcList {
17-
list: AtomicUsize::new(0),
17+
list: AtomicPtr::new(Node::EMPTY),
1818
_marker: marker::PhantomData,
1919
}
2020
}
@@ -31,10 +31,10 @@ impl<T> ArcList<T> {
3131
return Ok(());
3232
}
3333
let mut head = self.list.load(SeqCst);
34-
let node = Arc::into_raw(data.clone()) as usize;
34+
let node = Arc::into_raw(data.clone()) as *mut Node<T>;
3535
loop {
3636
// If we've been sealed off, abort and return an error
37-
if head == 1 {
37+
if head == Node::sealed() {
3838
unsafe {
3939
drop(Arc::from_raw(node as *mut Node<T>));
4040
}
@@ -55,16 +55,16 @@ impl<T> ArcList<T> {
5555
pub fn take(&self) -> ArcList<T> {
5656
let mut list = self.list.load(SeqCst);
5757
loop {
58-
if list == 1 {
58+
if list == Node::sealed() {
5959
break;
6060
}
61-
match self.list.compare_exchange(list, 0, SeqCst, SeqCst) {
61+
match self.list.compare_exchange(list, Node::EMPTY, SeqCst, SeqCst) {
6262
Ok(_) => break,
6363
Err(l) => list = l,
6464
}
6565
}
6666
ArcList {
67-
list: AtomicUsize::new(list),
67+
list: AtomicPtr::new(list),
6868
_marker: marker::PhantomData,
6969
}
7070
}
@@ -73,7 +73,7 @@ impl<T> ArcList<T> {
7373
/// `push`.
7474
pub fn take_and_seal(&self) -> ArcList<T> {
7575
ArcList {
76-
list: AtomicUsize::new(self.list.swap(1, SeqCst)),
76+
list: AtomicPtr::new(self.list.swap(Node::sealed(), SeqCst)),
7777
_marker: marker::PhantomData,
7878
}
7979
}
@@ -82,7 +82,7 @@ impl<T> ArcList<T> {
8282
/// empty list.
8383
pub fn pop(&mut self) -> Option<Arc<Node<T>>> {
8484
let head = *self.list.get_mut();
85-
if head == 0 || head == 1 {
85+
if head == Node::EMPTY || head == Node::sealed() {
8686
return None;
8787
}
8888
let head = unsafe { Arc::from_raw(head as *const Node<T>) };
@@ -103,15 +103,21 @@ impl<T> Drop for ArcList<T> {
103103
}
104104

105105
pub struct Node<T> {
106-
next: AtomicUsize,
106+
next: AtomicPtr<Node<T>>,
107107
enqueued: AtomicBool,
108108
data: T,
109109
}
110110

111111
impl<T> Node<T> {
112+
const EMPTY: *mut Node<T> = std::ptr::null_mut();
113+
114+
const fn sealed() -> *mut Node<T> {
115+
std::ptr::null_mut::<Node<T>>().wrapping_add(1)
116+
}
117+
112118
pub fn new(data: T) -> Node<T> {
113119
Node {
114-
next: AtomicUsize::new(0),
120+
next: AtomicPtr::new(Node::EMPTY),
115121
enqueued: AtomicBool::new(false),
116122
data,
117123
}

src/native/timer.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use std::fmt;
2-
use std::mem;
32
use std::pin::Pin;
4-
use std::sync::atomic::AtomicUsize;
3+
use std::sync::atomic::{AtomicUsize, AtomicPtr};
54
use std::sync::atomic::Ordering::SeqCst;
65
use std::sync::{Arc, Mutex, Weak};
76
use std::task::{Context, Poll};
@@ -216,7 +215,8 @@ impl Default for Timer {
216215
}
217216
}
218217

219-
static HANDLE_FALLBACK: AtomicUsize = AtomicUsize::new(0);
218+
static HANDLE_FALLBACK: AtomicPtr<Inner> = AtomicPtr::new(EMPTY_HANDLE);
219+
const EMPTY_HANDLE: *mut Inner = std::ptr::null_mut();
220220

221221
/// Error returned from `TimerHandle::set_fallback`.
222222
#[derive(Clone, Debug)]
@@ -247,23 +247,23 @@ impl TimerHandle {
247247
/// successful then no future calls may succeed.
248248
fn set_as_global_fallback(self) -> Result<(), SetDefaultError> {
249249
unsafe {
250-
let val = self.into_usize();
251-
match HANDLE_FALLBACK.compare_exchange(0, val, SeqCst, SeqCst) {
250+
let val = self.into_raw();
251+
match HANDLE_FALLBACK.compare_exchange(EMPTY_HANDLE, val, SeqCst, SeqCst) {
252252
Ok(_) => Ok(()),
253253
Err(_) => {
254-
drop(TimerHandle::from_usize(val));
254+
drop(TimerHandle::from_raw(val));
255255
Err(SetDefaultError(()))
256256
}
257257
}
258258
}
259259
}
260260

261-
fn into_usize(self) -> usize {
262-
unsafe { mem::transmute::<Weak<Inner>, usize>(self.inner) }
261+
fn into_raw(self) -> *mut Inner {
262+
self.inner.into_raw() as *mut Inner
263263
}
264264

265-
unsafe fn from_usize(val: usize) -> TimerHandle {
266-
let inner = mem::transmute::<usize, Weak<Inner>>(val);
265+
unsafe fn from_raw(val: *mut Inner) -> TimerHandle {
266+
let inner = Weak::from_raw(val);
267267
TimerHandle { inner }
268268
}
269269
}
@@ -277,7 +277,7 @@ impl Default for TimerHandle {
277277
// actually create a helper thread then we'll just return a "defunkt"
278278
// handle which will return errors when timer objects are attempted to
279279
// be associated.
280-
if fallback == 0 {
280+
if fallback == EMPTY_HANDLE {
281281
let helper = match global::HelperThread::new() {
282282
Ok(helper) => helper,
283283
Err(_) => return TimerHandle { inner: Weak::new() },
@@ -301,11 +301,11 @@ impl Default for TimerHandle {
301301
// At this point our fallback handle global was configured so we use
302302
// its value to reify a handle, clone it, and then forget our reified
303303
// handle as we don't actually have an owning reference to it.
304-
assert!(fallback != 0);
304+
assert!(fallback != EMPTY_HANDLE);
305305
unsafe {
306-
let handle = TimerHandle::from_usize(fallback);
306+
let handle = TimerHandle::from_raw(fallback);
307307
let ret = handle.clone();
308-
let _ = handle.into_usize();
308+
let _ = handle.into_raw();
309309
ret
310310
}
311311
}

0 commit comments

Comments
 (0)