From 7fd29d2d8d411dda44d6c16470972ed9aa590ee7 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 17 Aug 2020 16:14:27 -0700 Subject: [PATCH 1/3] Use crossbeam_deque::Injector instead of crossbeam_queue::SegQueue `Injector` and `SegQueue` are _almost_ identical, down to the very same comments in their implementations. One difference is that `Injector` allocates its first block as soon as it's created, but `SegQueue` waits until its first `push`, which complicates it to allow being `null`. `Injector` also has methods to steal batches into a deque `Worker`, which might be useful to us. At the very least, this lets us trim a dependency. --- rayon-core/Cargo.toml | 1 - rayon-core/src/job.rs | 14 ++++++++++---- rayon-core/src/registry.rs | 24 ++++++++++++++---------- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/rayon-core/Cargo.toml b/rayon-core/Cargo.toml index 8793b946c..bb3836736 100644 --- a/rayon-core/Cargo.toml +++ b/rayon-core/Cargo.toml @@ -18,7 +18,6 @@ categories = ["concurrency"] num_cpus = "1.2" lazy_static = "1" crossbeam-deque = "0.7.2" -crossbeam-queue = "0.2" crossbeam-utils = "0.7" [dev-dependencies] diff --git a/rayon-core/src/job.rs b/rayon-core/src/job.rs index 60a6cc950..d8aae8101 100644 --- a/rayon-core/src/job.rs +++ b/rayon-core/src/job.rs @@ -1,7 +1,7 @@ use crate::latch::Latch; use crate::tlv; use crate::unwind; -use crossbeam_queue::SegQueue; +use crossbeam_deque::{Injector, Steal}; use std::any::Any; use std::cell::UnsafeCell; use std::mem; @@ -191,13 +191,13 @@ impl JobResult { /// Indirect queue to provide FIFO job priority. pub(super) struct JobFifo { - inner: SegQueue, + inner: Injector, } impl JobFifo { pub(super) fn new() -> Self { JobFifo { - inner: SegQueue::new(), + inner: Injector::new(), } } @@ -213,6 +213,12 @@ impl JobFifo { impl Job for JobFifo { unsafe fn execute(this: *const Self) { // We "execute" a queue by executing its first job, FIFO. - (*this).inner.pop().expect("job in fifo queue").execute() + loop { + match (*this).inner.steal() { + Steal::Success(job_ref) => break job_ref.execute(), + Steal::Empty => panic!("FIFO is empty"), + Steal::Retry => {} + } + } } } diff --git a/rayon-core/src/registry.rs b/rayon-core/src/registry.rs index b63a79ff1..0ad6bd325 100644 --- a/rayon-core/src/registry.rs +++ b/rayon-core/src/registry.rs @@ -8,8 +8,7 @@ use crate::{ AcquireThreadHandler, DeadlockHandler, ErrorKind, ExitHandler, PanicHandler, ReleaseThreadHandler, StartHandler, ThreadPoolBuildError, ThreadPoolBuilder, }; -use crossbeam_deque::{Steal, Stealer, Worker}; -use crossbeam_queue::SegQueue; +use crossbeam_deque::{Injector, Steal, Stealer, Worker}; use std::any::Any; use std::cell::Cell; use std::collections::hash_map::DefaultHasher; @@ -135,7 +134,7 @@ where pub struct Registry { thread_infos: Vec, sleep: Sleep, - injected_jobs: SegQueue, + injected_jobs: Injector, panic_handler: Option>, pub(crate) deadlock_handler: Option>, start_handler: Option>, @@ -240,7 +239,7 @@ impl Registry { let registry = Arc::new(Registry { thread_infos: stealers.into_iter().map(ThreadInfo::new).collect(), sleep: Sleep::new(n_threads), - injected_jobs: SegQueue::new(), + injected_jobs: Injector::new(), terminate_latch: CountLatch::new(), panic_handler: builder.take_panic_handler(), deadlock_handler: builder.take_deadlock_handler(), @@ -415,13 +414,18 @@ impl Registry { } fn pop_injected_job(&self, worker_index: usize) -> Option { - let job = self.injected_jobs.pop().ok(); - if job.is_some() { - log!(UninjectedWork { - worker: worker_index - }); + loop { + match self.injected_jobs.steal() { + Steal::Success(job) => { + log!(UninjectedWork { + worker: worker_index + }); + return Some(job); + } + Steal::Empty => return None, + Steal::Retry => {} + } } - job } /// If already in a worker-thread of this registry, just execute `op`. From 8e8af5630a0e280d3210d00ef20911ca5fc912b6 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Mon, 12 Oct 2020 10:47:16 -0700 Subject: [PATCH 2/3] Update crossbeam dependencies (requires Rust 1.36) --- Cargo.toml | 2 +- rayon-core/Cargo.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9cddaa6cb..89323fe83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ exclude = ["ci"] [dependencies] rayon-core = { version = "0.3", path = "rayon-core", package = "rustc-rayon-core" } -crossbeam-deque = "0.7.2" +crossbeam-deque = "0.8.0" # This is a public dependency! [dependencies.either] diff --git a/rayon-core/Cargo.toml b/rayon-core/Cargo.toml index bb3836736..d9353655a 100644 --- a/rayon-core/Cargo.toml +++ b/rayon-core/Cargo.toml @@ -17,8 +17,8 @@ categories = ["concurrency"] [dependencies] num_cpus = "1.2" lazy_static = "1" -crossbeam-deque = "0.7.2" -crossbeam-utils = "0.7" +crossbeam-deque = "0.8.0" +crossbeam-utils = "0.8.0" [dev-dependencies] rand = "0.7" From d79ec987bd3863d79993347459ced072f20a0e9b Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 10 Jan 2022 10:42:50 -0800 Subject: [PATCH 3/3] bump to 0.3.2 and prepare for release --- Cargo.toml | 2 +- rayon-core/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 89323fe83..147ac1bcc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc-rayon" # Reminder to update html_rool_url in lib.rs when updating version -version = "0.3.1" +version = "0.3.2" authors = ["Niko Matsakis ", "Josh Stone "] description = "Simple work-stealing parallelism for Rust - fork for rustc" diff --git a/rayon-core/Cargo.toml b/rayon-core/Cargo.toml index d9353655a..8cb3bb71b 100644 --- a/rayon-core/Cargo.toml +++ b/rayon-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustc-rayon-core" -version = "0.3.1" # reminder to update html_root_url attribute +version = "0.3.2" # reminder to update html_root_url attribute authors = ["Niko Matsakis ", "Josh Stone "] description = "Core APIs for Rayon - fork for rustc"