diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-07-07 07:12:38 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-07-07 07:12:38 +0000 |
commit | 38996fd597e6da596aaed4f0ba3b0414fd9fab22 (patch) | |
tree | 5dde593726f7dcc1fcedcc1ed4b1d54d3743b0bb | |
parent | 2bed517f5b256e4540aa7b7966c9e5e5c2e915d6 (diff) | |
parent | bc312a33af99a4ca364a29a732e04f466498e29b (diff) | |
download | crossbeam-queue-38996fd597e6da596aaed4f0ba3b0414fd9fab22.tar.gz |
Snap for 10453938 from bc312a33af99a4ca364a29a732e04f466498e29b to mainline-odp-releaseaml_odp_341717000aml_odp_341610000
Change-Id: Ibfd8a6c2c5a2142550bdf4a9132b4a2dab0e229d
-rw-r--r-- | .cargo_vcs_info.json | 2 | ||||
-rw-r--r-- | Android.bp | 6 | ||||
-rw-r--r-- | CHANGELOG.md | 18 | ||||
-rw-r--r-- | Cargo.toml | 5 | ||||
-rw-r--r-- | Cargo.toml.orig | 4 | ||||
-rw-r--r-- | METADATA | 12 | ||||
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | build-common.rs | 13 | ||||
-rw-r--r-- | build.rs | 10 | ||||
-rw-r--r-- | no_atomic.rs | 13 | ||||
-rw-r--r-- | src/array_queue.rs | 145 | ||||
-rw-r--r-- | src/seg_queue.rs | 24 | ||||
-rw-r--r-- | tests/array_queue.rs | 132 | ||||
-rw-r--r-- | tests/seg_queue.rs | 19 |
14 files changed, 320 insertions, 87 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 1c48586..1c674b3 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,6 +1,6 @@ { "git": { - "sha1": "2988f873f87d2263a7fd2b9465fb9c28f43a6490" + "sha1": "366276a4dde8bd6b4bdab531c09e6ab1ff38c407" }, "path_in_vcs": "crossbeam-queue" }
\ No newline at end of file @@ -43,7 +43,7 @@ rust_defaults { name: "crossbeam-queue_test_defaults", crate_name: "crossbeam_queue", cargo_env_compat: true, - cargo_pkg_version: "0.3.4", + cargo_pkg_version: "0.3.8", test_suites: ["general-tests"], auto_gen_config: true, edition: "2018", @@ -85,7 +85,7 @@ rust_library { host_supported: true, crate_name: "crossbeam_queue", cargo_env_compat: true, - cargo_pkg_version: "0.3.4", + cargo_pkg_version: "0.3.8", srcs: ["src/lib.rs"], edition: "2018", features: [ @@ -101,4 +101,6 @@ rust_library { "//apex_available:platform", "com.android.virt", ], + product_available: true, + vendor_available: true, } diff --git a/CHANGELOG.md b/CHANGELOG.md index bf79c5e..79aaacd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ +# Version 0.3.8 + +- Fix build script bug introduced in 0.3.7. (#932) + +# Version 0.3.7 + +**Note:** This release has been yanked due to regression fixed in 0.3.8. + +- Improve support for custom targets. (#922) + +# Version 0.3.6 + +- Bump the minimum supported Rust version to 1.38. (#877) + +# Version 0.3.5 + +- Add `ArrayQueue::force_push`. (#789) + # Version 0.3.4 - Implement `IntoIterator` for `ArrayQueue` and `SegQueue`. (#772) @@ -11,11 +11,12 @@ [package] edition = "2018" -rust-version = "1.36" +rust-version = "1.38" name = "crossbeam-queue" -version = "0.3.4" +version = "0.3.8" description = "Concurrent queues" homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-queue" +readme = "README.md" keywords = [ "queue", "mpmc", diff --git a/Cargo.toml.orig b/Cargo.toml.orig index ac68694..27c386c 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -4,9 +4,9 @@ name = "crossbeam-queue" # - Update CHANGELOG.md # - Update README.md # - Create "crossbeam-queue-X.Y.Z" git tag -version = "0.3.4" +version = "0.3.8" edition = "2018" -rust-version = "1.36" +rust-version = "1.38" license = "MIT OR Apache-2.0" repository = "https://github.com/crossbeam-rs/crossbeam" homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-queue" @@ -1,3 +1,7 @@ +# This project was upgraded with external_updater. +# Usage: tools/external_updater/updater.sh update rust/crates/crossbeam-queue +# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md + name: "crossbeam-queue" description: "Concurrent queues" third_party { @@ -7,13 +11,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/crossbeam-queue/crossbeam-queue-0.3.4.crate" + value: "https://static.crates.io/crates/crossbeam-queue/crossbeam-queue-0.3.8.crate" } - version: "0.3.4" + version: "0.3.8" license_type: NOTICE last_upgrade_date { year: 2022 - month: 3 - day: 1 + month: 12 + day: 8 } } @@ -8,7 +8,7 @@ https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-queue#license) https://crates.io/crates/crossbeam-queue) [![Documentation](https://docs.rs/crossbeam-queue/badge.svg)]( https://docs.rs/crossbeam-queue) -[![Rust 1.36+](https://img.shields.io/badge/rust-1.36+-lightgray.svg)]( +[![Rust 1.38+](https://img.shields.io/badge/rust-1.38+-lightgray.svg)]( https://www.rust-lang.org) [![chat](https://img.shields.io/discord/569610676205781012.svg?logo=discord)](https://discord.com/invite/JXYwgWZ) @@ -36,7 +36,7 @@ crossbeam-queue = "0.3" Crossbeam Queue supports stable Rust releases going back at least six months, and every time the minimum supported Rust version is increased, a new minor -version is released. Currently, the minimum supported Rust version is 1.36. +version is released. Currently, the minimum supported Rust version is 1.38. ## License diff --git a/build-common.rs b/build-common.rs new file mode 100644 index 0000000..e91bb4d --- /dev/null +++ b/build-common.rs @@ -0,0 +1,13 @@ +// The target triplets have the form of 'arch-vendor-system'. +// +// When building for Linux (e.g. the 'system' part is +// 'linux-something'), replace the vendor with 'unknown' +// so that mapping to rust standard targets happens correctly. +fn convert_custom_linux_target(target: String) -> String { + let mut parts: Vec<&str> = target.split('-').collect(); + let system = parts.get(2); + if system == Some(&"linux") { + parts[1] = "unknown"; + }; + parts.join("-") +} @@ -15,10 +15,11 @@ use std::env; include!("no_atomic.rs"); +include!("build-common.rs"); fn main() { let target = match env::var("TARGET") { - Ok(target) => target, + Ok(target) => convert_custom_linux_target(target), Err(e) => { println!( "cargo:warning={}: unable to get TARGET environment variable: {}", @@ -29,10 +30,9 @@ fn main() { } }; - // Note that this is `no_*`, not `has_*`. This allows treating - // `cfg(target_has_atomic = "ptr")` as true when the build script doesn't - // run. This is needed for compatibility with non-cargo build systems that - // don't run the build script. + // Note that this is `no_`*, not `has_*`. This allows treating as the latest + // stable rustc is used when the build script doesn't run. This is useful + // for non-cargo build systems that don't run the build script. if NO_ATOMIC_CAS.contains(&&*target) { println!("cargo:rustc-cfg=crossbeam_no_atomic_cas"); } diff --git a/no_atomic.rs b/no_atomic.rs index 90ac60a..8ce0d31 100644 --- a/no_atomic.rs +++ b/no_atomic.rs @@ -2,13 +2,17 @@ // It is not intended for manual editing. const NO_ATOMIC_CAS: &[&str] = &[ + "armv4t-none-eabi", + "armv5te-none-eabi", "avr-unknown-gnu-atmega328", "bpfeb-unknown-none", "bpfel-unknown-none", "msp430-none-elf", "riscv32i-unknown-none-elf", + "riscv32im-unknown-none-elf", "riscv32imc-unknown-none-elf", "thumbv4t-none-eabi", + "thumbv5te-none-eabi", "thumbv6m-none-eabi", ]; @@ -17,7 +21,9 @@ const NO_ATOMIC_64: &[&str] = &[ "arm-linux-androideabi", "armebv7r-none-eabi", "armebv7r-none-eabihf", + "armv4t-none-eabi", "armv4t-unknown-linux-gnueabi", + "armv5te-none-eabi", "armv5te-unknown-linux-gnueabi", "armv5te-unknown-linux-musleabi", "armv5te-unknown-linux-uclibceabi", @@ -31,6 +37,7 @@ const NO_ATOMIC_64: &[&str] = &[ "mips-unknown-linux-musl", "mips-unknown-linux-uclibc", "mipsel-sony-psp", + "mipsel-sony-psx", "mipsel-unknown-linux-gnu", "mipsel-unknown-linux-musl", "mipsel-unknown-linux-uclibc", @@ -49,10 +56,12 @@ const NO_ATOMIC_64: &[&str] = &[ "riscv32gc-unknown-linux-gnu", "riscv32gc-unknown-linux-musl", "riscv32i-unknown-none-elf", + "riscv32im-unknown-none-elf", "riscv32imac-unknown-none-elf", - "riscv32imc-esp-espidf", + "riscv32imac-unknown-xous-elf", "riscv32imc-unknown-none-elf", "thumbv4t-none-eabi", + "thumbv5te-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabi", "thumbv7em-none-eabihf", @@ -65,7 +74,9 @@ const NO_ATOMIC_64: &[&str] = &[ #[allow(dead_code)] // Only crossbeam-utils uses this. const NO_ATOMIC: &[&str] = &[ "avr-unknown-gnu-atmega328", + "mipsel-sony-psx", "msp430-none-elf", "riscv32i-unknown-none-elf", + "riscv32im-unknown-none-elf", "riscv32imc-unknown-none-elf", ]; diff --git a/src/array_queue.rs b/src/array_queue.rs index 5f3061b..e07fde8 100644 --- a/src/array_queue.rs +++ b/src/array_queue.rs @@ -27,9 +27,11 @@ struct Slot<T> { /// /// This queue allocates a fixed-capacity buffer on construction, which is used to store pushed /// elements. The queue cannot hold more elements than the buffer allows. Attempting to push an -/// element into a full queue will fail. Having a buffer allocated upfront makes this queue a bit -/// faster than [`SegQueue`]. +/// element into a full queue will fail. Alternatively, [`force_push`] makes it possible for +/// this queue to be used as a ring-buffer. Having a buffer allocated upfront makes this queue +/// a bit faster than [`SegQueue`]. /// +/// [`force_push`]: ArrayQueue::force_push /// [`SegQueue`]: super::SegQueue /// /// # Examples @@ -120,21 +122,10 @@ impl<T> ArrayQueue<T> { } } - /// Attempts to push an element into the queue. - /// - /// If the queue is full, the element is returned back as an error. - /// - /// # Examples - /// - /// ``` - /// use crossbeam_queue::ArrayQueue; - /// - /// let q = ArrayQueue::new(1); - /// - /// assert_eq!(q.push(10), Ok(())); - /// assert_eq!(q.push(20), Err(20)); - /// ``` - pub fn push(&self, value: T) -> Result<(), T> { + fn push_or_else<F>(&self, mut value: T, f: F) -> Result<(), T> + where + F: Fn(T, usize, usize, &Slot<T>) -> Result<T, T>, + { let backoff = Backoff::new(); let mut tail = self.tail.load(Ordering::Relaxed); @@ -143,6 +134,16 @@ impl<T> ArrayQueue<T> { let index = tail & (self.one_lap - 1); let lap = tail & !(self.one_lap - 1); + let new_tail = if index + 1 < self.cap { + // Same lap, incremented index. + // Set to `{ lap: lap, index: index + 1 }`. + tail + 1 + } else { + // One lap forward, index wraps around to zero. + // Set to `{ lap: lap.wrapping_add(1), index: 0 }`. + lap.wrapping_add(self.one_lap) + }; + // Inspect the corresponding slot. debug_assert!(index < self.buffer.len()); let slot = unsafe { self.buffer.get_unchecked(index) }; @@ -150,16 +151,6 @@ impl<T> ArrayQueue<T> { // If the tail and the stamp match, we may attempt to push. if tail == stamp { - let new_tail = if index + 1 < self.cap { - // Same lap, incremented index. - // Set to `{ lap: lap, index: index + 1 }`. - tail + 1 - } else { - // One lap forward, index wraps around to zero. - // Set to `{ lap: lap.wrapping_add(1), index: 0 }`. - lap.wrapping_add(self.one_lap) - }; - // Try moving the tail. match self.tail.compare_exchange_weak( tail, @@ -182,14 +173,7 @@ impl<T> ArrayQueue<T> { } } else if stamp.wrapping_add(self.one_lap) == tail + 1 { atomic::fence(Ordering::SeqCst); - let head = self.head.load(Ordering::Relaxed); - - // If the head lags one lap behind the tail as well... - if head.wrapping_add(self.one_lap) == tail { - // ...then the queue is full. - return Err(value); - } - + value = f(value, tail, new_tail, slot)?; backoff.spin(); tail = self.tail.load(Ordering::Relaxed); } else { @@ -200,6 +184,79 @@ impl<T> ArrayQueue<T> { } } + /// Attempts to push an element into the queue. + /// + /// If the queue is full, the element is returned back as an error. + /// + /// # Examples + /// + /// ``` + /// use crossbeam_queue::ArrayQueue; + /// + /// let q = ArrayQueue::new(1); + /// + /// assert_eq!(q.push(10), Ok(())); + /// assert_eq!(q.push(20), Err(20)); + /// ``` + pub fn push(&self, value: T) -> Result<(), T> { + self.push_or_else(value, |v, tail, _, _| { + let head = self.head.load(Ordering::Relaxed); + + // If the head lags one lap behind the tail as well... + if head.wrapping_add(self.one_lap) == tail { + // ...then the queue is full. + Err(v) + } else { + Ok(v) + } + }) + } + + /// Pushes an element into the queue, replacing the oldest element if necessary. + /// + /// If the queue is full, the oldest element is replaced and returned, + /// otherwise `None` is returned. + /// + /// # Examples + /// + /// ``` + /// use crossbeam_queue::ArrayQueue; + /// + /// let q = ArrayQueue::new(2); + /// + /// assert_eq!(q.force_push(10), None); + /// assert_eq!(q.force_push(20), None); + /// assert_eq!(q.force_push(30), Some(10)); + /// assert_eq!(q.pop(), Some(20)); + /// ``` + pub fn force_push(&self, value: T) -> Option<T> { + self.push_or_else(value, |v, tail, new_tail, slot| { + let head = tail.wrapping_sub(self.one_lap); + let new_head = new_tail.wrapping_sub(self.one_lap); + + // Try moving the head. + if self + .head + .compare_exchange_weak(head, new_head, Ordering::SeqCst, Ordering::Relaxed) + .is_ok() + { + // Move the tail. + self.tail.store(new_tail, Ordering::SeqCst); + + // Swap the previous value. + let old = unsafe { slot.value.get().replace(MaybeUninit::new(v)).assume_init() }; + + // Update the stamp. + slot.stamp.store(tail + 1, Ordering::Release); + + Err(old) + } else { + Ok(v) + } + }) + .err() + } + /// Attempts to pop an element from the queue. /// /// If the queue is empty, `None` is returned. @@ -387,10 +444,24 @@ impl<T> ArrayQueue<T> { impl<T> Drop for ArrayQueue<T> { fn drop(&mut self) { // Get the index of the head. - let hix = self.head.load(Ordering::Relaxed) & (self.one_lap - 1); + let head = *self.head.get_mut(); + let tail = *self.tail.get_mut(); + + let hix = head & (self.one_lap - 1); + let tix = tail & (self.one_lap - 1); + + let len = if hix < tix { + tix - hix + } else if hix > tix { + self.cap - hix + tix + } else if tail == head { + 0 + } else { + self.cap + }; // Loop over all slots that hold a message and drop them. - for i in 0..self.len() { + for i in 0..len { // Compute the index of the next slot holding a message. let index = if hix + i < self.cap { hix + i diff --git a/src/seg_queue.rs b/src/seg_queue.rs index 1767775..2761dc0 100644 --- a/src/seg_queue.rs +++ b/src/seg_queue.rs @@ -35,6 +35,11 @@ struct Slot<T> { } impl<T> Slot<T> { + const UNINIT: Self = Self { + value: UnsafeCell::new(MaybeUninit::uninit()), + state: AtomicUsize::new(0), + }; + /// Waits until a value is written into the slot. fn wait_write(&self) { let backoff = Backoff::new(); @@ -58,13 +63,10 @@ struct Block<T> { impl<T> Block<T> { /// Creates an empty block that starts at `start_index`. fn new() -> Block<T> { - // SAFETY: This is safe because: - // [1] `Block::next` (AtomicPtr) may be safely zero initialized. - // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. - // [3] `Slot::value` (UnsafeCell) may be safely zero initialized because it - // holds a MaybeUninit. - // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. - unsafe { MaybeUninit::zeroed().assume_init() } + Self { + next: AtomicPtr::new(ptr::null_mut()), + slots: [Slot::UNINIT; BLOCK_CAP], + } } /// Waits until the next pointer is set. @@ -437,9 +439,9 @@ impl<T> SegQueue<T> { impl<T> Drop for SegQueue<T> { fn drop(&mut self) { - let mut head = self.head.index.load(Ordering::Relaxed); - let mut tail = self.tail.index.load(Ordering::Relaxed); - let mut block = self.head.block.load(Ordering::Relaxed); + let mut head = *self.head.index.get_mut(); + let mut tail = *self.tail.index.get_mut(); + let mut block = *self.head.block.get_mut(); // Erase the lower bits. head &= !((1 << SHIFT) - 1); @@ -457,7 +459,7 @@ impl<T> Drop for SegQueue<T> { p.as_mut_ptr().drop_in_place(); } else { // Deallocate the block and move to the next one. - let next = (*block).next.load(Ordering::Relaxed); + let next = *(*block).next.get_mut(); drop(Box::from_raw(block)); block = next; } diff --git a/tests/array_queue.rs b/tests/array_queue.rs index a23e082..b9d4e5f 100644 --- a/tests/array_queue.rs +++ b/tests/array_queue.rs @@ -57,24 +57,30 @@ fn len_empty_full() { assert!(!q.is_full()); } -#[cfg_attr(miri, ignore)] // Miri is too slow #[test] fn len() { + #[cfg(miri)] + const COUNT: usize = 30; + #[cfg(not(miri))] const COUNT: usize = 25_000; + #[cfg(miri)] + const CAP: usize = 40; + #[cfg(not(miri))] const CAP: usize = 1000; + const ITERS: usize = CAP / 20; let q = ArrayQueue::new(CAP); assert_eq!(q.len(), 0); for _ in 0..CAP / 10 { - for i in 0..50 { + for i in 0..ITERS { q.push(i).unwrap(); assert_eq!(q.len(), i + 1); } - for i in 0..50 { + for i in 0..ITERS { q.pop().unwrap(); - assert_eq!(q.len(), 50 - i - 1); + assert_eq!(q.len(), ITERS - i - 1); } } assert_eq!(q.len(), 0); @@ -115,9 +121,11 @@ fn len() { assert_eq!(q.len(), 0); } -#[cfg_attr(miri, ignore)] // Miri is too slow #[test] fn spsc() { + #[cfg(miri)] + const COUNT: usize = 50; + #[cfg(not(miri))] const COUNT: usize = 100_000; let q = ArrayQueue::new(3); @@ -144,9 +152,52 @@ fn spsc() { .unwrap(); } -#[cfg_attr(miri, ignore)] // Miri is too slow +#[test] +fn spsc_ring_buffer() { + #[cfg(miri)] + const COUNT: usize = 50; + #[cfg(not(miri))] + const COUNT: usize = 100_000; + + let t = AtomicUsize::new(1); + let q = ArrayQueue::<usize>::new(3); + let v = (0..COUNT).map(|_| AtomicUsize::new(0)).collect::<Vec<_>>(); + + scope(|scope| { + scope.spawn(|_| loop { + match t.load(Ordering::SeqCst) { + 0 if q.is_empty() => break, + + _ => { + while let Some(n) = q.pop() { + v[n].fetch_add(1, Ordering::SeqCst); + } + } + } + }); + + scope.spawn(|_| { + for i in 0..COUNT { + if let Some(n) = q.force_push(i) { + v[n].fetch_add(1, Ordering::SeqCst); + } + } + + t.fetch_sub(1, Ordering::SeqCst); + }); + }) + .unwrap(); + + for c in v { + assert_eq!(c.load(Ordering::SeqCst), 1); + } +} + #[test] fn mpmc() { + #[cfg(miri)] + const COUNT: usize = 50; + #[cfg(not(miri))] const COUNT: usize = 25_000; const THREADS: usize = 4; @@ -181,10 +232,57 @@ fn mpmc() { } } -#[cfg_attr(miri, ignore)] // Miri is too slow +#[test] +fn mpmc_ring_buffer() { + #[cfg(miri)] + const COUNT: usize = 50; + #[cfg(not(miri))] + const COUNT: usize = 25_000; + const THREADS: usize = 4; + + let t = AtomicUsize::new(THREADS); + let q = ArrayQueue::<usize>::new(3); + let v = (0..COUNT).map(|_| AtomicUsize::new(0)).collect::<Vec<_>>(); + + scope(|scope| { + for _ in 0..THREADS { + scope.spawn(|_| loop { + match t.load(Ordering::SeqCst) { + 0 if q.is_empty() => break, + + _ => { + while let Some(n) = q.pop() { + v[n].fetch_add(1, Ordering::SeqCst); + } + } + } + }); + } + + for _ in 0..THREADS { + scope.spawn(|_| { + for i in 0..COUNT { + if let Some(n) = q.force_push(i) { + v[n].fetch_add(1, Ordering::SeqCst); + } + } + + t.fetch_sub(1, Ordering::SeqCst); + }); + } + }) + .unwrap(); + + for c in v { + assert_eq!(c.load(Ordering::SeqCst), THREADS); + } +} + #[test] fn drops() { - const RUNS: usize = 100; + let runs: usize = if cfg!(miri) { 3 } else { 100 }; + let steps: usize = if cfg!(miri) { 50 } else { 10_000 }; + let additional: usize = if cfg!(miri) { 10 } else { 50 }; static DROPS: AtomicUsize = AtomicUsize::new(0); @@ -199,9 +297,9 @@ fn drops() { let mut rng = thread_rng(); - for _ in 0..RUNS { - let steps = rng.gen_range(0..10_000); - let additional = rng.gen_range(0..50); + for _ in 0..runs { + let steps = rng.gen_range(0..steps); + let additional = rng.gen_range(0..additional); DROPS.store(0, Ordering::SeqCst); let q = ArrayQueue::new(50); @@ -236,7 +334,7 @@ fn drops() { #[test] fn linearizable() { #[cfg(miri)] - const COUNT: usize = 500; + const COUNT: usize = 100; #[cfg(not(miri))] const COUNT: usize = 25_000; const THREADS: usize = 4; @@ -244,13 +342,21 @@ fn linearizable() { let q = ArrayQueue::new(THREADS); scope(|scope| { - for _ in 0..THREADS { + for _ in 0..THREADS / 2 { scope.spawn(|_| { for _ in 0..COUNT { while q.push(0).is_err() {} q.pop().unwrap(); } }); + + scope.spawn(|_| { + for _ in 0..COUNT { + if q.force_push(0).is_none() { + q.pop().unwrap(); + } + } + }); } }) .unwrap(); diff --git a/tests/seg_queue.rs b/tests/seg_queue.rs index f1304ed..bf5fb99 100644 --- a/tests/seg_queue.rs +++ b/tests/seg_queue.rs @@ -52,9 +52,11 @@ fn len() { assert_eq!(q.len(), 0); } -#[cfg_attr(miri, ignore)] // Miri is too slow #[test] fn spsc() { + #[cfg(miri)] + const COUNT: usize = 100; + #[cfg(not(miri))] const COUNT: usize = 100_000; let q = SegQueue::new(); @@ -80,9 +82,11 @@ fn spsc() { .unwrap(); } -#[cfg_attr(miri, ignore)] // Miri is too slow #[test] fn mpmc() { + #[cfg(miri)] + const COUNT: usize = 50; + #[cfg(not(miri))] const COUNT: usize = 25_000; const THREADS: usize = 4; @@ -117,10 +121,11 @@ fn mpmc() { } } -#[cfg_attr(miri, ignore)] // Miri is too slow #[test] fn drops() { - const RUNS: usize = 100; + let runs: usize = if cfg!(miri) { 5 } else { 100 }; + let steps: usize = if cfg!(miri) { 50 } else { 10_000 }; + let additional: usize = if cfg!(miri) { 100 } else { 1_000 }; static DROPS: AtomicUsize = AtomicUsize::new(0); @@ -135,9 +140,9 @@ fn drops() { let mut rng = thread_rng(); - for _ in 0..RUNS { - let steps = rng.gen_range(0..10_000); - let additional = rng.gen_range(0..1000); + for _ in 0..runs { + let steps = rng.gen_range(0..steps); + let additional = rng.gen_range(0..additional); DROPS.store(0, Ordering::SeqCst); let q = SegQueue::new(); |