> > If you have a task that looks like:
> >
> > loop:
> > <do something important>
> > sleep_on(q)
> >
> > And you do wakeup(q) hoping to get something important done, then if the
> > task isn't sleeping at the time of the wakeup it will ignore the wakeup
> > and go to sleep, which imay not be what you wanted.
>
> Ok, so how should this code have been written?
DECLARE_WAIT_QUEUE(wait, current);
while(1) {
do_something_important()
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&q, &wait);
/* Now if something arrives, we'll be 'woken' immediately -
- that is; our state will be set to TASK_RUNNING */
if (!stuff_to_do()) {
/* If the 'stuff' arrives here, we get woken anyway,
so the schedule() returns immediately. You
can use schedule_timeout() here if you need
a timeout, obviously */
schedule();
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&q, &wait);
if (signal_pending(current)) {
/* You've been signalled. Deal with it. If you don't
want signals to wake you, use TASK_UNINTERRUPTIBLE
above instead of TASK_INTERRUPTIBLE. Be aware
that you'll add one to the load average all the
time your task is sleeping then. */
return -EINTR;
}
}
Alternatively, you could up() a semaphore for each task that's do be done,
and down() it again each time you remove one from the queue.
-- dwmw2
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/