Due to an oversight we do not implement commandSleep with a timeout,
it wouldn't be too difficult to add to the kpi (so file an
enhancement request). But that wont solve your problem today.
I'd suggest that the easiest thing to do in this design is for you to
allocate a <kern/thread_call.h> call out at init time and re-arm it
each time just before you call thread sleep. Then from the callout
you can issue a commandWakeup. This is the lightest weight solution I
can think off.
A couple of issues you need to be aware of in both the thread_call
and IOTimerEventSource solutions.
1> timer threads are higher priority than the IOWorkLoop threads
which means that your timeout may fire even though the hardware is
ready, so check your hardware from you timeout routine too.
2> it can be trick to cancel a timer. Tiger finally has a fixed
IOTimerEventSource where the cancel is synchronous and you can rely
on it. thread_call returns a boolean to indicate if the cancel found
the call in its queue. If it returns false then it is possible that
the call is still outstanding. This requires tricky reference
counting code.
Godfrey
On 05/02/2005, at 13:49 , John Baldwin wrote:
Currently I tend to use IOCommandGate::commandSleep() and
IOCommandGate::commandWakeup() to have top-half code wait for an
event from an
interrupt (top-half uses commandSleep(), interrupt handler uses
commandWakeup
()). It seems that if I want to use a timeout (in case the
firmware on my card
is out to lunch) I need to setup an IOTimerEventSource and give it
a one-shot
timeout just before I call commandSleep(). Is that the right way
to do this?
It seems that if my top-half thread were interrupted in between the
setTimeout()
and the commandSleep() that the timeout could end up firing before the
commandSleep() and the thread would miss the wakeup and potentially
sleep
forever. Do I just need to setup a periodic timeout instead and call
cancelTimeout() after resuming from commandSleep()? Is there a
better way or is
this really the right way to do things?