1 use std
::sync
::atomic
::AtomicUsize
;
2 use std
::sync
::atomic
::Ordering
::{AcqRel, Acquire, Relaxed}
;
5 use std
::time
::{Duration, Instant}
;
7 use crossbeam_epoch
::{self as epoch, Atomic, Collector, LocalHandle, Owned, Shared}
;
10 fn worker(a
: Arc
<Atomic
<AtomicUsize
>>, handle
: LocalHandle
) -> usize {
11 let mut rng
= rand
::thread_rng();
15 thread
::sleep(Duration
::from_millis(1));
17 let timeout
= Duration
::from_millis(rng
.gen_range(0, 10));
18 let now
= Instant
::now();
20 while now
.elapsed() < timeout
{
22 let guard
= &handle
.pin();
25 let val
= if rng
.gen() {
26 let p
= a
.swap(Owned
::new(AtomicUsize
::new(sum
)), AcqRel
, guard
);
28 guard
.defer_destroy(p
);
30 p
.deref().load(Relaxed
)
33 let p
= a
.load(Acquire
, guard
);
34 unsafe { p.deref().fetch_add(sum, Relaxed) }
37 sum
= sum
.wrapping_add(val
);
46 let collector
= Collector
::new();
47 let a
= Arc
::new(Atomic
::new(AtomicUsize
::new(777)));
52 let c
= collector
.clone();
53 thread
::spawn(move || worker(a
, c
.register()))
62 a
.swap(Shared
::null(), AcqRel
, epoch
::unprotected())