Re: Threading in IOKit (was: Protection Questions)
Re: Threading in IOKit (was: Protection Questions)
- Subject: Re: Threading in IOKit (was: Protection Questions)
- From: Scott Taggart <email@hidden>
- Date: Mon, 03 Jun 2002 16:27:20 -0700
Godfrey,
Thanks for the extended response. And, fine by me if this becomes the
starting place for documenting how all this works (I'm sure others will agree).
I have a few follow-ups.
At 02:51 PM 6/3/2002, Godfrey van der Linden wrote:
>
Basically there are two locking mechansims you will need to worry about.
>
>
One is the IOWorkLoop you are slaved against, that is the workloop of the
>
USB controller. The second lock is the network funnel. In general you
>
will not have to worry about the funnel as the IONetworkingFamily will
>
handle most of that for you.
OK, so the USB stuff is self-gated, so to speak so one USB completion will
not preempt another USB completion. I am unclear exactly what you mean by
not worrying about network funnel other than are you saying that the same
applies to it as the USB completions - that is that all network calls will
be self-protected (from themselves that is). Is this correct (but USB
callbacks are not protected against network calls and vice-versa?- see my
questions below)?
>
Now to address some of your questions.
>
>
In X you don't get anything at Primary interrupt time, so that is easy
>
(Note PCI device do have access to the primary interrupt through the
>
IOFilterInterruptEventSource but you are a USB device so you don't have to
>
worry about that.
>
>
All USB completions come on the USBs IOWorkLoop and thus holds the
>
gate. If you wish to synchronise a 'down' call against your completions
>
you can do this by creating your on IOCommandGate and registering it
>
against your work loop. You get the correct work loop to use by call
>
IOService::getWorkLoop() on yourself so that is pretty
>
easy. getWorkLoop() automatically walks down your provider chain looking
>
for a driver that exports the completion context, the USB controller in
>
your example.
By "down", I assume you mean a call from the network stack into my USB
driver? (again, I am new to this, so I will butcher the assumptions I make
and the terminology I use). If I understand this correctly, you are saying
that the network calls (could/might) preempt the USB callbacks (and
vice-versa) and thus need to be gated against the same gate as the USB
callbacks, correct? Can you point me to code that manually creates its own
IOCommandGate() (I am sure I can find this but if you can just give me a
file name, that would be great).
>
Timers also synchronise against the work loop when you use the
>
IOTimerEventSource. However there is a long outstanding bug against the
>
IOTES where it doesn't have a deterministic way of cancelling at the
>
moment. If you wish to shut down a driver and still have a timer
>
outstanding it is usually better to just wait for the last timeout to
>
occur rather than attempting to cancel it. (yes I have had this bug for a
>
long time and the fix is pretty easy but I have a long list of other very
>
high priority problems to fix first).
How do you "defer" the shutdown of the driver when you get a "terminate()"
call to wait for the timer completion? Are there any samples of how to do
this?
>
Now there are a couple of X subtleties that 9 didn't have.
>
>
Provided you use the work loop paradigm then it is easy to synchronise
>
against all callouts and also easy to keep down calls correct by using
>
your own command gate. But you do have to watch out for blocking
>
calls. It is probably never correct to issue a call that can block
>
indefinitely while in a gated context. However short, (how short is
>
undefined?) delays acceptable, hence it is ok to use locks on a work loop
>
context but it is better if you don't need to.
Seems reasonable to not "block". So, this leads me to the natural
questions: What calls can and can't be blocked? How long is "too" long? I
think in my case, I just queue most requests and return, which, I presume
is the "right" way to handle things.
>
(The inflictor of IOWorkLoop on a poor unsuspecting world)
The workloop is a nice concept. As you can see, however, there are natural
questions that arise as to the "rules". All I can say is the more
documentation and samples, the better ;)
And one final question (for now!). I am sure that if I had enough time
(which I don't), I could figure this out. And, the question itself is
tricky: I don't understand *how* registering an event (interrupt, etc.)
causes it to get gated (I would like the actual mechanism explained because
I am curious). For example, I see one of the EN drivers registering an
interrupt function as a workloop "task". When I look at the interrupt
function itself, it just looks "normal" - that is it itself does nothing
workloop/gate related. So, suppose we have a registered interrupt function
named "InterruptFunc()". Obviously, the hardware does not generate an
interrupt that directly calls this function - somehow, the gate code gets
"in front" of this function, does the gate "thing" and then calls the
function when it owns the gate. Would you mind explaining how the gate
code gets put in "front" of a registered function (what is the "glue" that
welds the source of the event (interrupt, timer, etc.) to the gate and then
to the function being gated?
Many thanks,
Scott
_______________________________________________
darwin-kernel mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/darwin-kernel
Do not post admin requests to the list. They will be ignored.