Re: [PATCH 1/2] sched: Introduce APIs for waiting multi events

From: Paul E. McKenney
Date: Thu Apr 16 2009 - 23:00:14 EST


On Wed, Apr 15, 2009 at 11:18:48AM +0800, Lai Jiangshan wrote:
>
> Impact: make kernel has APIs for waiting multi events
>
> Based on code in the RCU, the simple waiting-multi-events
> algorithm may do not serve RCU only.
>
> Introduce 5 APIs for waiting multi events
>
> start scheduling events: ref_completion_get_init()
> schedule one event: ref_completion_get()
> end scheduling events: ref_completion_put_init()
>
> any event is finished: ref_completion_put()
>
> waiting scheduled events: ref_completion_wait()

Interesting API! What other uses for it have you found?

One question down below.

Thanx, Paul

> Signed-off-by: Lai Jiangshan <laijs@xxxxxxxxxxxxxx>
> ---
> diff --git a/include/linux/completion.h b/include/linux/completion.h
> index 4a6b604..86c8236 100644
> --- a/include/linux/completion.h
> +++ b/include/linux/completion.h
> @@ -8,6 +8,7 @@
> * See kernel/sched.c for details.
> */
>
> +#include <asm/atomic.h>
> #include <linux/wait.h>
>
> /**
> @@ -98,5 +99,44 @@ extern void complete_all(struct completion *);
> */
> #define INIT_COMPLETION(x) ((x).done = 0)
>
> +/*
> + * wait all references are put, or wait multi events finished in other words
> + * ref_completion_get_init() called before the struct is used or reused.
> + * ref_completion_put_init() called after all ref_completion_get()s called.
> + * ref_completion_wait() waiting until all ref_completion_put()s and
> + * the ref_completion_put_init() are called.
> + */
> +struct ref_completion {
> + atomic_t ref;
> + struct completion wait;
> +};
> +
> +static inline void ref_completion_get_init(struct ref_completion *rc)
> +{
> + atomic_set(&rc->ref, 1);
> + init_completion(&rc->wait);
> +}
> +
> +static inline void ref_completion_get(struct ref_completion *rc)
> +{
> + atomic_inc(&rc->ref);
> +}
> +
> +static inline void ref_completion_put(struct ref_completion *rc)
> +{
> + if (atomic_dec_and_test(&rc->ref))
> + complete_all(&rc->wait);
> +}
> +
> +static inline void ref_completion_put_init(struct ref_completion *rc)
> +{
> + if (atomic_dec_and_test(&rc->ref))
> + complete_all(&rc->wait);
> +}

Looks to me that ref_completion_put() and ref_completion_put_init() are
identical. What is the story with that?

> +static inline void ref_completion_wait(struct ref_completion *rc)
> +{
> + wait_for_completion(&rc->wait);
> +}
>
> #endif
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/