Commit 0a7f5ba7 authored by Boqun Feng's avatar Boqun Feng Committed by Miguel Ojeda

rust: sync: Makes `CondVar::wait()` an uninterruptible wait

Currently, `CondVar::wait()` is an interruptible wait, and this is
different than `wait_event()` in include/linux/wait.h (which is an
uninterruptible wait). To avoid confusion between different APIs on the
interruptible/uninterruptible, make `CondVar::wait()` an uninterruptible
wait same as `wait_event()`, also rename the old `wait()` to
`CondVar::wait_interruptible()`.
Spotted-by: default avatarTiago Lam <tiagolam@gmail.com>
Signed-off-by: default avatarBoqun Feng <boqun.feng@gmail.com>
Reviewed-by: default avatarBenno Lossin <benno.lossin@proton.me>
Reviewed-by: default avatarAlice Ryhl <aliceryhl@google.com>
Reviewed-by: default avatarTiago Lam <tiagolam@gmail.com>
Link: https://lore.kernel.org/r/20231214200421.690629-1-boqun.feng@gmail.comSigned-off-by: default avatarMiguel Ojeda <ojeda@kernel.org>
parent 80fe9e51
...@@ -50,7 +50,7 @@ macro_rules! new_condvar { ...@@ -50,7 +50,7 @@ macro_rules! new_condvar {
/// fn wait_for_value(e: &Example, v: u32) { /// fn wait_for_value(e: &Example, v: u32) {
/// let mut guard = e.value.lock(); /// let mut guard = e.value.lock();
/// while *guard != v { /// while *guard != v {
/// e.value_changed.wait_uninterruptible(&mut guard); /// e.value_changed.wait(&mut guard);
/// } /// }
/// } /// }
/// ///
...@@ -120,28 +120,28 @@ fn wait_internal<T: ?Sized, B: Backend>(&self, wait_state: u32, guard: &mut Guar ...@@ -120,28 +120,28 @@ fn wait_internal<T: ?Sized, B: Backend>(&self, wait_state: u32, guard: &mut Guar
unsafe { bindings::finish_wait(self.wait_list.get(), wait.get()) }; unsafe { bindings::finish_wait(self.wait_list.get(), wait.get()) };
} }
/// Releases the lock and waits for a notification in interruptible mode. /// 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 /// 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 /// thread to sleep, reacquiring the lock on wake up. It wakes up when notified by
/// [`CondVar::notify_one`] or [`CondVar::notify_all`], or when the thread receives a signal. /// [`CondVar::notify_one`] or [`CondVar::notify_all`]. Note that it may also wake up
/// It may also wake up spuriously. /// spuriously.
pub fn wait<T: ?Sized, B: Backend>(&self, guard: &mut Guard<'_, T, B>) {
self.wait_internal(bindings::TASK_UNINTERRUPTIBLE, guard);
}
/// 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. /// Returns whether there is a signal pending.
#[must_use = "wait returns if a signal is pending, so the caller must check the return value"] #[must_use = "wait_interruptible returns if a signal is pending, so the caller must check the return value"]
pub fn wait<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 {
self.wait_internal(bindings::TASK_INTERRUPTIBLE, guard); self.wait_internal(bindings::TASK_INTERRUPTIBLE, guard);
crate::current!().signal_pending() crate::current!().signal_pending()
} }
/// Releases the lock and waits for a notification in uninterruptible mode.
///
/// Similar to [`CondVar::wait`], except that the wait is not interruptible. That is, the
/// thread won't wake up due to signals. It may, however, wake up supirously.
pub fn wait_uninterruptible<T: ?Sized, B: Backend>(&self, guard: &mut Guard<'_, T, B>) {
self.wait_internal(bindings::TASK_UNINTERRUPTIBLE, guard)
}
/// Calls the kernel function to notify the appropriate number of threads with the given flags. /// Calls the kernel function to notify the appropriate number of threads with the given flags.
fn notify(&self, count: i32, flags: u32) { fn notify(&self, count: i32, flags: u32) {
// SAFETY: `wait_list` points to valid memory. // SAFETY: `wait_list` points to valid memory.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment