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: BlockedType
The type of blocking this waker uses (interruptible or uninterruptible)
name: &'static str
Human-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: &mut Task, cpu: &mut Arch) -> !
pub fn wait(&self, task: &mut Task, cpu: &mut Arch) -> !
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)
- Adds the task ID to the wait queue
- Calls the scheduler to yield CPU to other tasks
§Note
This function never returns normally. The task will be blocked and only
resume execution when the entire syscall is restarted after being woken up.
The !
return type indicates this function diverges (never returns).
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
true
if a task was woken upfalse
if 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 stats
Sourcepub 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.