summaryrefslogtreecommitdiffstats
path: root/vendor/crossbeam-deque
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/crossbeam-deque')
-rw-r--r--vendor/crossbeam-deque/.cargo-checksum.json2
-rw-r--r--vendor/crossbeam-deque/CHANGELOG.md18
-rw-r--r--vendor/crossbeam-deque/Cargo.toml26
-rw-r--r--vendor/crossbeam-deque/README.md4
-rw-r--r--vendor/crossbeam-deque/src/deque.rs76
-rw-r--r--vendor/crossbeam-deque/src/lib.rs1
-rw-r--r--vendor/crossbeam-deque/tests/fifo.rs21
-rw-r--r--vendor/crossbeam-deque/tests/injector.rs28
-rw-r--r--vendor/crossbeam-deque/tests/lifo.rs23
9 files changed, 148 insertions, 51 deletions
diff --git a/vendor/crossbeam-deque/.cargo-checksum.json b/vendor/crossbeam-deque/.cargo-checksum.json
index c4f2a9329..45404d824 100644
--- a/vendor/crossbeam-deque/.cargo-checksum.json
+++ b/vendor/crossbeam-deque/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"7d5f333652da0da5f068ff91ecf259599f9ff4a4448bd987dd451699b66f0f59","Cargo.toml":"a9a138b4e005ddea76f588ca7004629ebd8f1a64cd1d55474fe36cae4c57a890","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"6b0a911f542186ef96eb56537cade0ecf1a5731d5d494b7094ff87f0fdeb7710","src/deque.rs":"64a2153dc566847fd9fa0e6b2b7adb3933af9984fbe3429b6f1200b058bb9850","src/lib.rs":"9f0581481691bc698176f369410726adf597d470b9d14e226a65f490d6aff8c6","tests/fifo.rs":"1d83f9ffeeba2cd6bd32f1ab136d843b8c73075d5045619be12dc3c27d8ab3ba","tests/injector.rs":"6812c97615e3f685b5612c390861f2e570ff469f3b9871ba97ddbed5c1f5266b","tests/lifo.rs":"b2ddc8154492322e734b23f35ce54040f9ec84ef878009de3a64d44d35c365a6","tests/steal.rs":"cdf588cc13eeb275ef1231eb18e3245faca7a2d054fa6527bfdba2a34bc8f7bf"},"package":"6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"} \ No newline at end of file
+{"files":{"CHANGELOG.md":"ad5f2c10299e57aaed2d1b8f8a109faa2dfb16c52ce81f60ec5adb0ea9308d7f","Cargo.toml":"4802e7c0d5ab1dc35c162671483a6ee9bff5a3f1d6dd620a01863ac25068019e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"3c62aa0ee37cf714b5b3c304545d5caea4cc0a71020fccb1f146611d64202bb2","src/deque.rs":"cfb3c5b3bcea1f27ca2633d8b8576ff2080e1e9fc083236f2db7916bb77786ed","src/lib.rs":"ec0257a388627d691d652fd04d261c5c0590e1e31a35c8bf5912afac51fd5734","tests/fifo.rs":"3d98e0d4ca7cfddf10708b71642cf1ff05543d067ad837e48401d63cc31c0a18","tests/injector.rs":"fb054ef9fcac5f12e08b7b3451f370b96ab7589d32ef5c02e25958a473c45519","tests/lifo.rs":"57abdb3fc5920a422f785ba308b658bdc5400947532eeffb799f2395a2061549","tests/steal.rs":"cdf588cc13eeb275ef1231eb18e3245faca7a2d054fa6527bfdba2a34bc8f7bf"},"package":"715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"} \ No newline at end of file
diff --git a/vendor/crossbeam-deque/CHANGELOG.md b/vendor/crossbeam-deque/CHANGELOG.md
index 14dcc20b7..855b714f4 100644
--- a/vendor/crossbeam-deque/CHANGELOG.md
+++ b/vendor/crossbeam-deque/CHANGELOG.md
@@ -1,3 +1,7 @@
+# Version 0.8.2
+
+- Bump the minimum supported Rust version to 1.38. (#877)
+
# Version 0.8.1
- Fix deque steal race condition. (#726)
@@ -5,26 +9,40 @@
# Version 0.8.0
+**Note:** This release has been yanked. See [GHSA-pqqp-xmhj-wgcw](https://github.com/crossbeam-rs/crossbeam/security/advisories/GHSA-pqqp-xmhj-wgcw) for details.
+
- Bump the minimum supported Rust version to 1.36.
- Add `Worker::len()` and `Injector::len()` methods.
- Add `std` (enabled by default) feature for forward compatibility.
+# Version 0.7.4
+
+- Fix deque steal race condition.
+
# Version 0.7.3
+**Note:** This release has been yanked. See [GHSA-pqqp-xmhj-wgcw](https://github.com/crossbeam-rs/crossbeam/security/advisories/GHSA-pqqp-xmhj-wgcw) for details.
+
- Stop stealing from the same deque. (#448)
- Fix unsoundness issues by adopting `MaybeUninit`. (#458)
# Version 0.7.2
+**Note:** This release has been yanked. See [GHSA-pqqp-xmhj-wgcw](https://github.com/crossbeam-rs/crossbeam/security/advisories/GHSA-pqqp-xmhj-wgcw) for details.
+
- Bump `crossbeam-epoch` to `0.8`.
- Bump `crossbeam-utils` to `0.7`.
# Version 0.7.1
+**Note:** This release has been yanked. See [GHSA-pqqp-xmhj-wgcw](https://github.com/crossbeam-rs/crossbeam/security/advisories/GHSA-pqqp-xmhj-wgcw) for details.
+
- Bump the minimum required version of `crossbeam-utils`.
# Version 0.7.0
+**Note:** This release has been yanked. See [GHSA-pqqp-xmhj-wgcw](https://github.com/crossbeam-rs/crossbeam/security/advisories/GHSA-pqqp-xmhj-wgcw) for details.
+
- Make `Worker::pop()` faster in the FIFO case.
- Replace `fifo()` nad `lifo()` with `Worker::new_fifo()` and `Worker::new_lifo()`.
- Add more batched steal methods.
diff --git a/vendor/crossbeam-deque/Cargo.toml b/vendor/crossbeam-deque/Cargo.toml
index 3ea5a59f6..4ff10b353 100644
--- a/vendor/crossbeam-deque/Cargo.toml
+++ b/vendor/crossbeam-deque/Cargo.toml
@@ -11,16 +11,26 @@
[package]
edition = "2018"
+rust-version = "1.38"
name = "crossbeam-deque"
-version = "0.8.1"
-authors = ["The Crossbeam Project Developers"]
+version = "0.8.2"
description = "Concurrent work-stealing deque"
homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-deque"
-documentation = "https://docs.rs/crossbeam-deque"
-keywords = ["chase-lev", "lock-free", "scheduler", "scheduling"]
-categories = ["algorithms", "concurrency", "data-structures"]
+readme = "README.md"
+keywords = [
+ "chase-lev",
+ "lock-free",
+ "scheduler",
+ "scheduling",
+]
+categories = [
+ "algorithms",
+ "concurrency",
+ "data-structures",
+]
license = "MIT OR Apache-2.0"
repository = "https://github.com/crossbeam-rs/crossbeam"
+
[dependencies.cfg-if]
version = "1"
@@ -33,9 +43,13 @@ default-features = false
version = "0.8"
optional = true
default-features = false
+
[dev-dependencies.rand]
version = "0.8"
[features]
default = ["std"]
-std = ["crossbeam-epoch/std", "crossbeam-utils/std"]
+std = [
+ "crossbeam-epoch/std",
+ "crossbeam-utils/std",
+]
diff --git a/vendor/crossbeam-deque/README.md b/vendor/crossbeam-deque/README.md
index 8ad1a7278..23c8794c2 100644
--- a/vendor/crossbeam-deque/README.md
+++ b/vendor/crossbeam-deque/README.md
@@ -8,7 +8,7 @@ https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-deque#license)
https://crates.io/crates/crossbeam-deque)
[![Documentation](https://docs.rs/crossbeam-deque/badge.svg)](
https://docs.rs/crossbeam-deque)
-[![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)
@@ -28,7 +28,7 @@ crossbeam-deque = "0.8"
Crossbeam Deque 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/vendor/crossbeam-deque/src/deque.rs b/vendor/crossbeam-deque/src/deque.rs
index 802a2fef5..bda3bf820 100644
--- a/vendor/crossbeam-deque/src/deque.rs
+++ b/vendor/crossbeam-deque/src/deque.rs
@@ -3,7 +3,7 @@ use std::cmp;
use std::fmt;
use std::iter::FromIterator;
use std::marker::PhantomData;
-use std::mem::{self, MaybeUninit};
+use std::mem::{self, ManuallyDrop, MaybeUninit};
use std::ptr;
use std::sync::atomic::{self, AtomicIsize, AtomicPtr, AtomicUsize, Ordering};
use std::sync::Arc;
@@ -38,9 +38,8 @@ impl<T> Buffer<T> {
fn alloc(cap: usize) -> Buffer<T> {
debug_assert_eq!(cap, cap.next_power_of_two());
- let mut v = Vec::with_capacity(cap);
+ let mut v = ManuallyDrop::new(Vec::with_capacity(cap));
let ptr = v.as_mut_ptr();
- mem::forget(v);
Buffer { ptr, cap }
}
@@ -53,6 +52,8 @@ impl<T> Buffer<T> {
/// Returns a pointer to the task at the specified `index`.
unsafe fn at(&self, index: isize) -> *mut T {
// `self.cap` is always a power of two.
+ // We do all the loads at `MaybeUninit` because we might realize, after loading, that we
+ // don't actually have the right to access this memory.
self.ptr.offset(index & (self.cap - 1) as isize)
}
@@ -62,8 +63,8 @@ impl<T> Buffer<T> {
/// technically speaking a data race and therefore UB. We should use an atomic store here, but
/// that would be more expensive and difficult to implement generically for all types `T`.
/// Hence, as a hack, we use a volatile write instead.
- unsafe fn write(&self, index: isize, task: T) {
- ptr::write_volatile(self.at(index), task)
+ unsafe fn write(&self, index: isize, task: MaybeUninit<T>) {
+ ptr::write_volatile(self.at(index).cast::<MaybeUninit<T>>(), task)
}
/// Reads a task from the specified `index`.
@@ -71,9 +72,9 @@ impl<T> Buffer<T> {
/// This method might be concurrently called with another `write` at the same index, which is
/// technically speaking a data race and therefore UB. We should use an atomic load here, but
/// that would be more expensive and difficult to implement generically for all types `T`.
- /// Hence, as a hack, we use a volatile write instead.
- unsafe fn read(&self, index: isize) -> T {
- ptr::read_volatile(self.at(index))
+ /// Hence, as a hack, we use a volatile load instead.
+ unsafe fn read(&self, index: isize) -> MaybeUninit<T> {
+ ptr::read_volatile(self.at(index).cast::<MaybeUninit<T>>())
}
}
@@ -115,8 +116,8 @@ struct Inner<T> {
impl<T> Drop for Inner<T> {
fn drop(&mut self) {
// Load the back index, front index, and buffer.
- let b = self.back.load(Ordering::Relaxed);
- let f = self.front.load(Ordering::Relaxed);
+ let b = *self.back.get_mut();
+ let f = *self.front.get_mut();
unsafe {
let buffer = self.buffer.load(Ordering::Relaxed, epoch::unprotected());
@@ -406,7 +407,7 @@ impl<T> Worker<T> {
// Write `task` into the slot.
unsafe {
- buffer.write(b, task);
+ buffer.write(b, MaybeUninit::new(task));
}
atomic::fence(Ordering::Release);
@@ -461,7 +462,7 @@ impl<T> Worker<T> {
unsafe {
// Read the popped task.
let buffer = self.buffer.get();
- let task = buffer.read(f);
+ let task = buffer.read(f).assume_init();
// Shrink the buffer if `len - 1` is less than one fourth of the capacity.
if buffer.cap > MIN_CAP && len <= buffer.cap as isize / 4 {
@@ -509,8 +510,8 @@ impl<T> Worker<T> {
)
.is_err()
{
- // Failed. We didn't pop anything.
- mem::forget(task.take());
+ // Failed. We didn't pop anything. Reset to `None`.
+ task.take();
}
// Restore the back index to the original task.
@@ -524,7 +525,7 @@ impl<T> Worker<T> {
}
}
- task
+ task.map(|t| unsafe { t.assume_init() })
}
}
}
@@ -661,12 +662,11 @@ impl<T> Stealer<T> {
.is_err()
{
// We didn't steal this task, forget it.
- mem::forget(task);
return Steal::Retry;
}
// Return the stolen task.
- Steal::Success(task)
+ Steal::Success(unsafe { task.assume_init() })
}
/// Steals a batch of tasks and pushes them into another worker.
@@ -821,7 +821,6 @@ impl<T> Stealer<T> {
.is_err()
{
// We didn't steal this task, forget it and break from the loop.
- mem::forget(task);
batch_size = i;
break;
}
@@ -975,7 +974,6 @@ impl<T> Stealer<T> {
.is_err()
{
// We didn't steal this task, forget it.
- mem::forget(task);
return Steal::Retry;
}
@@ -992,7 +990,6 @@ impl<T> Stealer<T> {
.is_err()
{
// We didn't steal this task, forget it.
- mem::forget(task);
return Steal::Retry;
}
@@ -1037,7 +1034,6 @@ impl<T> Stealer<T> {
.is_err()
{
// We didn't steal this task, forget it and break from the loop.
- mem::forget(tmp);
batch_size = i;
break;
}
@@ -1077,7 +1073,7 @@ impl<T> Stealer<T> {
dest.inner.back.store(dest_b, Ordering::Release);
// Return with success.
- Steal::Success(task)
+ Steal::Success(unsafe { task.assume_init() })
}
}
@@ -1123,6 +1119,11 @@ struct Slot<T> {
}
impl<T> Slot<T> {
+ const UNINIT: Self = Self {
+ task: UnsafeCell::new(MaybeUninit::uninit()),
+ state: AtomicUsize::new(0),
+ };
+
/// Waits until a task is written into the slot.
fn wait_write(&self) {
let backoff = Backoff::new();
@@ -1146,13 +1147,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::task` (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.
@@ -1535,7 +1533,7 @@ impl<T> Injector<T> {
// Read the task.
let slot = (*block).slots.get_unchecked(offset + i);
slot.wait_write();
- let task = slot.task.get().read().assume_init();
+ let task = slot.task.get().read();
// Write it into the destination queue.
dest_buffer.write(dest_b.wrapping_add(i as isize), task);
@@ -1547,7 +1545,7 @@ impl<T> Injector<T> {
// Read the task.
let slot = (*block).slots.get_unchecked(offset + i);
slot.wait_write();
- let task = slot.task.get().read().assume_init();
+ let task = slot.task.get().read();
// Write it into the destination queue.
dest_buffer.write(dest_b.wrapping_add((batch_size - 1 - i) as isize), task);
@@ -1689,7 +1687,7 @@ impl<T> Injector<T> {
// Read the task.
let slot = (*block).slots.get_unchecked(offset);
slot.wait_write();
- let task = slot.task.get().read().assume_init();
+ let task = slot.task.get().read();
match dest.flavor {
Flavor::Fifo => {
@@ -1698,7 +1696,7 @@ impl<T> Injector<T> {
// Read the task.
let slot = (*block).slots.get_unchecked(offset + i + 1);
slot.wait_write();
- let task = slot.task.get().read().assume_init();
+ let task = slot.task.get().read();
// Write it into the destination queue.
dest_buffer.write(dest_b.wrapping_add(i as isize), task);
@@ -1711,7 +1709,7 @@ impl<T> Injector<T> {
// Read the task.
let slot = (*block).slots.get_unchecked(offset + i + 1);
slot.wait_write();
- let task = slot.task.get().read().assume_init();
+ let task = slot.task.get().read();
// Write it into the destination queue.
dest_buffer.write(dest_b.wrapping_add((batch_size - 1 - i) as isize), task);
@@ -1744,7 +1742,7 @@ impl<T> Injector<T> {
}
}
- Steal::Success(task)
+ Steal::Success(task.assume_init())
}
}
@@ -1820,9 +1818,9 @@ impl<T> Injector<T> {
impl<T> Drop for Injector<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);
@@ -1840,7 +1838,7 @@ impl<T> Drop for Injector<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/vendor/crossbeam-deque/src/lib.rs b/vendor/crossbeam-deque/src/lib.rs
index 16bc728b3..b696b5f96 100644
--- a/vendor/crossbeam-deque/src/lib.rs
+++ b/vendor/crossbeam-deque/src/lib.rs
@@ -95,6 +95,7 @@
rust_2018_idioms,
unreachable_pub
)]
+#![allow(clippy::question_mark)] // https://github.com/rust-lang/rust-clippy/issues/8281
#![cfg_attr(not(feature = "std"), no_std)]
use cfg_if::cfg_if;
diff --git a/vendor/crossbeam-deque/tests/fifo.rs b/vendor/crossbeam-deque/tests/fifo.rs
index e2365fb91..f98737b58 100644
--- a/vendor/crossbeam-deque/tests/fifo.rs
+++ b/vendor/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;
@@ -258,8 +268,17 @@ fn no_starvation() {
#[test]
fn destructors() {
+ #[cfg(miri)]
+ const THREADS: usize = 2;
+ #[cfg(not(miri))]
const THREADS: usize = 8;
+ #[cfg(miri)]
+ const COUNT: usize = 500;
+ #[cfg(not(miri))]
const COUNT: usize = 50_000;
+ #[cfg(miri)]
+ const STEPS: usize = 100;
+ #[cfg(not(miri))]
const STEPS: usize = 1000;
struct Elem(usize, Arc<Mutex<Vec<usize>>>);
@@ -330,7 +349,7 @@ fn destructors() {
{
let mut v = dropped.lock().unwrap();
assert_eq!(v.len(), rem);
- v.sort();
+ v.sort_unstable();
for pair in v.windows(2) {
assert_eq!(pair[0] + 1, pair[1]);
}
diff --git a/vendor/crossbeam-deque/tests/injector.rs b/vendor/crossbeam-deque/tests/injector.rs
index 3f74d1bfb..f706a8d9c 100644
--- a/vendor/crossbeam-deque/tests/injector.rs
+++ b/vendor/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();
@@ -58,6 +61,8 @@ fn spsc() {
assert_eq!(i, v);
break;
}
+ #[cfg(miri)]
+ std::hint::spin_loop();
}
}
@@ -73,6 +78,9 @@ fn spsc() {
#[test]
fn mpmc() {
+ #[cfg(miri)]
+ const COUNT: usize = 500;
+ #[cfg(not(miri))]
const COUNT: usize = 25_000;
const THREADS: usize = 4;
@@ -96,6 +104,8 @@ fn mpmc() {
v[n].fetch_add(1, SeqCst);
break;
}
+ #[cfg(miri)]
+ std::hint::spin_loop();
}
}
});
@@ -111,6 +121,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 +165,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 +224,7 @@ fn stress() {
.unwrap();
}
+#[cfg_attr(miri, ignore)] // Miri is too slow
#[test]
fn no_starvation() {
const THREADS: usize = 8;
@@ -269,8 +286,17 @@ fn no_starvation() {
#[test]
fn destructors() {
+ #[cfg(miri)]
+ const THREADS: usize = 2;
+ #[cfg(not(miri))]
const THREADS: usize = 8;
+ #[cfg(miri)]
+ const COUNT: usize = 500;
+ #[cfg(not(miri))]
const COUNT: usize = 50_000;
+ #[cfg(miri)]
+ const STEPS: usize = 100;
+ #[cfg(not(miri))]
const STEPS: usize = 1000;
struct Elem(usize, Arc<Mutex<Vec<usize>>>);
@@ -341,7 +367,7 @@ fn destructors() {
{
let mut v = dropped.lock().unwrap();
assert_eq!(v.len(), rem);
- v.sort();
+ v.sort_unstable();
for pair in v.windows(2) {
assert_eq!(pair[0] + 1, pair[1]);
}
diff --git a/vendor/crossbeam-deque/tests/lifo.rs b/vendor/crossbeam-deque/tests/lifo.rs
index 3e99e95c5..c1a65cd2e 100644
--- a/vendor/crossbeam-deque/tests/lifo.rs
+++ b/vendor/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();
@@ -84,6 +87,8 @@ fn spsc() {
assert_eq!(i, v);
break;
}
+ #[cfg(miri)]
+ std::hint::spin_loop();
}
}
@@ -100,6 +105,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 +149,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 +208,7 @@ fn stress() {
.unwrap();
}
+#[cfg_attr(miri, ignore)] // Miri is too slow
#[test]
fn no_starvation() {
const THREADS: usize = 8;
@@ -258,8 +270,17 @@ fn no_starvation() {
#[test]
fn destructors() {
+ #[cfg(miri)]
+ const THREADS: usize = 2;
+ #[cfg(not(miri))]
const THREADS: usize = 8;
+ #[cfg(miri)]
+ const COUNT: usize = 500;
+ #[cfg(not(miri))]
const COUNT: usize = 50_000;
+ #[cfg(miri)]
+ const STEPS: usize = 100;
+ #[cfg(not(miri))]
const STEPS: usize = 1000;
struct Elem(usize, Arc<Mutex<Vec<usize>>>);
@@ -330,7 +351,7 @@ fn destructors() {
{
let mut v = dropped.lock().unwrap();
assert_eq!(v.len(), rem);
- v.sort();
+ v.sort_unstable();
for pair in v.windows(2) {
assert_eq!(pair[0] + 1, pair[1]);
}