summaryrefslogtreecommitdiffstats
path: root/third_party/rust/crossbeam-epoch/examples
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/rust/crossbeam-epoch/examples/sanitize.rs66
1 files changed, 66 insertions, 0 deletions
diff --git a/third_party/rust/crossbeam-epoch/examples/sanitize.rs b/third_party/rust/crossbeam-epoch/examples/sanitize.rs
new file mode 100644
index 0000000000..4109c34a8c
--- /dev/null
+++ b/third_party/rust/crossbeam-epoch/examples/sanitize.rs
@@ -0,0 +1,66 @@
+use std::sync::atomic::AtomicUsize;
+use std::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed};
+use std::sync::Arc;
+use std::thread;
+use std::time::{Duration, Instant};
+
+use crossbeam_epoch::{self as epoch, Atomic, Collector, LocalHandle, Owned, Shared};
+use rand::Rng;
+
+fn worker(a: Arc<Atomic<AtomicUsize>>, handle: LocalHandle) -> usize {
+ let mut rng = rand::thread_rng();
+ let mut sum = 0;
+
+ if rng.gen() {
+ thread::sleep(Duration::from_millis(1));
+ }
+ let timeout = Duration::from_millis(rng.gen_range(0..10));
+ let now = Instant::now();
+
+ while now.elapsed() < timeout {
+ for _ in 0..100 {
+ let guard = &handle.pin();
+ guard.flush();
+
+ let val = if rng.gen() {
+ let p = a.swap(Owned::new(AtomicUsize::new(sum)), AcqRel, guard);
+ unsafe {
+ guard.defer_destroy(p);
+ guard.flush();
+ p.deref().load(Relaxed)
+ }
+ } else {
+ let p = a.load(Acquire, guard);
+ unsafe { p.deref().fetch_add(sum, Relaxed) }
+ };
+
+ sum = sum.wrapping_add(val);
+ }
+ }
+
+ sum
+}
+
+fn main() {
+ for _ in 0..100 {
+ let collector = Collector::new();
+ let a = Arc::new(Atomic::new(AtomicUsize::new(777)));
+
+ let threads = (0..16)
+ .map(|_| {
+ let a = a.clone();
+ let c = collector.clone();
+ thread::spawn(move || worker(a, c.register()))
+ })
+ .collect::<Vec<_>>();
+
+ for t in threads {
+ t.join().unwrap();
+ }
+
+ unsafe {
+ a.swap(Shared::null(), AcqRel, epoch::unprotected())
+ .into_owned();
+ }
+ }
+}