LWN.net Logo

 


 
Recent Features

LWN.net Weekly Edition for March 18, 2004

LWN.net Weekly Edition for March 11, 2004

The annotated SCO stock price chart

A grumpy editor's calendar search

LWN.net Weekly Edition for March 4, 2004

Printable page
 

 

Driver porting: completion events

This article is part of the LWN Porting Drivers to 2.6 series.
Completions are a simple synchronization mechanism that is preferable to sleeping and waking up in some situations. If you have a task that must simply sleep until some process has run its course, completions can do it easily and without race conditions. They are not strictly a 2.6 feature, having been added in 2.4.7, but they merit a quick summary here.

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 have been posted. Post one now

Copyright (©) 2003, Eklektix, Inc.
Linux (®) is a registered trademark of Linus Torvalds
Powered by Rackspace Managed Hosting.