Re: [PATCH net-next v3 7/8] rust: Add read_poll_timeout functions

From: Alice Ryhl
Date: Fri Oct 18 2024 - 04:30:40 EST


On Fri, Oct 18, 2024 at 10:10 AM FUJITA Tomonori
<fujita.tomonori@xxxxxxxxx> wrote:
>
> On Wed, 16 Oct 2024 10:52:17 +0200
> Alice Ryhl <aliceryhl@xxxxxxxxxx> wrote:
>
> > On Wed, Oct 16, 2024 at 10:45 AM Alice Ryhl <aliceryhl@xxxxxxxxxx> wrote:
> >>
> >> On Wed, Oct 16, 2024 at 5:54 AM FUJITA Tomonori
> >> <fujita.tomonori@xxxxxxxxx> wrote:
> >> > +/// Polls periodically until a condition is met or a timeout is reached.
> >> > +///
> >> > +/// `op` is called repeatedly until `cond` returns `true` or the timeout is
> >> > +/// reached. The return value of `op` is passed to `cond`.
> >> > +///
> >> > +/// `sleep_delta` is the duration to sleep between calls to `op`.
> >> > +/// If `sleep_delta` is less than one microsecond, the function will busy-wait.
> >> > +///
> >> > +/// `timeout_delta` is the maximum time to wait for `cond` to return `true`.
> >> > +///
> >> > +/// This macro can only be used in a nonatomic context.
> >> > +#[macro_export]
> >> > +macro_rules! readx_poll_timeout {
> >> > + ($op:expr, $cond:expr, $sleep_delta:expr, $timeout_delta:expr) => {{
> >> > + #[cfg(CONFIG_DEBUG_ATOMIC_SLEEP)]
> >> > + if !$sleep_delta.is_zero() {
> >> > + // SAFETY: FFI call.
> >> > + unsafe {
> >> > + $crate::bindings::__might_sleep(
> >> > + ::core::file!().as_ptr() as *const i8,
> >> > + ::core::line!() as i32,
> >> > + )
> >> > + }
> >> > + }
> >>
> >> I wonder if we can use #[track_caller] and
> >> core::panic::Location::caller [1] to do this without having to use a
> >> macro? I don't know whether it would work, but if it does, that would
> >> be super cool.
>
> Seems it works, no need to use macro. Thanks a lot!
>
> >> #[track_caller]
> >> fn might_sleep() {
> >> let location = core::panic::Location::caller();
> >> // SAFETY: FFI call.
> >> unsafe {
> >> $crate::bindings::__might_sleep(
> >> location.file().as_char_ptr(),
> >> location.line() as i32,
> >> )
> >> }
> >> }
> >
> > Actually, this raises a problem ... core::panic::Location doesn't give
> > us a nul-terminated string, so we probably can't pass it to
> > `__might_sleep`. The thing is, `::core::file!()` doesn't give us a
> > nul-terminated string either, so this code is probably incorrect
> > as-is.
>
> Ah, what's the recommended way to get a null-terminated string from
> &str?

In this case, you should be able to use the `c_str!` macro.

`kernel::c_str!(core::file!()).as_char_ptr()`

Alice