On Wed, Oct 09, 2024 at 07:53:14PM -0400, Kent Overstreet wrote:
> Add a closure version of wait_event_timeout(), with the same semantics.
> 
> The closure version is useful because unlike wait_event(), it allows
> blocking code to run in the conditional expression.
> 
> Cc: Coly Li <[email protected]>
> Signed-off-by: Kent Overstreet <[email protected]>

Acked-by: Coly Li <[email protected]>

Thanks.

> ---
>  include/linux/closure.h | 35 +++++++++++++++++++++++++++++++++++
>  1 file changed, 35 insertions(+)
> 
> diff --git a/include/linux/closure.h b/include/linux/closure.h
> index 2af44427107d..880fe85e35e9 100644
> --- a/include/linux/closure.h
> +++ b/include/linux/closure.h
> @@ -454,4 +454,39 @@ do {                                                     
>                 \
>               __closure_wait_event(waitlist, _cond);                  \
>  } while (0)
>  
> +#define __closure_wait_event_timeout(waitlist, _cond, _until)                
> \
> +({                                                                   \
> +     struct closure cl;                                              \
> +     long _t;                                                        \
> +                                                                     \
> +     closure_init_stack(&cl);                                        \
> +                                                                     \
> +     while (1) {                                                     \
> +             closure_wait(waitlist, &cl);                            \
> +             if (_cond) {                                            \
> +                     _t = max_t(long, 1L, _until - jiffies);         \
> +                     break;                                          \
> +             }                                                       \
> +             _t = max_t(long, 0L, _until - jiffies);                 \
> +             if (!_t)                                                \
> +                     break;                                          \
> +             closure_sync_timeout(&cl, _t);                          \
> +     }                                                               \
> +     closure_wake_up(waitlist);                                      \
> +     closure_sync(&cl);                                              \
> +     _t;                                                             \
> +})
> +
> +/*
> + * Returns 0 if timeout expired, remaining time in jiffies (at least 1) if
> + * condition became true
> + */
> +#define closure_wait_event_timeout(waitlist, _cond, _timeout)                
> \
> +({                                                                   \
> +     unsigned long _until = jiffies + _timeout;                      \
> +     (_cond)                                                         \
> +             ? max_t(long, 1L, _until - jiffies)                     \
> +             : __closure_wait_event_timeout(waitlist, _cond, _until);\
> +})
> +
>  #endif /* _LINUX_CLOSURE_H */
> -- 
> 2.45.2
> 

-- 
Coly Li

Reply via email to