Re: IOCommandGate vs ISyncer
Re: IOCommandGate vs ISyncer
- Subject: Re: IOCommandGate vs ISyncer
- From: Godfrey van der Linden <email@hidden>
- Date: Thu, 14 Aug 2008 17:04:13 -0700
G'day Duane,
I pretty sure that all block storage completion routines are called
from a workloop context. I.e. the runAction() is actually performed
for you by an interrupt event source way, way down on the stack. This
is the basic model of threading in I/O Kit, your completion routines
are always called in a 'gated' context. So if you want to synchronise
with such a routine you also need to use a commandGate.
Thus when you need to block a thread --- aka put to sleep --- decision
to block the thread must be made while gated, this is where the
command gate::runAction comes into use as described be ChrisS. Once
you decide that you need to sleep here it is simply a matter of
blocking the thread with commandSleep, which blocks your thread and
drops the gate so other threads can make progress.
When the threading model was designed we modelled the gated target/
action concepts on the Java Synchronous routine threading, though
without language support there was never any easy way to make it
elegant. Any action routine called by an event source, like
interrupt, timeout of even command actions are guaranteed to be single
threaded against the IOWorkLoop that are registered with. No matter
how many drivers there are on a stack there usually all synch against
one workloop.
It can, and has been with some force, argued that this model is both
unconventional and over engineered. However it does have a couple of
very nice advantages over lock based threading. There is no way to
lose count of how many times a recursive lock is taken so error paths
always release locks cleanly. Another huge advantage is that taking
the lock --- closing the gate in IOKit speak --- is always represented
with a function call on the stack. So if you think you have caused a
deadlock 'showallstacks' in gdb will always show it. This dug Apple
out of the poo many many times during Darwin's early development.
Cheers
Godfrey van der Linden
On 2008-08-13, at 12:30 , Duane Murphy wrote:
Thanks Chris. I get the gist of how this works...
--- At Wed, 13 Aug 2008 10:27:53 -0700, Chris Sarcone wrote:
Duane -
What is the recipe for this seemingly simple task (that IOSyncer
handles
very nicely) with IOCommandGate.
Easy recipe:
Sync Call is made
done = false;
Send I/O asynchronously
IOCommandGate::runAction()
while (!done)
IOCommandGate::commandSleep(&done,TH_UNINT);
On workloop completion thread:
done = true;
IOCommandGate::commandWakeup(&done);
This is the part that I'm usually confused on.
Does the thread have to have the gate to call commandWakeup or can
commandWakeup be called anytime?
The completion thread is the callback for the completion of IO
(IOStorageCompletion). Can that callback just call commandWakeup or
do I
have to enter the gate first using runAction and call commandWakeup
from
the runAction call back?
Thanks again. This was very helpful.
...Duane
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden