From 217bcc560b5cc0f968ff76d57ae63a850eb442e7 Mon Sep 17 00:00:00 2001 From: Kai Law Date: Wed, 4 Feb 2026 12:06:49 +0800 Subject: [PATCH 1/2] Optimize perf of atomic_wake Release the global lock when we have found the AtomicWaitEntry. --- kernel/src/sync/atomic_wait.rs | 42 ++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/kernel/src/sync/atomic_wait.rs b/kernel/src/sync/atomic_wait.rs index 75eb38bd..c168e5e0 100644 --- a/kernel/src/sync/atomic_wait.rs +++ b/kernel/src/sync/atomic_wait.rs @@ -110,7 +110,7 @@ pub fn atomic_wait(atom: &AtomicUsize, val: usize, timeout: Tick) -> Result<(), |e| unsafe { Arc::clone_from(e) }, ); let t = scheduler::current_thread(); - let mut we = entry.pending.irqsave_lock(); + let mut we = entry.pending.lock(); we.take_irq_guard(w.get_guard_mut()); drop(w); #[cfg(debugging_scheduler)] @@ -126,7 +126,7 @@ pub fn atomic_wait(atom: &AtomicUsize, val: usize, timeout: Tick) -> Result<(), wait_queue::insert(we.deref_mut(), &mut wait_entry, InsertMode::InsertToEnd).unwrap(); reached_deadline = scheduler::suspend_me_for(timeout, Some(we)); w = EntryListHead::lock(); - we = entry.pending.irqsave_lock(); + we = entry.pending.lock(); borrowed_wait_entry = we.pop(borrowed_wait_entry).unwrap(); }); if we.is_empty() { @@ -151,37 +151,39 @@ pub fn atomic_wake(atom: &AtomicUsize, how_many: usize) -> Result ); let mut woken = 0; let mut w = EntryListHead::lock(); + let mut entry = None; for e in ArcListIterator::new(w.get_list_mut(), None) { - if e.addr() != addr { - continue; + if e.addr() == addr { + entry = Some(unsafe { Arc::clone_from(e) }); + break; } - let mut we = e.pending.irqsave_lock(); - for next in we.iter() { - if scheduler::queue_ready_thread(thread::SUSPENDED, next.thread.clone()).is_ok() { - woken += 1; - #[cfg(debugging_scheduler)] - crate::trace!( - "[TH:0x{:x}] Woken up 0x{:x}", - scheduler::current_thread_id(), - Thread::id(&next.thread) - ); - } - if woken == how_many { - break; - } + } + let Some(entry) = entry else { + return Ok(woken); + }; + let mut we = entry.pending.lock(); + we.take_irq_guard(w.get_guard_mut()); + drop(w); + for next in we.iter() { + if scheduler::queue_ready_thread(thread::SUSPENDED, next.thread.clone()).is_ok() { + woken += 1; + #[cfg(debugging_scheduler)] + crate::trace!( + "[TH:0x{:x}] Woken up 0x{:x}", + scheduler::current_thread_id(), + Thread::id(&next.thread) + ); } if woken == how_many { break; } } - drop(w); #[cfg(debugging_scheduler)] crate::trace!( "[TH:0x{:x}] woken up {} threads", scheduler::current_thread_id(), woken ); - if woken > 0 { scheduler::yield_me_now_or_later(); } From a3baa626622bf965822a2c8a47f93b6eef50e5b1 Mon Sep 17 00:00:00 2001 From: Kai Law Date: Wed, 4 Feb 2026 12:12:02 +0800 Subject: [PATCH 2/2] Fix irq --- kernel/src/sync/atomic_wait.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/src/sync/atomic_wait.rs b/kernel/src/sync/atomic_wait.rs index c168e5e0..d0b1bcd3 100644 --- a/kernel/src/sync/atomic_wait.rs +++ b/kernel/src/sync/atomic_wait.rs @@ -178,6 +178,7 @@ pub fn atomic_wake(atom: &AtomicUsize, how_many: usize) -> Result break; } } + drop(we); #[cfg(debugging_scheduler)] crate::trace!( "[TH:0x{:x}] woken up {} threads",