diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 82847d83ad2..b2aa500a0fd 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -1428,39 +1428,76 @@ fn _assert_both() {} _assert_both::(); } -/// Returns the number of hardware threads available to the program. +/// Returns an estimate of the default amount of parallelism a program should use. /// -/// This value should be considered only a hint. +/// Parallelism is a resource. A given machine provides a certain capacity for +/// parallelism, i.e., a bound on the number of computations it can perform +/// simultaneously. This number often corresponds to the amount of CPUs or +/// computer has, but it may diverge in various cases. /// -/// # Platform-specific behavior +/// Host environments such as VMs or container orchestrators may want to +/// restrict the amount of parallelism made available to programs in them. This +/// is often done to limit the potential impact of (unintentionally) +/// resource-intensive programs on other programs running on the same machine. /// -/// If interpreted as the number of actual hardware threads, it may undercount on -/// Windows systems with more than 64 hardware threads. If interpreted as the -/// available concurrency for that process, it may overcount on Windows systems -/// when limited by a process wide affinity mask or job object limitations, and -/// it may overcount on Linux systems when limited by a process wide affinity -/// mask or affected by cgroups limits. +/// # Limitations +/// +/// The purpose of this API is to provide an easy and portable way to query +/// the default amount of parallelism the program should use. Among other things it +/// does not expose information on NUMA regions, does not account for +/// differences in (co)processor capabilities, and will not modify the program's +/// global state in order to more accurately query the amount of available +/// parallelism. +/// +/// The value returned by this function should be considered a simplified +/// approximation of the actual amount of parallelism available at any given +/// time. To get a more detailed or precise overview of the amount of +/// parallelism available to the program, you may wish to use +/// platform-specific APIs as well. The following platform limitations currently +/// apply to `available_parallelism`: +/// +/// On Windows: +/// - It may undercount the amount of parallelism available on systems with more +/// than 64 logical CPUs. However, programs typically need specific support to +/// take advantage of more than 64 logical CPUs, and in the absence of such +/// support, the number returned by this function accurately reflects the +/// number of logical CPUs the program can use by default. +/// - It may overcount the amount of parallelism available on systems limited by +/// process-wide affinity masks, or job object limitations. +/// +/// On Linux: +/// - It may overcount the amount of parallelism available when limited by a +/// process-wide affinity mask, or when affected by cgroup limits. +/// +/// On all targets: +/// - It may overcount the amount of parallelism available when running in a VM +/// with CPU usage limits (e.g. an overcommitted host). /// /// # Errors /// -/// This function will return an error in the following situations, but is not -/// limited to just these cases: +/// This function will, but is not limited to, return errors in the following +/// cases: /// -/// - If the number of hardware threads is not known for the target platform. -/// - The process lacks permissions to view the number of hardware threads -/// available. +/// - If the amount of parallelism is not known for the target platform. +/// - If the program lacks permission to query the amount of parallelism made +/// available to it. /// /// # Examples /// /// ``` /// # #![allow(dead_code)] /// #![feature(available_parallelism)] -/// use std::thread; +/// use std::{io, thread}; /// -/// let count = thread::available_parallelism().map(|n| n.get()).unwrap_or(1); +/// fn main() -> io::Result<()> { +/// let count = thread::available_parallelism()?.get(); +/// assert!(count >= 1_usize); +/// Ok(()) +/// } /// ``` +#[doc(alias = "available_concurrency")] // Alias for a previous name we gave this API on unstable. #[doc(alias = "hardware_concurrency")] // Alias for C++ `std::thread::hardware_concurrency`. -#[doc(alias = "available_concurrency")] // Alias for a name we gave this API on unstable. +#[doc(alias = "num_cpus")] // Alias for a popular ecosystem crate which provides similar functionality. #[unstable(feature = "available_parallelism", issue = "74479")] pub fn available_parallelism() -> io::Result { imp::available_parallelism()