pub struct CondVar { /* private fields */ }
Expand description
A conditional variable.
Exposes the kernel’s struct wait_queue_head
as a condition variable. It allows the caller to
atomically release the given lock and go to sleep. It reacquires the lock when it wakes up. And
it wakes up when notified by another thread (via CondVar::notify_one
or
CondVar::notify_all
) or because the thread received a signal. It may also wake up
spuriously.
Instances of CondVar
need a lock class and to be pinned. The recommended way to create such
instances is with the pin_init
and new_condvar
macros.
§Examples
The following is an example of using a condvar with a mutex:
use kernel::sync::{new_condvar, new_mutex, CondVar, Mutex};
#[pin_data]
pub struct Example {
#[pin]
value: Mutex<u32>,
#[pin]
value_changed: CondVar,
}
/// Waits for `e.value` to become `v`.
fn wait_for_value(e: &Example, v: u32) {
let mut guard = e.value.lock();
while *guard != v {
e.value_changed.wait(&mut guard);
}
}
/// Increments `e.value` and notifies all potential waiters.
fn increment(e: &Example) {
*e.value.lock() += 1;
e.value_changed.notify_all();
}
/// Allocates a new boxed `Example`.
fn new_example() -> Result<Pin<Box<Example>>> {
Box::pin_init(pin_init!(Example {
value <- new_mutex!(0),
value_changed <- new_condvar!(),
}), GFP_KERNEL)
}
Implementations§
source§impl CondVar
impl CondVar
sourcepub fn new(
name: &'static CStr,
key: &'static LockClassKey
) -> impl PinInit<Self>
pub fn new( name: &'static CStr, key: &'static LockClassKey ) -> impl PinInit<Self>
Constructs a new condvar initialiser.
sourcepub fn wait<T: ?Sized, B: Backend>(&self, guard: &mut Guard<'_, T, B>)
pub fn wait<T: ?Sized, B: Backend>(&self, guard: &mut Guard<'_, T, B>)
Releases the lock and waits for a notification in uninterruptible mode.
Atomically releases the given lock (whose ownership is proven by the guard) and puts the
thread to sleep, reacquiring the lock on wake up. It wakes up when notified by
CondVar::notify_one
or CondVar::notify_all
. Note that it may also wake up
spuriously.
sourcepub fn wait_interruptible<T: ?Sized, B: Backend>(
&self,
guard: &mut Guard<'_, T, B>
) -> bool
pub fn wait_interruptible<T: ?Sized, B: Backend>( &self, guard: &mut Guard<'_, T, B> ) -> bool
Releases the lock and waits for a notification in interruptible mode.
Similar to CondVar::wait
, except that the wait is interruptible. That is, the thread may
wake up due to signals. It may also wake up spuriously.
Returns whether there is a signal pending.
sourcepub fn wait_interruptible_timeout<T: ?Sized, B: Backend>(
&self,
guard: &mut Guard<'_, T, B>,
jiffies: Jiffies
) -> CondVarTimeoutResult
pub fn wait_interruptible_timeout<T: ?Sized, B: Backend>( &self, guard: &mut Guard<'_, T, B>, jiffies: Jiffies ) -> CondVarTimeoutResult
Releases the lock and waits for a notification in interruptible mode.
Atomically releases the given lock (whose ownership is proven by the guard) and puts the
thread to sleep. It wakes up when notified by CondVar::notify_one
or
CondVar::notify_all
, or when a timeout occurs, or when the thread receives a signal.
sourcepub fn notify_sync(&self)
pub fn notify_sync(&self)
Calls the kernel function to notify one thread synchronously.
This method behaves like notify_one
, except that it hints to the scheduler that the
current thread is about to go to sleep, so it should schedule the target thread on the same
CPU.
sourcepub fn notify_one(&self)
pub fn notify_one(&self)
Wakes a single waiter up, if any.
This is not ‘sticky’ in the sense that if no thread is waiting, the notification is lost completely (as opposed to automatically waking up the next waiter).
sourcepub fn notify_all(&self)
pub fn notify_all(&self)
Wakes all waiters up, if any.
This is not ‘sticky’ in the sense that if no thread is waiting, the notification is lost completely (as opposed to automatically waking up the next waiter).