Skip to content

Commit

Permalink
runtime: box futures larger than 16k on release mode (#6826)
Browse files Browse the repository at this point in the history
  • Loading branch information
mhils authored Sep 16, 2024
1 parent 02aaea2 commit b5de84d
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 52 deletions.
13 changes: 6 additions & 7 deletions tokio/src/runtime/blocking/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<F>() > 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::<F>() > 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,
Expand All @@ -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::<F>() > BOX_FUTURE_THRESHOLD {
let (join_handle, spawn_result) = if std::mem::size_of::<F>() > BOX_FUTURE_THRESHOLD {
self.spawn_blocking_inner(
Box::new(func),
Mandatory::Mandatory,
Expand Down
4 changes: 2 additions & 2 deletions tokio/src/runtime/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ impl Handle {
F: Future + Send + 'static,
F::Output: Send + 'static,
{
if cfg!(debug_assertions) && std::mem::size_of::<F>() > BOX_FUTURE_THRESHOLD {
if std::mem::size_of::<F>() > BOX_FUTURE_THRESHOLD {
self.spawn_named(Box::pin(future), None)
} else {
self.spawn_named(future, None)
Expand Down Expand Up @@ -296,7 +296,7 @@ impl Handle {
/// [`tokio::time`]: crate::time
#[track_caller]
pub fn block_on<F: Future>(&self, future: F) -> F::Output {
if cfg!(debug_assertions) && std::mem::size_of::<F>() > BOX_FUTURE_THRESHOLD {
if std::mem::size_of::<F>() > BOX_FUTURE_THRESHOLD {
self.block_on_inner(Box::pin(future))
} else {
self.block_on_inner(future)
Expand Down
6 changes: 5 additions & 1 deletion tokio/src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions tokio/src/runtime/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ impl Runtime {
F: Future + Send + 'static,
F::Output: Send + 'static,
{
if cfg!(debug_assertions) && std::mem::size_of::<F>() > BOX_FUTURE_THRESHOLD {
if std::mem::size_of::<F>() > BOX_FUTURE_THRESHOLD {
self.handle.spawn_named(Box::pin(future), None)
} else {
self.handle.spawn_named(future, None)
Expand Down Expand Up @@ -329,7 +329,7 @@ impl Runtime {
/// [handle]: fn@Handle::block_on
#[track_caller]
pub fn block_on<F: Future>(&self, future: F) -> F::Output {
if cfg!(debug_assertions) && std::mem::size_of::<F>() > BOX_FUTURE_THRESHOLD {
if std::mem::size_of::<F>() > BOX_FUTURE_THRESHOLD {
self.block_on_inner(Box::pin(future))
} else {
self.block_on_inner(future)
Expand Down
68 changes: 31 additions & 37 deletions tokio/src/task/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<Fut>() > 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::<Fut>() > 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
Expand All @@ -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::<Fut>() > BOX_FUTURE_THRESHOLD {
handle.spawn_named(Box::pin(future), self.name)
} else {
handle.spawn_named(future, self.name)
},
)
Ok(if std::mem::size_of::<Fut>() > 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
Expand All @@ -139,13 +135,11 @@ impl<'a> Builder<'a> {
Fut: Future + 'static,
Fut::Output: 'static,
{
Ok(
if cfg!(debug_assertions) && std::mem::size_of::<Fut>() > 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::<Fut>() > 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
Expand Down Expand Up @@ -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::<Function>() > 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::<Function>() > 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)
Expand Down
4 changes: 2 additions & 2 deletions tokio/src/task/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ cfg_rt! {
F: Future + 'static,
F::Output: 'static,
{
if cfg!(debug_assertions) && std::mem::size_of::<F>() > BOX_FUTURE_THRESHOLD {
if std::mem::size_of::<F>() > BOX_FUTURE_THRESHOLD {
spawn_local_inner(Box::pin(future), None)
} else {
spawn_local_inner(future, None)
Expand Down Expand Up @@ -649,7 +649,7 @@ impl LocalSet {
F: Future + 'static,
F::Output: 'static,
{
if cfg!(debug_assertions) && std::mem::size_of::<F>() > BOX_FUTURE_THRESHOLD {
if std::mem::size_of::<F>() > BOX_FUTURE_THRESHOLD {
self.spawn_named_inner(Box::pin(future), name)
} else {
self.spawn_named_inner(future, name)
Expand Down
2 changes: 1 addition & 1 deletion tokio/src/task/spawn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<F>() > BOX_FUTURE_THRESHOLD {
if std::mem::size_of::<F>() > BOX_FUTURE_THRESHOLD {
spawn_inner(Box::pin(future), None)
} else {
spawn_inner(future, None)
Expand Down

0 comments on commit b5de84d

Please sign in to comment.