Re: [PATCH 12/13] rust: sync: introduce `CondVar`

From: Wedson Almeida Filho
Date: Thu Mar 30 2023 - 10:57:18 EST


On Thu, Mar 30, 2023 at 02:59:27PM +0200, Peter Zijlstra wrote:
> On Thu, Mar 30, 2023 at 01:39:53AM -0300, Wedson Almeida Filho wrote:
>
> > + fn wait_internal<T: ?Sized, B: Backend>(&self, wait_state: u32, guard: &mut Guard<'_, T, B>) {
> > + let wait = Opaque::<bindings::wait_queue_entry>::uninit();
> > +
> > + // SAFETY: `wait` points to valid memory.
> > + unsafe { bindings::init_wait(wait.get()) };
> > +
> > + // SAFETY: Both `wait` and `wait_list` point to valid memory.
> > + unsafe {
> > + bindings::prepare_to_wait_exclusive(self.wait_list.get(), wait.get(), wait_state as _)
> > + };
>
> I can't read this rust gunk, but where is the condition test gone?
>
> Also, where is the loop gone to?

They're both at the caller. The usage of condition variables is something like:

while guard.value != v {
condvar.wait_uninterruptible(&mut guard);
}

(Note that this is not specific to the kernel or to Rust: this is how condvars
work in general. You'll find this in any textbook on the topic.)

In the implementation of wait_internal(), we add the local wait entry to the
wait queue _before_ releasing the lock (i.e., before the test result can
change), so we guarantee that we don't miss wake up attempts.

Thanks,
-Wedson