#ifndef __LINUX_COMPLETION_H #define __LINUX_COMPLETION_H /* * (C) Copyright 2001 Linus Torvalds * * Atomic wait-for-completion handler data structures. * See kernel/sched.c for details. */ #include struct completion { unsigned int done; wait_queue_head_t wait; }; #define COMPLETION_INITIALIZER(work) \ { 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) } #define COMPLETION_INITIALIZER_ONSTACK(work) \ ({ init_completion(&work); work; }) #define DECLARE_COMPLETION(work) \ struct completion work = COMPLETION_INITIALIZER(work) /* * Lockdep needs to run a non-constant initializer for on-stack * completions - so we use the _ONSTACK() variant for those that * are on the kernel stack: */ #ifdef CONFIG_LOCKDEP # define DECLARE_COMPLETION_ONSTACK(work) \ struct completion work = COMPLETION_INITIALIZER_ONSTACK(work) #else # define DECLARE_COMPLETION_ONSTACK(work) DECLARE_COMPLETION(work) #endif static inline void init_completion(struct completion *x) { x->done = 0; init_waitqueue_head(&x->wait); } extern void wait_for_completion(struct completion *); extern int wait_for_completion_interruptible(struct completion *x); extern int wait_for_completion_killable(struct completion *x); extern unsigned long wait_for_completion_timeout(struct completion *x, unsigned long timeout); extern unsigned long wait_for_completion_interruptible_timeout( struct completion *x, unsigned long timeout); extern void complete(struct completion *); extern void complete_all(struct completion *); #define INIT_COMPLETION(x) ((x).done = 0) /** * try_wait_for_completion - try to decrement a completion without blocking * @x: completion structure * * Returns: 0 if a decrement cannot be done without blocking * 1 if a decrement succeeded. * * If a completion is being used as a counting completion, * attempt to decrement the counter without blocking. This * enables us to avoid waiting if the resource the completion * is protecting is not available. */ static inline bool try_wait_for_completion(struct completion *x) { int ret = 1; spin_lock_irq(&x->wait.lock); if (!x->done) ret = 0; else x->done--; spin_unlock_irq(&x->wait.lock); return ret; } /** * completion_done - Test to see if a completion has any waiters * @x: completion structure * * Returns: 0 if there are waiters (wait_for_completion() in progress) * 1 if there are no waiters. * */ static inline bool completion_done(struct completion *x) { int ret = 1; spin_lock_irq(&x->wait.lock); if (!x->done) ret = 0; spin_unlock_irq(&x->wait.lock); return ret; } #endif