A completion is, essentially, a one-shot flag that says "things may proceed." Working with completions requires including <linux/completion.h> and creating a variable of type struct completion. This structure may be declared and initialized statically with:
DECLARE_COMPLETION(my_comp);A dynamic initialization would look like:
struct completion my_comp; init_completion(&my_comp);When your driver begins some process whose completion must be waited for, it's simply a matter of passing your completion event to wait_for_completion():
void wait_for_completion(struct completion *comp);When some other part of your code has decided that the completion has happened, it can wake up anybody who is waiting with one of:
void complete(struct completion *comp); void complete_all(struct completion *comp);The first form will wake up exactly one waiting process, while the second will wake up all processes waiting for that event. Note that completions are implemented in such a way that they will work properly even if complete() is called before wait_for_completion().
If you do not use complete_all(), you should be able to use a completion structure multiple times without problem. It does not hurt, however, to reinitialize the structure before each use - so long as you do it before initiating the process that will call complete()! The macro INIT_COMPLETION() can be used to quickly reinitialize a completion structure that has been fully initialized at least once.
No comments:
Post a Comment