Skip to content

Commit aa51fb9

Browse files
committed
fix(wait): call unlock_cpu_and_check_preemption after timeout expiration
It's necessary to call `unlock_cpu_and_check_preemption` after waking up a task. For timed wake-ups, there are two possible places to do this: 1. The timeout callback function `interrupt_task_by_timeout` (defined in `wait.rs`). However, `unlock_cpu_and_check_preemption` takes the ownership of CPU Lock and the convention of timeout callback functions requires that they enter and leave with CPU Lock active, so this function would have to re-acquire CPU Lock before returning. 2. The tick handler, `handle_tick` (defined in `timeout.rs`). It already releases CPU Lock, so this option doesn't have the CPU Lock issue. This option may cause redundant calls to `unlock_cpu_and_check_preemption`, but those won't happen too often because timeout objects are expected to be used to wake up tasks for most of the times. This commit implements the second option.
1 parent daae12e commit aa51fb9

File tree

1 file changed

+13
-0
lines changed

1 file changed

+13
-0
lines changed

src/constance/src/kernel/timeout.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ use core::{
135135
};
136136

137137
use super::{
138+
task,
138139
utils::{lock_cpu, CpuLockCell, CpuLockGuard, CpuLockGuardBorrowMut},
139140
AdjustTimeError, BadParamError, Kernel, TimeError, UTicks,
140141
};
@@ -339,6 +340,14 @@ pub(super) struct Timeout<System: Kernel> {
339340
_phantom: core::marker::PhantomData<System>,
340341
}
341342

343+
/// Tiemout callback function.
344+
///
345+
/// The callback function is called with CPU Lock active and an interrupt
346+
/// context when the associated [`Timeout`] expires.
347+
///
348+
/// The callback function may wake up tasks. When it does that, it doesn't have
349+
/// to call `unlock_cpu_and_check_preemption` or `yield_cpu` - it's
350+
/// automatically taken care of.
342351
pub(super) type TimeoutFn<System> = fn(usize, CpuLockGuard<System>) -> CpuLockGuard<System>;
343352

344353
/// Value of [`Timeout::heap_pos`] indicating the timeout is not included in the
@@ -716,6 +725,10 @@ pub(super) fn handle_tick<System: Kernel>() {
716725

717726
// Schedule the next tick
718727
pend_next_tick(lock.borrow_mut(), current_time);
728+
729+
// Callback functions might have woken up some tasks. Check for dispatch and
730+
// release CPU Lock.
731+
task::unlock_cpu_and_check_preemption(lock);
719732
}
720733

721734
/// Get the current event time.

0 commit comments

Comments
 (0)