+//! Rayon-core houses the core stable APIs of Rayon.
//!
-//! [Under construction](https://github.com/rayon-rs/rayon/issues/231)
+//! These APIs have been mirrored in the Rayon crate and it is recommended to use these from there.
+//!
+//! [`join`] is used to take two closures and potentially run them in parallel.
+//! - It will run in parallel if task B gets stolen before task A can finish.
+//! - It will run sequentially if task A finishes before task B is stolen and can continue on task B.
+//!
+//! [`scope`] creates a scope in which you can run any number of parallel tasks.
+//! These tasks can spawn nested tasks and scopes, but given the nature of work stealing, the order of execution can not be guaranteed.
+//! The scope will exist until all tasks spawned within the scope have been completed.
+//!
+//! [`spawn`] add a task into the 'static' or 'global' scope, or a local scope created by the [`scope()`] function.
+//!
+//! [`ThreadPool`] can be used to create your own thread pools (using [`ThreadPoolBuilder`]) or to customize the global one.
+//! Tasks spawned within the pool (using [`install()`], [`join()`], etc.) will be added to a deque,
+//! where it becomes available for work stealing from other threads in the local threadpool.
+//!
+//! [`join`]: fn.join.html
+//! [`scope`]: fn.scope.html
+//! [`scope()`]: fn.scope.html
+//! [`spawn`]: fn.spawn.html
+//! [`ThreadPool`]: struct.threadpool.html
+//! [`install()`]: struct.ThreadPool.html#method.install
+//! [`spawn()`]: struct.ThreadPool.html#method.spawn
+//! [`join()`]: struct.ThreadPool.html#method.join
+//! [`ThreadPoolBuilder`]: struct.ThreadPoolBuilder.html
//!
//! ## Restricting multiple versions
//!
//! conflicting requirements will need to be resolved before the build will
//! succeed.
-#![doc(html_root_url = "https://docs.rs/rayon-core/1.5")]
+#![doc(html_root_url = "https://docs.rs/rayon-core/1.9")]
#![deny(missing_debug_implementations)]
#![deny(missing_docs)]
#![deny(unreachable_pub)]
+#![warn(rust_2018_idioms)]
use std::any::Any;
use std::env;
use std::marker::PhantomData;
use std::str::FromStr;
-extern crate crossbeam_deque;
-extern crate crossbeam_queue;
-extern crate crossbeam_utils;
-#[cfg(any(debug_assertions, rayon_unstable))]
-#[macro_use]
-extern crate lazy_static;
-extern crate num_cpus;
-
-#[cfg(test)]
-extern crate rand;
-#[cfg(test)]
-extern crate rand_xorshift;
-
#[macro_use]
mod log;
#[macro_use]
mod spawn;
mod thread_pool;
mod unwind;
-mod util;
mod compile_fail;
mod test;
-#[cfg(rayon_unstable)]
-pub mod internal;
-pub use join::{join, join_context};
-pub use registry::ThreadBuilder;
-pub use scope::{scope, Scope};
-pub use scope::{scope_fifo, ScopeFifo};
-pub use spawn::{spawn, spawn_fifo};
-pub use thread_pool::current_thread_has_pending_tasks;
-pub use thread_pool::current_thread_index;
-pub use thread_pool::ThreadPool;
+pub use self::join::{join, join_context};
+pub use self::registry::ThreadBuilder;
+pub use self::scope::{in_place_scope, scope, Scope};
+pub use self::scope::{in_place_scope_fifo, scope_fifo, ScopeFifo};
+pub use self::spawn::{spawn, spawn_fifo};
+pub use self::thread_pool::current_thread_has_pending_tasks;
+pub use self::thread_pool::current_thread_index;
+pub use self::thread_pool::ThreadPool;
+
+use self::registry::{CustomSpawn, DefaultSpawn, ThreadSpawn};
-use registry::{CustomSpawn, DefaultSpawn, ThreadSpawn};
+/// Returns the maximum number of threads that Rayon supports in a single thread-pool.
+///
+/// If a higher thread count is requested by calling `ThreadPoolBuilder::num_threads` or by setting
+/// the `RAYON_NUM_THREADS` environment variable, then it will be reduced to this maximum.
+///
+/// The value may vary between different targets, and is subject to change in new Rayon versions.
+pub fn max_num_threads() -> usize {
+ // We are limited by the bits available in the sleep counter's `AtomicUsize`.
+ crate::sleep::THREADS_MAX
+}
/// Returns the number of threads in the current registry. If this
/// code is executing within a Rayon thread-pool, then this will be
///
/// [snt]: struct.ThreadPoolBuilder.html#method.num_threads
pub fn current_num_threads() -> usize {
- ::registry::Registry::current_num_threads()
+ crate::registry::Registry::current_num_threads()
}
/// Error when initializing a thread pool.
panic_handler: Option<Box<PanicHandler>>,
/// Closure to compute the name of a thread.
- get_thread_name: Option<Box<FnMut(usize) -> String>>,
+ get_thread_name: Option<Box<dyn FnMut(usize) -> String>>,
/// The stack size for the created worker threads
stack_size: Option<usize>,
/// The type for a panic handling closure. Note that this same closure
/// may be invoked multiple times in parallel.
-type PanicHandler = Fn(Box<Any + Send>) + Send + Sync;
+type PanicHandler = dyn Fn(Box<dyn Any + Send>) + Send + Sync;
/// The type for a closure that gets invoked when a thread starts. The
/// closure is passed the index of the thread on which it is invoked.
/// Note that this same closure may be invoked multiple times in parallel.
-type StartHandler = Fn(usize) + Send + Sync;
+type StartHandler = dyn Fn(usize) + Send + Sync;
/// The type for a closure that gets invoked when a thread exits. The
/// closure is passed the index of the thread on which is is invoked.
/// Note that this same closure may be invoked multiple times in parallel.
-type ExitHandler = Fn(usize) + Send + Sync;
+type ExitHandler = dyn Fn(usize) + Send + Sync;
// NB: We can't `#[derive(Default)]` because `S` is left ambiguous.
impl Default for ThreadPoolBuilder {
where
S: ThreadSpawn,
{
- /// Create a new `ThreadPool` initialized using this configuration.
+ /// Creates a new `ThreadPool` initialized using this configuration.
pub fn build(self) -> Result<ThreadPool, ThreadPoolBuildError> {
ThreadPool::build(self)
}
}
impl ThreadPoolBuilder {
- /// Create a scoped `ThreadPool` initialized using this configuration.
+ /// Creates a scoped `ThreadPool` initialized using this configuration.
///
/// This is a convenience function for building a pool using [`crossbeam::scope`]
/// to spawn threads in a [`spawn_handler`](#method.spawn_handler).
/// A scoped pool may be useful in combination with scoped thread-local variables.
///
/// ```
- /// #[macro_use]
- /// extern crate scoped_tls;
/// # use rayon_core as rayon;
///
- /// scoped_thread_local!(static POOL_DATA: Vec<i32>);
+ /// scoped_tls::scoped_thread_local!(static POOL_DATA: Vec<i32>);
///
/// fn main() -> Result<(), rayon::ThreadPoolBuildError> {
/// let pool_data = vec![1, 2, 3];
}
impl<S> ThreadPoolBuilder<S> {
- /// Set a custom function for spawning threads.
+ /// Sets a custom function for spawning threads.
///
/// Note that the threads will not exit until after the pool is dropped. It
/// is up to the caller to wait for thread termination if that is important
Some(f(index))
}
- /// Set a closure which takes a thread index and returns
+ /// Sets a closure which takes a thread index and returns
/// the thread's name.
pub fn thread_name<F>(mut self, closure: F) -> Self
where
self
}
- /// Set the number of threads to be used in the rayon threadpool.
+ /// Sets the number of threads to be used in the rayon threadpool.
///
/// If you specify a non-zero number of threads using this
/// function, then the resulting thread-pools are guaranteed to
/// in a call to `std::panic::catch_unwind()`.
pub fn panic_handler<H>(mut self, panic_handler: H) -> Self
where
- H: Fn(Box<Any + Send>) + Send + Sync + 'static,
+ H: Fn(Box<dyn Any + Send>) + Send + Sync + 'static,
{
self.panic_handler = Some(Box::new(panic_handler));
self
self.stack_size
}
- /// Set the stack size of the worker threads
+ /// Sets the stack size of the worker threads
pub fn stack_size(mut self, stack_size: usize) -> Self {
self.stack_size = Some(stack_size);
self
self.start_handler.take()
}
- /// Set a callback to be invoked on thread start.
+ /// Sets a callback to be invoked on thread start.
///
/// The closure is passed the index of the thread on which it is invoked.
/// Note that this same closure may be invoked multiple times in parallel.
self.exit_handler.take()
}
- /// Set a callback to be invoked on thread exit.
+ /// Sets a callback to be invoked on thread exit.
///
/// The closure is passed the index of the thread on which it is invoked.
/// Note that this same closure may be invoked multiple times in parallel.
}
/// Deprecated in favor of `ThreadPoolBuilder::build`.
- pub fn build(self) -> Result<ThreadPool, Box<Error + 'static>> {
+ pub fn build(self) -> Result<ThreadPool, Box<dyn Error + 'static>> {
self.builder.build().map_err(Box::from)
}
/// Deprecated in favor of `ThreadPoolBuilder::panic_handler`.
pub fn panic_handler<H>(mut self, panic_handler: H) -> Configuration
where
- H: Fn(Box<Any + Send>) + Send + Sync + 'static,
+ H: Fn(Box<dyn Any + Send>) + Send + Sync + 'static,
{
self.builder = self.builder.panic_handler(panic_handler);
self
}
}
+const GLOBAL_POOL_ALREADY_INITIALIZED: &str =
+ "The global thread pool has already been initialized.";
+
impl Error for ThreadPoolBuildError {
+ #[allow(deprecated)]
fn description(&self) -> &str {
match self.kind {
- ErrorKind::GlobalPoolAlreadyInitialized => {
- "The global thread pool has already been initialized."
- }
+ ErrorKind::GlobalPoolAlreadyInitialized => GLOBAL_POOL_ALREADY_INITIALIZED,
ErrorKind::IOError(ref e) => e.description(),
}
}
+
+ fn source(&self) -> Option<&(dyn Error + 'static)> {
+ match &self.kind {
+ ErrorKind::GlobalPoolAlreadyInitialized => None,
+ ErrorKind::IOError(e) => Some(e),
+ }
+ }
}
impl fmt::Display for ThreadPoolBuildError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self.kind {
- ErrorKind::IOError(ref e) => e.fmt(f),
- _ => self.description().fmt(f),
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match &self.kind {
+ ErrorKind::GlobalPoolAlreadyInitialized => GLOBAL_POOL_ALREADY_INITIALIZED.fmt(f),
+ ErrorKind::IOError(e) => e.fmt(f),
}
}
}
/// Deprecated in favor of `ThreadPoolBuilder::build_global`.
#[deprecated(note = "use `ThreadPoolBuilder::build_global`")]
#[allow(deprecated)]
-pub fn initialize(config: Configuration) -> Result<(), Box<Error>> {
+pub fn initialize(config: Configuration) -> Result<(), Box<dyn Error>> {
config.into_builder().build_global().map_err(Box::from)
}
impl<S> fmt::Debug for ThreadPoolBuilder<S> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let ThreadPoolBuilder {
ref num_threads,
ref get_thread_name,
// output.
struct ClosurePlaceholder;
impl fmt::Debug for ClosurePlaceholder {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("<closure>")
}
}
#[allow(deprecated)]
impl fmt::Debug for Configuration {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.builder.fmt(f)
}
}