Re: [PATCH v2 3/4] rust: sync: add `CondVar::wait_timeout`

From: Benno Lossin
Date: Wed Dec 20 2023 - 06:33:04 EST


On 12/16/23 16:31, Alice Ryhl wrote:
> @@ -102,7 +105,12 @@ pub fn new(name: &'static CStr, key: &'static LockClassKey) -> impl PinInit<Self
> })
> }
>
> - fn wait_internal<T: ?Sized, B: Backend>(&self, wait_state: u32, guard: &mut Guard<'_, T, B>) {
> + fn wait_internal<T: ?Sized, B: Backend>(
> + &self,
> + wait_state: u32,
> + guard: &mut Guard<'_, T, B>,
> + timeout: c_long,
> + ) -> c_long {
> let wait = Opaque::<bindings::wait_queue_entry>::uninit();
>
> // SAFETY: `wait` points to valid memory.
> @@ -113,11 +121,13 @@ fn wait_internal<T: ?Sized, B: Backend>(&self, wait_state: u32, guard: &mut Guar
> bindings::prepare_to_wait_exclusive(self.wait_list.get(), wait.get(), wait_state as _)
> };
>
> - // SAFETY: No arguments, switches to another thread.
> - guard.do_unlocked(|| unsafe { bindings::schedule() });
> + // SAFETY: Switches to another thread. The timeout can be any number.
> + let ret = guard.do_unlocked(|| unsafe { bindings::schedule_timeout(timeout) });

I am not sure what exactly the safety requirements of `schedule_timeout`
are. I looked at the function and saw that the timout should not be
negative. But aside from that only the the context switching should be
relevant. What things are not allowed to do when calling `schedule`
(aside from the stuff that klint catches)?
Because if there are none, then I would put the "switches to another
thread" part into a normal comment.

--
Cheers,
Benno

>
> // SAFETY: Both `wait` and `wait_list` point to valid memory.
> unsafe { bindings::finish_wait(self.wait_list.get(), wait.get()) };
> +
> + ret
> }