From 45a43de3e11e58a59c20d72239e9a20cfa69b593 Mon Sep 17 00:00:00 2001 From: CJP10 Date: Sun, 18 Aug 2024 18:21:05 -0400 Subject: [PATCH] use loom for concurrency testing --- Cargo.toml | 3 +++ src/experimental.rs | 47 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 268d9eb..175e733 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,9 @@ license = "MIT/Apache-2.0" [dependencies] parking_lot = "0.12.3" +[target.'cfg(loom)'.dependencies] +loom = "0.7" + [dev-dependencies] criterion = "0.5.1" criterion-plot = "0.5.0" diff --git a/src/experimental.rs b/src/experimental.rs index 97c6872..8e9b302 100644 --- a/src/experimental.rs +++ b/src/experimental.rs @@ -3,12 +3,15 @@ use std::{ iter::FromIterator, mem::ManuallyDrop, ops::{Deref, DerefMut}, - sync::atomic::{ - AtomicU64, - Ordering::{Acquire, Relaxed, Release}, - }, + sync::atomic::Ordering::{Acquire, Relaxed, Release}, }; +#[cfg(not(loom))] +use std::sync::atomic::AtomicU64; + +#[cfg(loom)] +use loom::sync::atomic::AtomicU64; + const U64_BITS: usize = u64::BITS as usize; pub struct Pool { @@ -139,7 +142,6 @@ impl AtomicBitSet { #[cfg(test)] mod tests { use crate::experimental::Pool; - use std::iter::FromIterator; use std::sync::atomic::Ordering::Relaxed; #[test] @@ -191,3 +193,38 @@ mod tests { } } } + +#[cfg(loom)] +mod loom_tests { + use crate::experimental::Pool; + use loom::sync::Arc; + + #[test] + fn concurrent_pull_sum() { + loom::model(|| { + const N: usize = 2; + let p: Pool = (0..N).map(|_| 0).collect(); + let p = Arc::new(p); + + let handles: Vec<_> = (0..N) + .map(|_| { + let p1 = p.clone(); + loom::thread::spawn(move || { + *p1.pull().unwrap() += 1; + }) + }) + .collect(); + + for handle in handles { + handle.join().unwrap(); + } + + unsafe { + assert_eq!( + p.objects.iter().map(|x| (*x.get()).unwrap()).sum::(), + N + ); + } + }); + } +}