From 4b03aeaf3b616586909e5d97c12921f6b23159de Mon Sep 17 00:00:00 2001 From: Jeff Vander Stoep Date: Tue, 6 Feb 2024 14:04:14 +0100 Subject: Upgrade rayon to 1.8.1 This project was upgraded with external_updater. Usage: tools/external_updater/updater.sh update external/rust/crates/rayon For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md Test: TreeHugger Change-Id: I69efc8d2d4e6c7140c769cbd4fc83f755b320c97 --- .cargo_vcs_info.json | 2 +- Android.bp | 2 +- Cargo.toml | 17 ++++++++++++---- Cargo.toml.orig | 16 +++++++++++---- METADATA | 25 ++++++++++------------- README.md | 6 +++--- RELEASES.md | 21 +++++++++++++++++++ src/iter/extend.rs | 10 ++++++++++ src/iter/from_par_iter.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++++ src/iter/mod.rs | 10 +++++----- src/iter/par_bridge.rs | 12 ++++++++++- src/iter/product.rs | 2 +- src/iter/sum.rs | 2 +- src/iter/test.rs | 2 +- src/lib.rs | 2 +- src/slice/quicksort.rs | 42 +++++++++++++++++++++----------------- 16 files changed, 167 insertions(+), 55 deletions(-) diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 34dd103..45c6796 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,6 +1,6 @@ { "git": { - "sha1": "6236214d717694917e77aa1c16d91176b9bc2fff" + "sha1": "7df6d5b8493a5fdb257565cab26dacdfe08ec8aa" }, "path_in_vcs": "" } \ No newline at end of file diff --git a/Android.bp b/Android.bp index db51fec..d0daecf 100644 --- a/Android.bp +++ b/Android.bp @@ -42,7 +42,7 @@ rust_library { host_supported: true, crate_name: "rayon", cargo_env_compat: true, - cargo_pkg_version: "1.7.0", + cargo_pkg_version: "1.8.1", srcs: ["src/lib.rs"], edition: "2021", rustlibs: [ diff --git a/Cargo.toml b/Cargo.toml index 9b0e7b6..a1761f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,9 +11,9 @@ [package] edition = "2021" -rust-version = "1.59" +rust-version = "1.63" name = "rayon" -version = "1.7.0" +version = "1.8.1" authors = [ "Niko Matsakis ", "Josh Stone ", @@ -22,7 +22,6 @@ exclude = [ "/ci/*", "/scripts/*", "/.github/*", - "/bors.toml", ] description = "Simple work-stealing parallelism for Rust" documentation = "https://docs.rs/rayon/" @@ -43,10 +42,20 @@ version = "1.0" default-features = false [dependencies.rayon-core] -version = "1.11.0" +version = "1.12.1" + +[dependencies.wasm_sync] +version = "0.1.0" +optional = true [dev-dependencies.rand] version = "0.8" [dev-dependencies.rand_xorshift] version = "0.3" + +[features] +web_spin_lock = [ + "dep:wasm_sync", + "rayon-core/web_spin_lock", +] diff --git a/Cargo.toml.orig b/Cargo.toml.orig index a6ccc97..293e64b 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,10 +1,10 @@ [package] name = "rayon" -version = "1.7.0" +version = "1.8.1" authors = ["Niko Matsakis ", "Josh Stone "] description = "Simple work-stealing parallelism for Rust" -rust-version = "1.59" +rust-version = "1.63" edition = "2021" license = "MIT OR Apache-2.0" repository = "https://github.com/rayon-rs/rayon" @@ -12,20 +12,28 @@ documentation = "https://docs.rs/rayon/" readme = "README.md" keywords = ["parallel", "thread", "concurrency", "join", "performance"] categories = ["concurrency"] -exclude = ["/ci/*", "/scripts/*", "/.github/*", "/bors.toml"] +exclude = ["/ci/*", "/scripts/*", "/.github/*"] [workspace] members = ["rayon-demo", "rayon-core"] exclude = ["ci"] [dependencies] -rayon-core = { version = "1.11.0", path = "rayon-core" } +rayon-core = { version = "1.12.1", path = "rayon-core" } +wasm_sync = { version = "0.1.0", optional = true } # This is a public dependency! [dependencies.either] version = "1.0" default-features = false +[features] +# This feature switches to a spin-lock implementation on the browser's +# main thread to avoid the forbidden `atomics.wait`. +# +# Only useful on the `wasm32-unknown-unknown` target. +web_spin_lock = ["dep:wasm_sync", "rayon-core/web_spin_lock"] + [dev-dependencies] rand = "0.8" rand_xorshift = "0.3" diff --git a/METADATA b/METADATA index 94b529f..4b10622 100644 --- a/METADATA +++ b/METADATA @@ -1,23 +1,20 @@ # This project was upgraded with external_updater. -# Usage: tools/external_updater/updater.sh update rust/crates/rayon -# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md +# Usage: tools/external_updater/updater.sh update external/rust/crates/rayon +# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md name: "rayon" description: "Simple work-stealing parallelism for Rust" third_party { - url { - type: HOMEPAGE - value: "https://crates.io/crates/rayon" - } - url { - type: ARCHIVE - value: "https://static.crates.io/crates/rayon/rayon-1.7.0.crate" - } - version: "1.7.0" license_type: NOTICE last_upgrade_date { - year: 2023 - month: 4 - day: 3 + year: 2024 + month: 2 + day: 6 + } + homepage: "https://crates.io/crates/rayon" + identifier { + type: "Archive" + value: "https://static.crates.io/crates/rayon/rayon-1.8.1.crate" + version: "1.8.1" } } diff --git a/README.md b/README.md index 7f925bc..082f6a4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Rayon crate](https://img.shields.io/crates/v/rayon.svg)](https://crates.io/crates/rayon) [![Rayon documentation](https://docs.rs/rayon/badge.svg)](https://docs.rs/rayon) -![minimum rustc 1.59](https://img.shields.io/badge/rustc-1.59+-red.svg) +![minimum rustc 1.63](https://img.shields.io/badge/rustc-1.63+-red.svg) [![build status](https://github.com/rayon-rs/rayon/workflows/master/badge.svg)](https://github.com/rayon-rs/rayon/actions) [![Join the chat at https://gitter.im/rayon-rs/Lobby](https://badges.gitter.im/rayon-rs/Lobby.svg)](https://gitter.im/rayon-rs/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) @@ -71,7 +71,7 @@ as: ```toml [dependencies] -rayon = "1.7" +rayon = "1.8" ``` To use the parallel iterator APIs, a number of traits have to be in @@ -84,7 +84,7 @@ just add: use rayon::prelude::*; ``` -Rayon currently requires `rustc 1.59.0` or greater. +Rayon currently requires `rustc 1.63.0` or greater. ### Usage with WebAssembly diff --git a/RELEASES.md b/RELEASES.md index 28b476d..9b71516 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,24 @@ +# Release rayon 1.8.1 / rayon-core 1.12.1 (2024-01-17) + +- The new `"web_spin_lock"` crate feature makes mutexes spin on the main + browser thread in WebAssembly, rather than suffer an error about forbidden + `atomics.wait` if they were to block in that context. Thanks @RReverser! + +# Release rayon 1.8.0 / rayon-core 1.12.0 (2023-09-20) + +- The minimum supported `rustc` is now 1.63. +- Added `ThreadPoolBuilder::use_current_thread` to use the builder thread as + part of the new thread pool. That thread does not run the pool's main loop, + but it may participate in work-stealing if it yields to rayon in some way. +- Implemented `FromParallelIterator` for `Box<[T]>`, `Rc<[T]>`, and + `Arc<[T]>`, as well as `FromParallelIterator>` and + `ParallelExtend>` for `String`. +- `ThreadPoolBuilder::build_scoped` now uses `std::thread::scope`. +- The default number of threads is now determined using + `std::thread::available_parallelism` instead of the `num_cpus` crate. +- The internal logging facility has been removed, reducing bloat for all users. +- Many smaller performance tweaks and documentation updates. + # Release rayon 1.7.0 / rayon-core 1.11.0 (2023-03-03) - The minimum supported `rustc` is now 1.59. diff --git a/src/iter/extend.rs b/src/iter/extend.rs index 1769d47..a264528 100644 --- a/src/iter/extend.rs +++ b/src/iter/extend.rs @@ -500,6 +500,16 @@ impl ParallelExtend for String { } } +/// Extends a string with boxed strings from a parallel iterator. +impl ParallelExtend> for String { + fn par_extend(&mut self, par_iter: I) + where + I: IntoParallelIterator>, + { + extend!(self, par_iter, string_extend); + } +} + /// Extends a string with string slices from a parallel iterator. impl<'a> ParallelExtend> for String { fn par_extend(&mut self, par_iter: I) diff --git a/src/iter/from_par_iter.rs b/src/iter/from_par_iter.rs index 3240f32..49afd6c 100644 --- a/src/iter/from_par_iter.rs +++ b/src/iter/from_par_iter.rs @@ -6,6 +6,8 @@ use std::collections::LinkedList; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::collections::{BinaryHeap, VecDeque}; use std::hash::{BuildHasher, Hash}; +use std::rc::Rc; +use std::sync::Arc; /// Creates an empty default collection and extends it. fn collect_extended(par_iter: I) -> C @@ -31,6 +33,45 @@ where } } +/// Collects items from a parallel iterator into a boxed slice. +impl FromParallelIterator for Box<[T]> +where + T: Send, +{ + fn from_par_iter(par_iter: I) -> Self + where + I: IntoParallelIterator, + { + Vec::from_par_iter(par_iter).into() + } +} + +/// Collects items from a parallel iterator into a reference-counted slice. +impl FromParallelIterator for Rc<[T]> +where + T: Send, +{ + fn from_par_iter(par_iter: I) -> Self + where + I: IntoParallelIterator, + { + Vec::from_par_iter(par_iter).into() + } +} + +/// Collects items from a parallel iterator into an atomically-reference-counted slice. +impl FromParallelIterator for Arc<[T]> +where + T: Send, +{ + fn from_par_iter(par_iter: I) -> Self + where + I: IntoParallelIterator, + { + Vec::from_par_iter(par_iter).into() + } +} + /// Collects items from a parallel iterator into a vecdeque. impl FromParallelIterator for VecDeque where @@ -174,6 +215,16 @@ impl FromParallelIterator for String { } } +/// Collects boxed strings from a parallel iterator into one large string. +impl FromParallelIterator> for String { + fn from_par_iter(par_iter: I) -> Self + where + I: IntoParallelIterator>, + { + collect_extended(par_iter) + } +} + /// Collects string slices from a parallel iterator into a string. impl<'a> FromParallelIterator> for String { fn from_par_iter(par_iter: I) -> Self diff --git a/src/iter/mod.rs b/src/iter/mod.rs index e60ea16..7b5a29a 100644 --- a/src/iter/mod.rs +++ b/src/iter/mod.rs @@ -1547,7 +1547,7 @@ pub trait ParallelIterator: Sized + Send { /// Computes the maximum of all the items in the iterator with respect to /// the given comparison function. If the iterator is empty, `None` is - /// returned; otherwise, `Some(min)` is returned. + /// returned; otherwise, `Some(max)` is returned. /// /// Note that the order in which the items will be reduced is not /// specified, so if the comparison function is not associative, then @@ -2392,7 +2392,7 @@ impl IntoParallelIterator for T { #[allow(clippy::len_without_is_empty)] pub trait IndexedParallelIterator: ParallelIterator { /// Collects the results of the iterator into the specified - /// vector. The vector is always truncated before execution + /// vector. The vector is always cleared before execution /// begins. If possible, reusing the vector across calls can lead /// to better performance since it reuses the same backing buffer. /// @@ -2401,7 +2401,7 @@ pub trait IndexedParallelIterator: ParallelIterator { /// ``` /// use rayon::prelude::*; /// - /// // any prior data will be truncated + /// // any prior data will be cleared /// let mut vec = vec![-1, -2, -3]; /// /// (0..5).into_par_iter() @@ -2414,7 +2414,7 @@ pub trait IndexedParallelIterator: ParallelIterator { } /// Unzips the results of the iterator into the specified - /// vectors. The vectors are always truncated before execution + /// vectors. The vectors are always cleared before execution /// begins. If possible, reusing the vectors across calls can lead /// to better performance since they reuse the same backing buffer. /// @@ -2423,7 +2423,7 @@ pub trait IndexedParallelIterator: ParallelIterator { /// ``` /// use rayon::prelude::*; /// - /// // any prior data will be truncated + /// // any prior data will be cleared /// let mut left = vec![42; 10]; /// let mut right = vec![-1; 10]; /// diff --git a/src/iter/par_bridge.rs b/src/iter/par_bridge.rs index 8398274..17bc15b 100644 --- a/src/iter/par_bridge.rs +++ b/src/iter/par_bridge.rs @@ -1,6 +1,11 @@ -use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; +#[cfg(not(feature = "web_spin_lock"))] use std::sync::Mutex; +#[cfg(feature = "web_spin_lock")] +use wasm_sync::Mutex; + +use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; + use crate::iter::plumbing::{bridge_unindexed, Folder, UnindexedConsumer, UnindexedProducer}; use crate::iter::ParallelIterator; use crate::{current_num_threads, current_thread_index}; @@ -13,6 +18,11 @@ use crate::{current_num_threads, current_thread_index}; /// `par_iter` instead. However, it can still be useful for iterators that are difficult to /// parallelize by other means, like channels or file or network I/O. /// +/// Iterator items are pulled by `next()` one at a time, synchronized from each thread that is +/// ready for work, so this may become a bottleneck if the serial iterator can't keep up with the +/// parallel demand. The items are not buffered by `IterBridge`, so it's fine to use this with +/// large or even unbounded iterators. +/// /// The resulting iterator is not guaranteed to keep the order of the original iterator. /// /// # Examples diff --git a/src/iter/product.rs b/src/iter/product.rs index a3d0727..e081be0 100644 --- a/src/iter/product.rs +++ b/src/iter/product.rs @@ -13,7 +13,7 @@ where } fn mul(left: T, right: T) -> T { - iter::once(left).chain(iter::once(right)).product() + [left, right].into_iter().product() } struct ProductConsumer { diff --git a/src/iter/sum.rs b/src/iter/sum.rs index a73e0bf..ddae810 100644 --- a/src/iter/sum.rs +++ b/src/iter/sum.rs @@ -13,7 +13,7 @@ where } fn add(left: T, right: T) -> T { - iter::once(left).chain(iter::once(right)).sum() + [left, right].into_iter().sum() } struct SumConsumer { diff --git a/src/iter/test.rs b/src/iter/test.rs index c72068d..45fb971 100644 --- a/src/iter/test.rs +++ b/src/iter/test.rs @@ -654,7 +654,7 @@ fn check_partial_cmp_late_nan_direct() { } #[test] -fn check_partial_cmp_late_nane_to_seq() { +fn check_partial_cmp_late_nan_to_seq() { let a = vec![0.0, f64::NAN]; let b = vec![1.0, 1.0]; diff --git a/src/lib.rs b/src/lib.rs index 86f997b..dc7fcc0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -152,7 +152,7 @@ impl SendPtr { // Implement Clone without the T: Clone bound from the derive impl Clone for SendPtr { fn clone(&self) -> Self { - Self(self.0) + *self } } diff --git a/src/slice/quicksort.rs b/src/slice/quicksort.rs index d71079e..2bfc350 100644 --- a/src/slice/quicksort.rs +++ b/src/slice/quicksort.rs @@ -5,16 +5,34 @@ //! `rayon_core::join`. use std::cmp; +use std::marker::PhantomData; use std::mem::{self, MaybeUninit}; use std::ptr; /// When dropped, copies from `src` into `dest`. -struct CopyOnDrop { +#[must_use] +struct CopyOnDrop<'a, T> { src: *const T, dest: *mut T, + /// `src` is often a local pointer here, make sure we have appropriate + /// PhantomData so that dropck can protect us. + marker: PhantomData<&'a mut T>, } -impl Drop for CopyOnDrop { +impl<'a, T> CopyOnDrop<'a, T> { + /// Construct from a source pointer and a destination + /// Assumes dest lives longer than src, since there is no easy way to + /// copy down lifetime information from another pointer + unsafe fn new(src: &'a T, dest: *mut T) -> Self { + CopyOnDrop { + src, + dest, + marker: PhantomData, + } + } +} + +impl Drop for CopyOnDrop<'_, T> { fn drop(&mut self) { // SAFETY: This is a helper class. // Please refer to its usage for correctness. @@ -54,10 +72,7 @@ where // into the slice. let tmp = mem::ManuallyDrop::new(ptr::read(v.get_unchecked(0))); let v = v.as_mut_ptr(); - let mut hole = CopyOnDrop { - src: &*tmp, - dest: v.add(1), - }; + let mut hole = CopyOnDrop::new(&*tmp, v.add(1)); ptr::copy_nonoverlapping(v.add(1), v.add(0), 1); for i in 2..len { @@ -103,10 +118,7 @@ where // into the slice. let tmp = mem::ManuallyDrop::new(ptr::read(v.get_unchecked(len - 1))); let v = v.as_mut_ptr(); - let mut hole = CopyOnDrop { - src: &*tmp, - dest: v.add(len - 2), - }; + let mut hole = CopyOnDrop::new(&*tmp, v.add(len - 2)); ptr::copy_nonoverlapping(v.add(len - 2), v.add(len - 1), 1); for i in (0..len - 2).rev() { @@ -510,10 +522,7 @@ where // SAFETY: `pivot` is a reference to the first element of `v`, so `ptr::read` is safe. let tmp = mem::ManuallyDrop::new(unsafe { ptr::read(pivot) }); - let _pivot_guard = CopyOnDrop { - src: &*tmp, - dest: pivot, - }; + let _pivot_guard = unsafe { CopyOnDrop::new(&*tmp, pivot) }; let pivot = &*tmp; // Find the first pair of out-of-order elements. @@ -569,10 +578,7 @@ where // operation panics, the pivot will be automatically written back into the slice. // SAFETY: The pointer here is valid because it is obtained from a reference to a slice. let tmp = mem::ManuallyDrop::new(unsafe { ptr::read(pivot) }); - let _pivot_guard = CopyOnDrop { - src: &*tmp, - dest: pivot, - }; + let _pivot_guard = unsafe { CopyOnDrop::new(&*tmp, pivot) }; let pivot = &*tmp; // Now partition the slice. -- cgit v1.2.3