Skip to content

Commit 74db994

Browse files
committed
Use more explecic cfg guard for domain timing
1 parent 3138eff commit 74db994

File tree

6 files changed

+30
-22
lines changed

6 files changed

+30
-22
lines changed

benches/folly.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ folly_bench!(concurrent_new_holder, {
4848
});
4949
folly_bench!(concurrent_retire, {
5050
let foo = Box::into_raw(Box::new(HazPtrObjectWrapper::with_global_domain(0)));
51-
black_box(unsafe { foo.retire(&deleters::drop_box) });
51+
black_box(unsafe { HazPtrObjectWrapper::retire(foo, &deleters::drop_box) });
5252
});
5353

5454
criterion_group!(benches, concurrent_new_holder, concurrent_retire);

src/domain.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,16 @@ use alloc::collections::BTreeSet;
55
use core::marker::PhantomData;
66
use core::sync::atomic::Ordering;
77

8-
#[cfg(all(feature = "std", not(miri)))]
8+
// Like folly's implementation, we use a time a based check to run reclamation about every
9+
// `SYNC_TIME_PERIOD` nanoseconds. The next time we should run reclamation is stored in
10+
// `due_time` inside `Domain`. On `no_std` we don't (yet) have access to time so this feature is
11+
// disabled. Also on platforms with < 64 bits, we can only store 2^32 nanoseconds -> ~4 seconds or
12+
// less, so this feature is also disabled. Additionally, miri can't support time because of
13+
// system calls (perhaps this can be mocked), and loom can't support time for reasons of determinism.
14+
15+
#[cfg(all(feature = "std", target_pointer_width = "64", not(miri), not(loom)))]
916
const SYNC_TIME_PERIOD: u64 = std::time::Duration::from_nanos(2000000000).as_nanos() as u64;
10-
#[cfg(all(feature = "std", not(miri)))]
17+
#[cfg(all(feature = "std", target_pointer_width = "64", not(miri), not(loom)))]
1118
use crate::sync::atomic::AtomicU64;
1219

1320
#[cfg(loom)]
@@ -55,7 +62,7 @@ pub struct Domain<F> {
5562
hazptrs: HazPtrRecords,
5663
untagged: [RetiredList; NUM_SHARDS],
5764
family: PhantomData<F>,
58-
#[cfg(all(feature = "std", not(miri)))]
65+
#[cfg(all(feature = "std", target_pointer_width = "64", not(miri), not(loom)))]
5966
due_time: AtomicU64,
6067
nbulk_reclaims: AtomicUsize,
6168
count: AtomicIsize,
@@ -104,7 +111,7 @@ macro_rules! new {
104111
},
105112
untagged,
106113
count: AtomicIsize::new(0),
107-
#[cfg(all(feature = "std", not(miri)))]
114+
#[cfg(all(feature = "std", target_pointer_width = "64", not(miri), not(loom)))]
108115
due_time: AtomicU64::new(0),
109116
nbulk_reclaims: AtomicUsize::new(0),
110117
family: PhantomData,
@@ -361,7 +368,7 @@ impl<F> Domain<F> {
361368
.compare_exchange_weak(rcount, 0, Ordering::AcqRel, Ordering::Relaxed)
362369
{
363370
Ok(_) => {
364-
#[cfg(all(feature = "std", not(miri)))]
371+
#[cfg(all(feature = "std", target_pointer_width = "64", not(miri), not(loom)))]
365372
{
366373
self.due_time
367374
.store(Self::now() + SYNC_TIME_PERIOD, Ordering::Release);
@@ -374,7 +381,7 @@ impl<F> Domain<F> {
374381
0
375382
}
376383

377-
#[cfg(all(feature = "std", not(miri)))]
384+
#[cfg(all(feature = "std", target_pointer_width = "64", not(miri), not(loom)))]
378385
fn check_due_time(&self) -> isize {
379386
let time = Self::now();
380387
let due = self.due_time.load(Ordering::Acquire);
@@ -402,7 +409,7 @@ impl<F> Domain<F> {
402409
// TODO: Implement some kind of mock time for no_std.
403410
// Currently we reclaim only based on rcount on no_std
404411
// (also the reason for allow unused_mut)
405-
#[cfg(all(feature = "std", not(miri)))]
412+
#[cfg(all(feature = "std", target_pointer_width = "64", not(miri), not(loom)))]
406413
{
407414
rcount = self.check_due_time();
408415
}
@@ -546,7 +553,7 @@ impl<F> Domain<F> {
546553
0
547554
}
548555

549-
#[cfg(all(not(loom), feature = "std"))]
556+
#[cfg(all(feature = "std", target_pointer_width = "64", not(miri), not(loom)))]
550557
fn now() -> u64 {
551558
use std::convert::TryFrom;
552559
u64::try_from(

src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
//#![feature(arbitrary_self_types)]
21
#![deny(unsafe_op_in_unsafe_fn)]
32
#![allow(dead_code)]
43
#![cfg_attr(not(feature = "std"), no_std)]

src/object.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ where
2020
///
2121
/// It is okay for existing readers to still refer to Self.
2222
///
23+
//TODO: Once arbitrary_self_types is stabilized change `this` back to `self`.
24+
//See: https://github.com/rust-lang/rust/issues/44874
2325
unsafe fn retire(this: *mut Self, deleter: &'static dyn Deleter) -> usize {
2426
let ptr = this as *mut (dyn Reclaim + 'domain);
2527
unsafe { (&*this).domain().retire(ptr, deleter) }

tests/folly.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ fn basic_objects() {
6565
num += 1;
6666
let obj = Node::new(count, 0, std::ptr::null_mut());
6767
let x = Box::into_raw(Box::new(HazPtrObjectWrapper::with_domain(&domain, obj)));
68-
unsafe { x.retire(&deleters::drop_box) };
68+
unsafe { HazPtrObjectWrapper::retire(x, &deleters::drop_box) };
6969
}
7070
assert_eq!(num, count.ctors());
7171
domain.cleanup();
@@ -90,7 +90,7 @@ fn basic_protection() {
9090
let obj = Box::into_raw(Box::new(HazPtrObjectWrapper::with_domain(&domain, obj)));
9191
let mut h = HazardPointer::make_in_domain(&domain);
9292
unsafe { h.protect_raw(obj) };
93-
unsafe { obj.retire(&deleters::drop_box) };
93+
unsafe { HazPtrObjectWrapper::retire(obj, &deleters::drop_box) };
9494
assert_eq!(1, count.ctors());
9595
domain.cleanup();
9696
assert_eq!(0, count.dtors());
@@ -113,7 +113,7 @@ fn destruction() {
113113
fn drop(&mut self) {
114114
self.dtors.fetch_add(1, Ordering::AcqRel);
115115
if !self.next.is_null() {
116-
unsafe { self.next.retire(&deleters::drop_box) };
116+
unsafe { HazPtrObjectWrapper::retire(self.next, &deleters::drop_box) };
117117
}
118118
}
119119
}
@@ -125,7 +125,7 @@ fn destruction() {
125125
HeadRetireNext { next: last, dtors },
126126
)));
127127
}
128-
unsafe { last.retire(&deleters::drop_box) };
128+
unsafe { HazPtrObjectWrapper::retire(last, &deleters::drop_box) };
129129
domain.cleanup();
130130
assert_eq!(2000, dtors.load(Ordering::SeqCst));
131131
}
@@ -141,7 +141,7 @@ fn move_test() {
141141
let x = Box::into_raw(Box::new(HazPtrObjectWrapper::with_domain(&domain, obj)));
142142
let mut hptr0 = HazardPointer::make_in_domain(&domain);
143143
unsafe { hptr0.protect_raw(x) };
144-
unsafe { x.retire(&deleters::drop_box) };
144+
unsafe { HazPtrObjectWrapper::retire(x, &deleters::drop_box) };
145145
let hptr1 = hptr0;
146146
let hptr1 = hptr1;
147147
let mut hptr2;
@@ -163,7 +163,7 @@ fn array() {
163163
let mut hptr = HazardPointer::make_many_in_domain::<3>(&domain);
164164
let hptr = hptr.hazard_pointers();
165165
unsafe { hptr[2].protect_raw(x) };
166-
unsafe { x.retire(&deleters::drop_box) };
166+
unsafe { HazPtrObjectWrapper::retire(x, &deleters::drop_box) };
167167
// x is still protected from the call to protect_raw earlier.
168168
assert_eq!(unsafe { &*x }.val, i);
169169
hptr[2].reset_protection();
@@ -175,13 +175,13 @@ fn array() {
175175
fn free_function_retire() {
176176
let domain = unique_domain!();
177177
let foo = Box::into_raw(Box::new(HazPtrObjectWrapper::with_domain(&domain, 0)));
178-
unsafe { foo.retire(&deleters::drop_box) };
178+
unsafe { HazPtrObjectWrapper::retire(foo, &deleters::drop_box) };
179179
let foo2 = Box::into_raw(Box::new(HazPtrObjectWrapper::with_domain(&domain, 0)));
180180
unsafe fn _custom_drop(ptr: *mut (dyn Reclaim + 'static)) {
181181
let _ = Box::from_raw(ptr);
182182
}
183183
const CUSTOM_DROP: unsafe fn(*mut dyn Reclaim) = _custom_drop;
184-
unsafe { foo2.retire(&CUSTOM_DROP) };
184+
unsafe { HazPtrObjectWrapper::retire(foo2, &CUSTOM_DROP) };
185185

186186
// Third test just checks that dtor is called, which is already covered by other tests.
187187
// It is _not_ using a custom deleter/retirer.
@@ -205,8 +205,8 @@ fn array_part_of_cleanup() {
205205
let h = h.hazard_pointers();
206206
unsafe { h[0].protect_raw(p0) };
207207
unsafe { h[1].protect_raw(p1) };
208-
unsafe { p0.retire(&deleters::drop_box) };
209-
unsafe { p1.retire(&deleters::drop_box) };
208+
unsafe { HazPtrObjectWrapper::retire(p0, &deleters::drop_box) };
209+
unsafe { HazPtrObjectWrapper::retire(p1, &deleters::drop_box) };
210210
}
211211
assert_eq!(2, count.ctors());
212212
domain.cleanup();

tests/loom.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ fn folly_cleanup() {
288288
for j in (tid..THREAD_OPS).step_by(NUM_THREADS) {
289289
let obj = Node::new(count, j, std::ptr::null_mut());
290290
let p = Box::into_raw(Box::new(HazPtrObjectWrapper::with_domain(&D, obj)));
291-
unsafe { p.retire(&deleters::drop_box) };
291+
unsafe { HazPtrObjectWrapper::retire(p, &deleters::drop_box) };
292292
}
293293
threads_done.fetch_add(1, Ordering::AcqRel);
294294
let _ = main_done.lock();
@@ -299,7 +299,7 @@ fn folly_cleanup() {
299299
for i in 0..MAIN_OPS {
300300
let obj = Node::new(count, i, std::ptr::null_mut());
301301
let p = Box::into_raw(Box::new(HazPtrObjectWrapper::with_domain(&D, obj)));
302-
unsafe { p.retire(&deleters::drop_box) };
302+
unsafe { HazPtrObjectWrapper::retire(p, &deleters::drop_box) };
303303
}
304304
}
305305
while threads_done.load(Ordering::Acquire) < NUM_THREADS {

0 commit comments

Comments
 (0)