pub struct Waker {
wait_queue: Mutex<VecDeque<usize>>,
block_type: BlockedType,
name: &'static str,
}Expand description
A synchronization primitive that manages waiting and waking of tasks
The Waker struct provides a mechanism for tasks to wait for specific events
and be woken up when those events occur. It maintains a queue of waiting task IDs
and provides methods to block the current task or wake up waiting tasks.
§Examples
// Create a new interruptible waker for UART receive events
static UART_RX_WAKER: Waker = Waker::new_interruptible("uart_rx");
// In a blocking read function
UART_RX_WAKER.wait();
// In an interrupt handler
UART_RX_WAKER.wake_one();Fields§
§wait_queue: Mutex<VecDeque<usize>>Queue of waiting task IDs
block_type: BlockedTypeThe type of blocking this waker uses (interruptible or uninterruptible)
name: &'static strHuman-readable name for debugging purposes
Implementations§
Source§impl Waker
impl Waker
Sourcepub const fn new_interruptible(name: &'static str) -> Self
pub const fn new_interruptible(name: &'static str) -> Self
Create a new interruptible waker
Interruptible wakers allow waiting tasks to be interrupted by signals or other asynchronous events. This is suitable for user I/O operations where cancellation might be needed.
§Arguments
name- A human-readable name for debugging purposes
§Examples
static KEYBOARD_WAKER: Waker = Waker::new_interruptible("keyboard");Sourcepub const fn new_uninterruptible(name: &'static str) -> Self
pub const fn new_uninterruptible(name: &'static str) -> Self
Create a new uninterruptible waker
Uninterruptible wakers ensure that waiting tasks cannot be interrupted and will wait until the event occurs. This is suitable for critical operations like disk I/O where data integrity is important.
§Arguments
name- A human-readable name for debugging purposes
§Examples
static DISK_IO_WAKER: Waker = Waker::new_uninterruptible("disk_io");Sourcepub fn wait(&self, task_id: usize, trapframe: &mut Trapframe)
pub fn wait(&self, task_id: usize, trapframe: &mut Trapframe)
Block the current task and add it to the wait queue
This method puts the current task into a blocked state and adds its ID
to the wait queue. The task will remain blocked until another part of
the system calls wake_one() or wake_all() on this waker.
§Behavior
- Gets the current task ID
- Sets the task state to
Blocked(self.block_type)FIRST - Adds the task ID to the wait queue
- Calls the scheduler to yield CPU to other tasks
- Returns when the task is woken up and rescheduled
§Note
This function returns when the task is woken up by another part of the system. The calling code can then continue execution, typically to re-check the condition that caused the wait.
§Critical Section
To prevent race conditions between wait() and wake_one()/wake_all():
- Set task state to Blocked BEFORE adding to queue
- This ensures wake_task() can safely operate even if called immediately
Sourcepub fn wait_with_timeout(
&self,
task_id: usize,
trapframe: &mut Trapframe,
timeout_ticks: Option<u64>,
) -> bool
pub fn wait_with_timeout( &self, task_id: usize, trapframe: &mut Trapframe, timeout_ticks: Option<u64>, ) -> bool
Block the task until woken or the timeout elapses.
Returns true if woken by event, false if timeout elapsed.
Sourcepub fn wake_one(&self) -> bool
pub fn wake_one(&self) -> bool
Wake up one waiting task
This method removes one task from the wait queue and moves it from the blocked queue to the ready queue, making it eligible for scheduling again.
§Returns
trueif a task was woken upfalseif the wait queue was empty
§Examples
// In an interrupt handler
if UART_RX_WAKER.wake_one() {
// A task was woken up
}Sourcepub fn wake_all(&self) -> usize
pub fn wake_all(&self) -> usize
Wake up all waiting tasks
This method removes all tasks from the wait queue and moves them from the blocked queue to the ready queue, making them all eligible for scheduling again.
§Returns
The number of tasks that were woken up
§Examples
// Wake all tasks waiting for a broadcast event
let woken_count = BROADCAST_WAKER.wake_all();
println!("Woke up {} tasks", woken_count);Sourcepub fn block_type(&self) -> BlockedType
pub fn block_type(&self) -> BlockedType
Get the blocking type of this waker
§Returns
The BlockedType (either Interruptible or Uninterruptible)
Sourcepub fn waiting_count(&self) -> usize
pub fn waiting_count(&self) -> usize
Sourcepub fn get_waiting_task_ids(&self) -> VecDeque<usize>
pub fn get_waiting_task_ids(&self) -> VecDeque<usize>
Get a list of task IDs currently waiting in the queue
This method returns a snapshot of all task IDs currently waiting in this waker’s queue. Useful for debugging and monitoring.
§Returns
A vector containing all waiting task IDs
§Examples
let waiting_tasks = waker.get_waiting_task_ids();
println!("Tasks waiting: {:?}", waiting_tasks);Sourcepub fn is_task_waiting(&self, task_id: usize) -> bool
pub fn is_task_waiting(&self, task_id: usize) -> bool
Sourcepub fn get_stats(&self) -> WakerStats
pub fn get_stats(&self) -> WakerStats
Get detailed statistics about this waker
This method provides detailed information about the current state of the waker, including all waiting tasks and their metadata.
§Returns
A WakerStats struct containing comprehensive state information
§Examples
let stats = uart_waker.get_stats();
// Use Debug trait to print the statsSourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Print debug information about this waker
Outputs detailed information about the waker’s current state including name, blocking type, waiting task count, and task IDs. Useful for debugging and monitoring system state.
§Examples
waker.debug_print();
// Output:
// [Waker DEBUG] uart_rx: Interruptible, 3 waiting tasks: [42, 137, 89]Check if the waker has any waiting tasks
§Returns
true if there are no waiting tasks, false otherwise
Sourcepub fn clear_queue(&self) -> usize
pub fn clear_queue(&self) -> usize
Clear all waiting tasks without waking them
This is a dangerous operation that should only be used in exceptional circumstances like system cleanup or error recovery. The tasks will remain in blocked state and need to be handled separately.
§Returns
The number of tasks that were removed from the queue
§Safety
This operation can leave tasks in a permanently blocked state. Use with extreme caution.