diff --git a/ci/crossbeam-channel.sh b/ci/crossbeam-channel.sh index abe70583a..05f59b220 100755 --- a/ci/crossbeam-channel.sh +++ b/ci/crossbeam-channel.sh @@ -11,6 +11,9 @@ cargo test -- --test-threads=1 if [[ "$RUST_VERSION" == "nightly"* ]]; then cd benchmarks cargo check --bins + cd .. RUSTDOCFLAGS=-Dwarnings cargo doc --no-deps --all-features + + ./../ci/miri.sh -- -Zmiri-disable-isolation fi diff --git a/ci/crossbeam-deque.sh b/ci/crossbeam-deque.sh index fb53ab88c..84230f5e4 100755 --- a/ci/crossbeam-deque.sh +++ b/ci/crossbeam-deque.sh @@ -10,4 +10,7 @@ cargo test if [[ "$RUST_VERSION" == "nightly"* ]]; then RUSTDOCFLAGS=-Dwarnings cargo doc --no-deps --all-features + + # -Zmiri-ignore-leaks is needed for https://github.com/crossbeam-rs/crossbeam/issues/579 + ./../ci/miri.sh -- -Zmiri-ignore-leaks fi diff --git a/ci/crossbeam-epoch.sh b/ci/crossbeam-epoch.sh index 995f81c0d..1d0a6df37 100755 --- a/ci/crossbeam-epoch.sh +++ b/ci/crossbeam-epoch.sh @@ -22,4 +22,8 @@ if [[ "$RUST_VERSION" == "nightly"* ]]; then --features sanitize,nightly \ --example sanitize fi + + # -Zmiri-disable-stacked-borrows is needed for https://github.com/crossbeam-rs/crossbeam/issues/545 + # -Zmiri-ignore-leaks is needed for https://github.com/crossbeam-rs/crossbeam/issues/579 + ./../ci/miri.sh -- -Zmiri-disable-stacked-borrows -Zmiri-ignore-leaks fi diff --git a/ci/crossbeam-queue.sh b/ci/crossbeam-queue.sh index b15303b5b..cb16404a7 100755 --- a/ci/crossbeam-queue.sh +++ b/ci/crossbeam-queue.sh @@ -10,4 +10,6 @@ cargo test if [[ "$RUST_VERSION" == "nightly"* ]]; then RUSTDOCFLAGS=-Dwarnings cargo doc --no-deps --all-features + + ./../ci/miri.sh fi diff --git a/ci/crossbeam-skiplist.sh b/ci/crossbeam-skiplist.sh index 3928d42e4..48650804c 100755 --- a/ci/crossbeam-skiplist.sh +++ b/ci/crossbeam-skiplist.sh @@ -12,4 +12,8 @@ if [[ "$RUST_VERSION" == "nightly"* ]]; then cargo test --features nightly RUSTDOCFLAGS=-Dwarnings cargo doc --no-deps --all-features + + # -Zmiri-disable-stacked-borrows is needed for https://github.com/crossbeam-rs/crossbeam/issues/545 + # -Zmiri-ignore-leaks is needed for https://github.com/crossbeam-rs/crossbeam/issues/579 + ./../ci/miri.sh -- -Zmiri-disable-stacked-borrows -Zmiri-ignore-leaks fi diff --git a/ci/crossbeam-utils.sh b/ci/crossbeam-utils.sh index 4879687de..11fc9d7f1 100755 --- a/ci/crossbeam-utils.sh +++ b/ci/crossbeam-utils.sh @@ -12,4 +12,6 @@ if [[ "$RUST_VERSION" == "nightly"* ]]; then cargo test --features nightly RUSTDOCFLAGS=-Dwarnings cargo doc --no-deps --all-features + + ./../ci/miri.sh -- -Zmiri-disable-isolation fi diff --git a/ci/crossbeam.sh b/ci/crossbeam.sh index 99d4483bd..c3fa09255 100755 --- a/ci/crossbeam.sh +++ b/ci/crossbeam.sh @@ -12,4 +12,7 @@ if [[ "$RUST_VERSION" == "nightly"* ]]; then cargo test --features nightly RUSTDOCFLAGS=-Dwarnings cargo doc --no-deps --all-features + + # -Zmiri-ignore-leaks is needed for https://github.com/crossbeam-rs/crossbeam/issues/579 + ./ci/miri.sh -- -Zmiri-ignore-leaks fi diff --git a/ci/miri.sh b/ci/miri.sh new file mode 100755 index 000000000..7092f9202 --- /dev/null +++ b/ci/miri.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -ex + +export RUSTFLAGS="-D warnings" + +if [[ "$OSTYPE" != "linux"* ]]; then + exit 0 +fi + +MIRI_NIGHTLY=nightly-$(curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/miri) +rustup set profile minimal +rustup default "$MIRI_NIGHTLY" +rustup component add miri + +cargo miri test "${@}" diff --git a/crossbeam-deque/tests/fifo.rs b/crossbeam-deque/tests/fifo.rs index 19a1f5849..f377f918d 100644 --- a/crossbeam-deque/tests/fifo.rs +++ b/crossbeam-deque/tests/fifo.rs @@ -71,6 +71,9 @@ fn is_empty() { #[test] fn spsc() { + #[cfg(miri)] + const STEPS: usize = 500; + #[cfg(not(miri))] const STEPS: usize = 50_000; let w = Worker::new_fifo(); @@ -100,6 +103,9 @@ fn spsc() { #[test] fn stampede() { const THREADS: usize = 8; + #[cfg(miri)] + const COUNT: usize = 500; + #[cfg(not(miri))] const COUNT: usize = 50_000; let w = Worker::new_fifo(); @@ -141,6 +147,9 @@ fn stampede() { #[test] fn stress() { const THREADS: usize = 8; + #[cfg(miri)] + const COUNT: usize = 500; + #[cfg(not(miri))] const COUNT: usize = 50_000; let w = Worker::new_fifo(); @@ -197,6 +206,7 @@ fn stress() { .unwrap(); } +#[cfg_attr(miri, ignore)] // Miri is too slow #[test] fn no_starvation() { const THREADS: usize = 8; @@ -256,6 +266,7 @@ fn no_starvation() { .unwrap(); } +#[cfg_attr(miri, ignore)] // Miri is too slow #[test] fn destructors() { const THREADS: usize = 8; diff --git a/crossbeam-deque/tests/injector.rs b/crossbeam-deque/tests/injector.rs index 0165e1a6b..8c1a250b6 100644 --- a/crossbeam-deque/tests/injector.rs +++ b/crossbeam-deque/tests/injector.rs @@ -46,6 +46,9 @@ fn is_empty() { #[test] fn spsc() { + #[cfg(miri)] + const COUNT: usize = 500; + #[cfg(not(miri))] const COUNT: usize = 100_000; let q = Injector::new(); @@ -73,6 +76,9 @@ fn spsc() { #[test] fn mpmc() { + #[cfg(miri)] + const COUNT: usize = 500; + #[cfg(not(miri))] const COUNT: usize = 25_000; const THREADS: usize = 4; @@ -111,6 +117,9 @@ fn mpmc() { #[test] fn stampede() { const THREADS: usize = 8; + #[cfg(miri)] + const COUNT: usize = 500; + #[cfg(not(miri))] const COUNT: usize = 50_000; let q = Injector::new(); @@ -152,6 +161,9 @@ fn stampede() { #[test] fn stress() { const THREADS: usize = 8; + #[cfg(miri)] + const COUNT: usize = 500; + #[cfg(not(miri))] const COUNT: usize = 50_000; let q = Injector::new(); @@ -208,6 +220,7 @@ fn stress() { .unwrap(); } +#[cfg_attr(miri, ignore)] // Miri is too slow #[test] fn no_starvation() { const THREADS: usize = 8; @@ -267,6 +280,7 @@ fn no_starvation() { .unwrap(); } +#[cfg_attr(miri, ignore)] // Miri is too slow #[test] fn destructors() { const THREADS: usize = 8; diff --git a/crossbeam-deque/tests/lifo.rs b/crossbeam-deque/tests/lifo.rs index d7e498add..32f223ba7 100644 --- a/crossbeam-deque/tests/lifo.rs +++ b/crossbeam-deque/tests/lifo.rs @@ -71,6 +71,9 @@ fn is_empty() { #[test] fn spsc() { + #[cfg(miri)] + const STEPS: usize = 500; + #[cfg(not(miri))] const STEPS: usize = 50_000; let w = Worker::new_lifo(); @@ -100,6 +103,9 @@ fn spsc() { #[test] fn stampede() { const THREADS: usize = 8; + #[cfg(miri)] + const COUNT: usize = 500; + #[cfg(not(miri))] const COUNT: usize = 50_000; let w = Worker::new_lifo(); @@ -141,6 +147,9 @@ fn stampede() { #[test] fn stress() { const THREADS: usize = 8; + #[cfg(miri)] + const COUNT: usize = 500; + #[cfg(not(miri))] const COUNT: usize = 50_000; let w = Worker::new_lifo(); @@ -197,6 +206,7 @@ fn stress() { .unwrap(); } +#[cfg_attr(miri, ignore)] // Miri is too slow #[test] fn no_starvation() { const THREADS: usize = 8; @@ -256,6 +266,7 @@ fn no_starvation() { .unwrap(); } +#[cfg_attr(miri, ignore)] // Miri is too slow #[test] fn destructors() { const THREADS: usize = 8; diff --git a/crossbeam-epoch/src/collector.rs b/crossbeam-epoch/src/collector.rs index 8224e1184..3955b09cb 100644 --- a/crossbeam-epoch/src/collector.rs +++ b/crossbeam-epoch/src/collector.rs @@ -178,13 +178,18 @@ mod tests { #[test] fn pin_holds_advance() { + #[cfg(miri)] + const N: usize = 500; + #[cfg(not(miri))] + const N: usize = 500_000; + let collector = Collector::new(); thread::scope(|scope| { for _ in 0..NUM_THREADS { scope.spawn(|_| { let handle = collector.register(); - for _ in 0..500_000 { + for _ in 0..N { let guard = &handle.pin(); let before = collector.global.epoch.load(Ordering::Relaxed); @@ -201,6 +206,9 @@ mod tests { #[test] fn incremental() { + #[cfg(miri)] + const COUNT: usize = 500; + #[cfg(not(miri))] const COUNT: usize = 100_000; static DESTROYS: AtomicUsize = AtomicUsize::new(0); @@ -229,12 +237,16 @@ mod tests { let guard = &handle.pin(); collector.global.collect(guard); } - assert!(DESTROYS.load(Ordering::Relaxed) == 100_000); + assert!(DESTROYS.load(Ordering::Relaxed) == COUNT); } #[test] fn buffering() { const COUNT: usize = 10; + #[cfg(miri)] + const N: usize = 500; + #[cfg(not(miri))] + const N: usize = 100_000; static DESTROYS: AtomicUsize = AtomicUsize::new(0); let collector = Collector::new(); @@ -251,7 +263,7 @@ mod tests { } } - for _ in 0..100_000 { + for _ in 0..N { collector.global.collect(&handle.pin()); } assert!(DESTROYS.load(Ordering::Relaxed) < COUNT); @@ -267,6 +279,9 @@ mod tests { #[test] fn count_drops() { + #[cfg(miri)] + const COUNT: usize = 500; + #[cfg(not(miri))] const COUNT: usize = 100_000; static DROPS: AtomicUsize = AtomicUsize::new(0); @@ -300,6 +315,9 @@ mod tests { #[test] fn count_destroy() { + #[cfg(miri)] + const COUNT: usize = 500; + #[cfg(not(miri))] const COUNT: usize = 100_000; static DESTROYS: AtomicUsize = AtomicUsize::new(0); @@ -366,6 +384,9 @@ mod tests { #[test] fn destroy_array() { + #[cfg(miri)] + const COUNT: usize = 500; + #[cfg(not(miri))] const COUNT: usize = 100_000; static DESTROYS: AtomicUsize = AtomicUsize::new(0); @@ -401,6 +422,9 @@ mod tests { #[test] fn stress() { const THREADS: usize = 8; + #[cfg(miri)] + const COUNT: usize = 500; + #[cfg(not(miri))] const COUNT: usize = 100_000; static DROPS: AtomicUsize = AtomicUsize::new(0); diff --git a/crossbeam-epoch/src/sync/queue.rs b/crossbeam-epoch/src/sync/queue.rs index 1bd76e92e..f5049e48a 100644 --- a/crossbeam-epoch/src/sync/queue.rs +++ b/crossbeam-epoch/src/sync/queue.rs @@ -251,6 +251,9 @@ mod test { } } + #[cfg(miri)] + const CONC_COUNT: i64 = 1000; + #[cfg(not(miri))] const CONC_COUNT: i64 = 1000000; #[test] diff --git a/crossbeam-queue/tests/array_queue.rs b/crossbeam-queue/tests/array_queue.rs index 7b9dba0ea..306d035da 100644 --- a/crossbeam-queue/tests/array_queue.rs +++ b/crossbeam-queue/tests/array_queue.rs @@ -57,6 +57,7 @@ fn len_empty_full() { assert_eq!(q.is_full(), false); } +#[cfg_attr(miri, ignore)] // Miri is too slow #[test] fn len() { const COUNT: usize = 25_000; @@ -114,6 +115,7 @@ fn len() { assert_eq!(q.len(), 0); } +#[cfg_attr(miri, ignore)] // Miri is too slow #[test] fn spsc() { const COUNT: usize = 100_000; @@ -142,6 +144,7 @@ fn spsc() { .unwrap(); } +#[cfg_attr(miri, ignore)] // Miri is too slow #[test] fn mpmc() { const COUNT: usize = 25_000; @@ -178,6 +181,7 @@ fn mpmc() { } } +#[cfg_attr(miri, ignore)] // Miri is too slow #[test] fn drops() { const RUNS: usize = 100; @@ -231,6 +235,9 @@ fn drops() { #[test] fn linearizable() { + #[cfg(miri)] + const COUNT: usize = 500; + #[cfg(not(miri))] const COUNT: usize = 25_000; const THREADS: usize = 4; diff --git a/crossbeam-queue/tests/seg_queue.rs b/crossbeam-queue/tests/seg_queue.rs index 6984a508f..b8bae8b91 100644 --- a/crossbeam-queue/tests/seg_queue.rs +++ b/crossbeam-queue/tests/seg_queue.rs @@ -52,6 +52,7 @@ fn len() { assert_eq!(q.len(), 0); } +#[cfg_attr(miri, ignore)] // Miri is too slow #[test] fn spsc() { const COUNT: usize = 100_000; @@ -79,6 +80,7 @@ fn spsc() { .unwrap(); } +#[cfg_attr(miri, ignore)] // Miri is too slow #[test] fn mpmc() { const COUNT: usize = 25_000; @@ -115,6 +117,7 @@ fn mpmc() { } } +#[cfg_attr(miri, ignore)] // Miri is too slow #[test] fn drops() { static DROPS: AtomicUsize = AtomicUsize::new(0);