Skip to content

Commit 8fd94da

Browse files
committed
task: add wake_all parameter to WaitQueue::wakeup and name test increment
Per review: wakeup() now takes wake_all so callers must be conscious of wake-all vs wake-head semantics; task termination wakes the entire queue, while wake_all=false removes only the head waiter for future turnstile- type waits. The multi-waiter test's magic 10 becomes a named constant.
1 parent 7d11685 commit 8fd94da

3 files changed

Lines changed: 22 additions & 9 deletions

File tree

kernel/src/task/schedule.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,7 @@ mod test {
951951
}
952952

953953
static MULTI_WAITER_COUNTER: AtomicU32 = AtomicU32::new(0);
954+
const MULTI_WAITER_TASK_INCREMENT: u32 = 10;
954955

955956
fn multi_waiter_target(_: usize) {
956957
// Increment the counter and exit; both waiting_task instances below
@@ -964,7 +965,7 @@ mod test {
964965
if let Some(task) = target {
965966
wait_for_termination(task);
966967
}
967-
MULTI_WAITER_COUNTER.fetch_add(10, Ordering::Relaxed);
968+
MULTI_WAITER_COUNTER.fetch_add(MULTI_WAITER_TASK_INCREMENT, Ordering::Relaxed);
968969
}
969970

970971
#[test]
@@ -999,8 +1000,11 @@ mod test {
9991000
wait_for_termination(target);
10001001

10011002
// Both waiter tasks must have run: multi_waiter_target adds 1,
1002-
// each waiting_task adds 10. Total = 1 + 10 + 10 = 21.
1003-
assert_eq!(MULTI_WAITER_COUNTER.load(Ordering::Relaxed), 21);
1003+
// each waiting_task adds MULTI_WAITER_TASK_INCREMENT.
1004+
assert_eq!(
1005+
MULTI_WAITER_COUNTER.load(Ordering::Relaxed),
1006+
1 + (MULTI_WAITER_TASK_INCREMENT * 2)
1007+
);
10041008
}
10051009

10061010
#[test]

kernel/src/task/tasks.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ impl Task {
598598
self.sched_state
599599
.panic_on_idle("Trying to terminate idle task")
600600
.set_state(TaskState::TERMINATED);
601-
self.wait_queue.lock().wakeup()
601+
self.wait_queue.lock().wakeup(true)
602602
}
603603

604604
pub fn set_task_blocked(&self) {

kernel/src/task/waiting.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use intrusive_collections::LinkedList;
99
use super::tasks::{TaskPointer, TaskWaitListAdapter};
1010

1111
/// A queue of tasks waiting for a single event. Multiple tasks may wait
12-
/// simultaneously; all are woken when the event fires.
12+
/// simultaneously.
1313
#[derive(Debug)]
1414
pub struct WaitQueue {
1515
waiters: LinkedList<TaskWaitListAdapter>,
@@ -29,10 +29,19 @@ impl WaitQueue {
2929
self.waiters.push_back(current_task);
3030
}
3131

32-
/// Wake all waiting tasks. Returns the drained list of waiters so the
33-
/// caller can schedule each one.
34-
pub fn wakeup(&mut self) -> LinkedList<TaskWaitListAdapter> {
35-
self.waiters.take()
32+
/// Wake waiting tasks. If `wake_all` is false, only the head waiter is
33+
/// removed. Returns the removed waiters so the caller can schedule each
34+
/// one.
35+
pub fn wakeup(&mut self, wake_all: bool) -> LinkedList<TaskWaitListAdapter> {
36+
if wake_all {
37+
self.waiters.take()
38+
} else {
39+
let mut waiters = LinkedList::new(TaskWaitListAdapter::new());
40+
if let Some(task) = self.waiters.pop_front() {
41+
waiters.push_back(task);
42+
}
43+
waiters
44+
}
3645
}
3746
}
3847

0 commit comments

Comments
 (0)