Re: waiting queue
Re: waiting queue
- Subject: Re: waiting queue
- From: devmaillists <email@hidden>
- Date: Wed, 29 Nov 2006 19:50:17 +0100
Hello Michael,
thank you very much. I tried to fully understand IOCommandgate /
IOCommandPool / IOCommand / IOWorkloop but I got stuck in the Apple
documentation. I used the darwin sources
the get some knowledge but it didnĀ“t explain the mechanism.
Are there some source of documentation I could try in addition?
Maybe to clarify what I ultimately want:
* The driver gets calls (from a user space programm) that should wait
for an event and return when this event has occurred (1)
* The kernel driver, well, waits for this event -- is indicated by
an interrupt -- to happen.
* When the interrupt has occurred, the driver returns.
I can trigger intterupts on the card, and handlers get called when
they occur. But somehow I can not get my brain wrapped around
IOCommandGate et. al.
1) There may be a timeout, but let's not make things too complicated
here
On 16.11.2006, at 19:12, Michael Smith wrote:
devmaillists wrote:
we are to implement waiting queues for scheduling threads
generated from a UserClient interface in our kext.
As I learned from the documentation I should use
wait_queue_alloc , wait_queue_free, wait_queue_member and so on to
implement wait queues.
Unfortunately I do not find the symbols in the 10.4 SDK only in
10.39 SDK but I think this is not an option for Intel based
developments.
What is the preferred way to do wait queues with 10.4 SDK.
If by "wait queues" you mean that you want to queue incoming
threads, then you should use a CommandGate with your workloop.
Something like this:
class foo : public IOService
{
...
public:
IOReturn clientCommand(..);
private:
IOCommandGate *_commandGate;
IOCommandGate::Action _commandAction;
IOReturn _clientCommand(...);
bool _busyFlag;
...
};
foo::start()
{
...
_commandGate = IOCommandGate::(this);
getWorkLoop()->addEventSource(_commandGate);
_commandAction = OSMemberFunctionCast(IOCommandGate::Action,
this, &foo::_clientCommand);
_busyFlag = false;
...
}
foo::clientCommand(...)
{
_commandGate->runAction(_commandAction, ...) }
foo::_clientCommand(...)
{
while (_busyFlag)
_commandGate->commandSleep(&busyFlag, THREAD_UNINT);
...
_busyFlag = false;
_commandGate->commandWakeup(&busyFlag, true /* wakeup one only */);
}
The busy flag acts as the semaphore indicating that there's a
thread in the critical region. The workloop lock is used to
provide concurrency protection against your interrupt thread, and
making it possible to sleep waiting for that thread without having
to deal with other threads coming into the critical region.
Caching the result of OSMemberFunctionCast is advisable, as it is
somewhat expensive.
= Mike
_______________________________________________
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