From b99b00eb302ae6ff19ca97d32b1e594143f43a60 Mon Sep 17 00:00:00 2001 From: Lucio Franco Date: Sat, 19 Dec 2020 11:04:04 -0500 Subject: [PATCH] rt: change `max_threads` to `max_blocking_threads` (#3287) Fixes #2802 --- tokio/src/runtime/builder.rs | 34 ++++++++++++++++------------------ tokio/tests/rt_threaded.rs | 15 ++++++++++++--- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/tokio/src/runtime/builder.rs b/tokio/src/runtime/builder.rs index b445c20b4..1f8892eaf 100644 --- a/tokio/src/runtime/builder.rs +++ b/tokio/src/runtime/builder.rs @@ -53,7 +53,7 @@ pub struct Builder { worker_threads: Option, /// Cap on thread usage. - max_threads: usize, + max_blocking_threads: usize, /// Name fn used for threads spawned by the runtime. pub(super) thread_name: ThreadNameFn, @@ -113,7 +113,7 @@ impl Builder { // Default to lazy auto-detection (one thread per CPU core) worker_threads: None, - max_threads: 512, + max_blocking_threads: 512, // Default thread name thread_name: std::sync::Arc::new(|| "tokio-runtime-worker".into()), @@ -209,22 +209,22 @@ impl Builder { self } - /// Specifies limit for threads, spawned by the Runtime. + /// Specifies limit for threads spawned by the Runtime used for blocking operations. /// - /// This is number of threads to be used by Runtime, including `core_threads` - /// Having `max_threads` less than `worker_threads` results in invalid configuration - /// when building multi-threaded `Runtime`, which would cause a panic. /// - /// Similarly to the `worker_threads`, this number should be between 0 and 32,768. + /// Similarly to the `worker_threads`, this number should be between 1 and 32,768. /// /// The default value is 512. /// - /// When multi-threaded runtime is not used, will act as limit on additional threads. + /// Otherwise as `worker_threads` are always active, it limits additional threads (e.g. for + /// blocking annotations). /// - /// Otherwise as `core_threads` are always active, it limits additional threads (e.g. for - /// blocking annotations) as `max_threads - core_threads`. - pub fn max_threads(&mut self, val: usize) -> &mut Self { - self.max_threads = val; + /// # Panic + /// + /// This will panic if `val` is not larger than `0`. + pub fn max_blocking_threads(&mut self, val: usize) -> &mut Self { + assert!(val > 0, "Max blocking threads cannot be set to 0"); + self.max_blocking_threads = val; self } @@ -424,7 +424,7 @@ impl Builder { let spawner = Spawner::Basic(scheduler.spawner().clone()); // Blocking pool - let blocking_pool = blocking::create_blocking_pool(self, self.max_threads); + let blocking_pool = blocking::create_blocking_pool(self, self.max_blocking_threads); let blocking_spawner = blocking_pool.spawner().clone(); Ok(Runtime { @@ -495,10 +495,8 @@ cfg_rt_multi_thread! { use crate::loom::sys::num_cpus; use crate::runtime::{Kind, ThreadPool}; use crate::runtime::park::Parker; - use std::cmp; - let core_threads = self.worker_threads.unwrap_or_else(|| cmp::min(self.max_threads, num_cpus())); - assert!(core_threads <= self.max_threads, "Core threads number cannot be above max limit"); + let core_threads = self.worker_threads.unwrap_or_else(num_cpus); let (driver, resources) = driver::Driver::new(self.get_cfg())?; @@ -506,7 +504,7 @@ cfg_rt_multi_thread! { let spawner = Spawner::ThreadPool(scheduler.spawner().clone()); // Create the blocking pool - let blocking_pool = blocking::create_blocking_pool(self, self.max_threads); + let blocking_pool = blocking::create_blocking_pool(self, self.max_blocking_threads + core_threads); let blocking_spawner = blocking_pool.spawner().clone(); // Create the runtime handle @@ -536,7 +534,7 @@ impl fmt::Debug for Builder { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt.debug_struct("Builder") .field("worker_threads", &self.worker_threads) - .field("max_threads", &self.max_threads) + .field("max_blocking_threads", &self.max_blocking_threads) .field( "thread_name", &" String + Send + Sync + 'static>", diff --git a/tokio/tests/rt_threaded.rs b/tokio/tests/rt_threaded.rs index 54ec09ad0..19b381cb9 100644 --- a/tokio/tests/rt_threaded.rs +++ b/tokio/tests/rt_threaded.rs @@ -331,7 +331,7 @@ fn coop_and_block_in_place() { // runtime worker yielded as part of `block_in_place` and guarantees the // same thread will reclaim the worker at the end of the // `block_in_place` call. - .max_threads(1) + .max_blocking_threads(1) .build() .unwrap(); @@ -375,9 +375,18 @@ fn coop_and_block_in_place() { // Testing this does not panic #[test] -fn max_threads() { +fn max_blocking_threads() { let _rt = tokio::runtime::Builder::new_multi_thread() - .max_threads(1) + .max_blocking_threads(1) + .build() + .unwrap(); +} + +#[test] +#[should_panic] +fn max_blocking_threads_set_to_zero() { + let _rt = tokio::runtime::Builder::new_multi_thread() + .max_blocking_threads(0) .build() .unwrap(); }