From 96cdf7732562eadc3f0f241d70873b3a3711cf3b Mon Sep 17 00:00:00 2001 From: wathenjiang Date: Wed, 29 May 2024 22:18:28 +0800 Subject: [PATCH 1/2] runtime: move the task out of lifo_slot to run queue before calling spawn_blocking to run the core --- tokio/src/runtime/scheduler/multi_thread/worker.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tokio/src/runtime/scheduler/multi_thread/worker.rs b/tokio/src/runtime/scheduler/multi_thread/worker.rs index 9f0dd98dfdc..2e67ae16a5e 100644 --- a/tokio/src/runtime/scheduler/multi_thread/worker.rs +++ b/tokio/src/runtime/scheduler/multi_thread/worker.rs @@ -395,11 +395,19 @@ where let cx = maybe_cx.expect("no .is_some() == false cases above should lead here"); // Get the worker core. If none is set, then blocking is fine! - let core = match cx.core.borrow_mut().take() { + let mut core = match cx.core.borrow_mut().take() { Some(core) => core, None => return Ok(()), }; + // If we heavily call `spawn_blocking`, there might be no available thread to + // run this core. Expect the task in the lifo_slot, all tasks in cores can be + // stolen, so we move the task ouf of the lifo_slot to the run_queue. + if let Some(task) = core.lifo_slot.take() { + core.run_queue + .push_back_or_overflow(task, &*cx.worker.handle, &mut core.stats); + } + // We are taking the core from the context and sending it to another // thread. take_core = true; From 59cb9f6422d451a1aa695cc9d554e4dff35b1abe Mon Sep 17 00:00:00 2001 From: Weijia Jiang Date: Wed, 29 May 2024 22:35:15 +0800 Subject: [PATCH 2/2] Update tokio/src/runtime/scheduler/multi_thread/worker.rs Co-authored-by: Alice Ryhl --- tokio/src/runtime/scheduler/multi_thread/worker.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tokio/src/runtime/scheduler/multi_thread/worker.rs b/tokio/src/runtime/scheduler/multi_thread/worker.rs index 2e67ae16a5e..4d41698ce44 100644 --- a/tokio/src/runtime/scheduler/multi_thread/worker.rs +++ b/tokio/src/runtime/scheduler/multi_thread/worker.rs @@ -401,8 +401,8 @@ where }; // If we heavily call `spawn_blocking`, there might be no available thread to - // run this core. Expect the task in the lifo_slot, all tasks in cores can be - // stolen, so we move the task ouf of the lifo_slot to the run_queue. + // run this core. Except for the task in the lifo_slot, all tasks can be + // stolen, so we move the task out of the lifo_slot to the run_queue. if let Some(task) = core.lifo_slot.take() { core.run_queue .push_back_or_overflow(task, &*cx.worker.handle, &mut core.stats);