Re: IOCommandGate and IOThread
Re: IOCommandGate and IOThread
- Subject: Re: IOCommandGate and IOThread
- From: Godfrey van der Linden <email@hidden>
- Date: Sat, 19 Apr 2008 10:12:52 +1000
Basically you are on the right track. Use the commandGate to put your
main thread to sleep waiting for your worker to get its act together.
You should synchronise with the IOWorkLoop in the driver stack, i.e.
the work loop returned by provider->getWorkLoop().
One thing you can try out though is a poorly documented, what isn't in
the kernel, service routines the osmk/kern/thread_call.h package.
This is a general purpose pool of threads that the mach kernel
provides for exactly these sort of short term on the side processing.
The best thing about it is that you don't have to do any of the usual
clean up and accounting. Another thing I like the ability to
preallocate a call/data pair and use it repeatedly.
Basically you are on the right track.
Godfrey
On 2008-04-19, at 5:03 , Duane Murphy wrote:
As suggested, I'd should be using IOCommandGate to wait for a worker
thread to complete. I've not found any documentation or notes for
how to
do this, so I am writing this up in order to document and determine if
this is the correct way to do this.
Scenario - An IOKit kext that uses a separate background thread to
process data independent of any other outside influence. When the kext
is signaled to stop this thread, how does the kext stop the thread and
wait for it to exit?
(The following code is uncompiled, untested, & unproven)
void myKext::startThread()
{
me->_threadComplete = false;
IOCreateThread( threadMain, this );
}
/* static */ void myKext::threadMain( myKext* me )
{
while ( me->_keepWorking )
{
doWork(); // ...
}
// _threadComplete is from OSMemberFunctionCast
me->_commandGate->runAction( _threadComplete, ... );
}
void myKext::threadComplete()
{
me->_commandGate->commandWakeup( &me->_threadComplete, true /* one
thread */ );
}
void myKext::stopThread()
{
_commandGate->runAction( _reallyStopThread, ... );
}
void myKext::reallyStopThread()
{
_keepWorking = false;
while( ! _threadComplete )
_commandGate->commandSleep( *_threadComplete );
}
The important point seems to be that one must be in the gate to sleep
and wake in order to be on the workloop. Hence the indirection through
IOCommandGate::runAction().
Assuming the rest of the driver hierarchy is similarly using the
workloop and command gate, this seems like it will work.
Did I get this right? Is there a better way? Are there other ways?
Thanks for the lesson,
...Duane
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel 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-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden