From b5de84d19b4316caccfe13aa7552d895bdd7f046 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Mon, 16 Sep 2024 22:15:44 +0200 Subject: [PATCH] runtime: box futures larger than 16k on release mode (#6826) --- tokio/src/runtime/blocking/pool.rs | 13 +++--- tokio/src/runtime/handle.rs | 4 +- tokio/src/runtime/mod.rs | 6 ++- tokio/src/runtime/runtime.rs | 4 +- tokio/src/task/builder.rs | 68 ++++++++++++++---------------- tokio/src/task/local.rs | 4 +- tokio/src/task/spawn.rs | 2 +- 7 files changed, 49 insertions(+), 52 deletions(-) diff --git a/tokio/src/runtime/blocking/pool.rs b/tokio/src/runtime/blocking/pool.rs index 8bd44278e2a..f8466a19bd9 100644 --- a/tokio/src/runtime/blocking/pool.rs +++ b/tokio/src/runtime/blocking/pool.rs @@ -299,12 +299,11 @@ impl Spawner { F: FnOnce() -> R + Send + 'static, R: Send + 'static, { - let (join_handle, spawn_result) = - if cfg!(debug_assertions) && std::mem::size_of::() > BOX_FUTURE_THRESHOLD { - self.spawn_blocking_inner(Box::new(func), Mandatory::NonMandatory, None, rt) - } else { - self.spawn_blocking_inner(func, Mandatory::NonMandatory, None, rt) - }; + let (join_handle, spawn_result) = if std::mem::size_of::() > BOX_FUTURE_THRESHOLD { + self.spawn_blocking_inner(Box::new(func), Mandatory::NonMandatory, None, rt) + } else { + self.spawn_blocking_inner(func, Mandatory::NonMandatory, None, rt) + }; match spawn_result { Ok(()) => join_handle, @@ -327,7 +326,7 @@ impl Spawner { F: FnOnce() -> R + Send + 'static, R: Send + 'static, { - let (join_handle, spawn_result) = if cfg!(debug_assertions) && std::mem::size_of::() > BOX_FUTURE_THRESHOLD { + let (join_handle, spawn_result) = if std::mem::size_of::() > BOX_FUTURE_THRESHOLD { self.spawn_blocking_inner( Box::new(func), Mandatory::Mandatory, diff --git a/tokio/src/runtime/handle.rs b/tokio/src/runtime/handle.rs index 64bc540c664..7e3cd1504e5 100644 --- a/tokio/src/runtime/handle.rs +++ b/tokio/src/runtime/handle.rs @@ -189,7 +189,7 @@ impl Handle { F: Future + Send + 'static, F::Output: Send + 'static, { - if cfg!(debug_assertions) && std::mem::size_of::() > BOX_FUTURE_THRESHOLD { + if std::mem::size_of::() > BOX_FUTURE_THRESHOLD { self.spawn_named(Box::pin(future), None) } else { self.spawn_named(future, None) @@ -296,7 +296,7 @@ impl Handle { /// [`tokio::time`]: crate::time #[track_caller] pub fn block_on(&self, future: F) -> F::Output { - if cfg!(debug_assertions) && std::mem::size_of::() > BOX_FUTURE_THRESHOLD { + if std::mem::size_of::() > BOX_FUTURE_THRESHOLD { self.block_on_inner(Box::pin(future)) } else { self.block_on_inner(future) diff --git a/tokio/src/runtime/mod.rs b/tokio/src/runtime/mod.rs index b652c8fdaeb..3f2467f6dbc 100644 --- a/tokio/src/runtime/mod.rs +++ b/tokio/src/runtime/mod.rs @@ -394,7 +394,11 @@ cfg_rt! { /// Boundary value to prevent stack overflow caused by a large-sized /// Future being placed in the stack. - pub(crate) const BOX_FUTURE_THRESHOLD: usize = 2048; + pub(crate) const BOX_FUTURE_THRESHOLD: usize = if cfg!(debug_assertions) { + 2048 + } else { + 16384 + }; mod thread_id; pub(crate) use thread_id::ThreadId; diff --git a/tokio/src/runtime/runtime.rs b/tokio/src/runtime/runtime.rs index 16f8718ab23..74061d24ce8 100644 --- a/tokio/src/runtime/runtime.rs +++ b/tokio/src/runtime/runtime.rs @@ -241,7 +241,7 @@ impl Runtime { F: Future + Send + 'static, F::Output: Send + 'static, { - if cfg!(debug_assertions) && std::mem::size_of::() > BOX_FUTURE_THRESHOLD { + if std::mem::size_of::() > BOX_FUTURE_THRESHOLD { self.handle.spawn_named(Box::pin(future), None) } else { self.handle.spawn_named(future, None) @@ -329,7 +329,7 @@ impl Runtime { /// [handle]: fn@Handle::block_on #[track_caller] pub fn block_on(&self, future: F) -> F::Output { - if cfg!(debug_assertions) && std::mem::size_of::() > BOX_FUTURE_THRESHOLD { + if std::mem::size_of::() > BOX_FUTURE_THRESHOLD { self.block_on_inner(Box::pin(future)) } else { self.block_on_inner(future) diff --git a/tokio/src/task/builder.rs b/tokio/src/task/builder.rs index 43d9322fceb..c98849b2746 100644 --- a/tokio/src/task/builder.rs +++ b/tokio/src/task/builder.rs @@ -88,13 +88,11 @@ impl<'a> Builder<'a> { Fut: Future + Send + 'static, Fut::Output: Send + 'static, { - Ok( - if cfg!(debug_assertions) && std::mem::size_of::() > BOX_FUTURE_THRESHOLD { - super::spawn::spawn_inner(Box::pin(future), self.name) - } else { - super::spawn::spawn_inner(future, self.name) - }, - ) + Ok(if std::mem::size_of::() > BOX_FUTURE_THRESHOLD { + super::spawn::spawn_inner(Box::pin(future), self.name) + } else { + super::spawn::spawn_inner(future, self.name) + }) } /// Spawn a task with this builder's settings on the provided [runtime @@ -110,13 +108,11 @@ impl<'a> Builder<'a> { Fut: Future + Send + 'static, Fut::Output: Send + 'static, { - Ok( - if cfg!(debug_assertions) && std::mem::size_of::() > BOX_FUTURE_THRESHOLD { - handle.spawn_named(Box::pin(future), self.name) - } else { - handle.spawn_named(future, self.name) - }, - ) + Ok(if std::mem::size_of::() > BOX_FUTURE_THRESHOLD { + handle.spawn_named(Box::pin(future), self.name) + } else { + handle.spawn_named(future, self.name) + }) } /// Spawns `!Send` a task on the current [`LocalSet`] with this builder's @@ -139,13 +135,11 @@ impl<'a> Builder<'a> { Fut: Future + 'static, Fut::Output: 'static, { - Ok( - if cfg!(debug_assertions) && std::mem::size_of::() > BOX_FUTURE_THRESHOLD { - super::local::spawn_local_inner(Box::pin(future), self.name) - } else { - super::local::spawn_local_inner(future, self.name) - }, - ) + Ok(if std::mem::size_of::() > BOX_FUTURE_THRESHOLD { + super::local::spawn_local_inner(Box::pin(future), self.name) + } else { + super::local::spawn_local_inner(future, self.name) + }) } /// Spawns `!Send` a task on the provided [`LocalSet`] with this builder's @@ -206,22 +200,22 @@ impl<'a> Builder<'a> { Output: Send + 'static, { use crate::runtime::Mandatory; - let (join_handle, spawn_result) = - if cfg!(debug_assertions) && std::mem::size_of::() > BOX_FUTURE_THRESHOLD { - handle.inner.blocking_spawner().spawn_blocking_inner( - Box::new(function), - Mandatory::NonMandatory, - self.name, - handle, - ) - } else { - handle.inner.blocking_spawner().spawn_blocking_inner( - function, - Mandatory::NonMandatory, - self.name, - handle, - ) - }; + let (join_handle, spawn_result) = if std::mem::size_of::() > BOX_FUTURE_THRESHOLD + { + handle.inner.blocking_spawner().spawn_blocking_inner( + Box::new(function), + Mandatory::NonMandatory, + self.name, + handle, + ) + } else { + handle.inner.blocking_spawner().spawn_blocking_inner( + function, + Mandatory::NonMandatory, + self.name, + handle, + ) + }; spawn_result?; Ok(join_handle) diff --git a/tokio/src/task/local.rs b/tokio/src/task/local.rs index 5600f08edcf..90d4d3612e8 100644 --- a/tokio/src/task/local.rs +++ b/tokio/src/task/local.rs @@ -367,7 +367,7 @@ cfg_rt! { F: Future + 'static, F::Output: 'static, { - if cfg!(debug_assertions) && std::mem::size_of::() > BOX_FUTURE_THRESHOLD { + if std::mem::size_of::() > BOX_FUTURE_THRESHOLD { spawn_local_inner(Box::pin(future), None) } else { spawn_local_inner(future, None) @@ -649,7 +649,7 @@ impl LocalSet { F: Future + 'static, F::Output: 'static, { - if cfg!(debug_assertions) && std::mem::size_of::() > BOX_FUTURE_THRESHOLD { + if std::mem::size_of::() > BOX_FUTURE_THRESHOLD { self.spawn_named_inner(Box::pin(future), name) } else { self.spawn_named_inner(future, name) diff --git a/tokio/src/task/spawn.rs b/tokio/src/task/spawn.rs index ec7a18c81ea..4208ac6e0c6 100644 --- a/tokio/src/task/spawn.rs +++ b/tokio/src/task/spawn.rs @@ -169,7 +169,7 @@ cfg_rt! { { // preventing stack overflows on debug mode, by quickly sending the // task to the heap. - if cfg!(debug_assertions) && std::mem::size_of::() > BOX_FUTURE_THRESHOLD { + if std::mem::size_of::() > BOX_FUTURE_THRESHOLD { spawn_inner(Box::pin(future), None) } else { spawn_inner(future, None)