diff --git a/src/trading/core/async_executor.rs b/src/trading/core/async_executor.rs index b55ba2a..89bf555 100644 --- a/src/trading/core/async_executor.rs +++ b/src/trading/core/async_executor.rs @@ -16,6 +16,7 @@ use std::collections::HashMap; use std::hash::BuildHasherDefault; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::{str::FromStr, sync::Arc, time::Instant}; +use tokio::sync::Notify; use fnv::FnvHasher; @@ -133,25 +134,27 @@ async fn run_one_swqos_job(job: SwqosJob) { }); } -async fn swqos_worker_loop(queue: Arc>) { +async fn swqos_worker_loop(queue: Arc>, notify: Arc) { loop { if let Some(job) = queue.pop() { run_one_swqos_job(job).await; } else { - tokio::task::yield_now().await; + notify.notified().await; } } } static SWQOS_QUEUE: OnceCell>> = OnceCell::new(); +static SWQOS_NOTIFY: OnceCell> = OnceCell::new(); static SWQOS_WORKERS_STARTED: AtomicBool = AtomicBool::new(false); fn ensure_swqos_pool(queue: Arc>) { if SWQOS_WORKERS_STARTED.swap(true, Ordering::AcqRel) { return; } + let notify = SWQOS_NOTIFY.get_or_init(|| Arc::new(Notify::new())).clone(); for _ in 0..SWQOS_POOL_WORKERS { - tokio::spawn(swqos_worker_loop(queue.clone())); + tokio::spawn(swqos_worker_loop(queue.clone(), notify.clone())); } } @@ -477,6 +480,11 @@ pub async fn execute_parallel( } } + // Wake all workers to process enqueued jobs + if let Some(notify) = SWQOS_NOTIFY.get() { + notify.notify_waiters(); + } + // All jobs enqueued (no spawn on hot path) if !wait_transaction_confirmed {