这一直困扰着我很长一段时间。 在我的IOkit驱动程序中,我将中断事件源,定时器事件源注册到workloop。我使用GetWorkLoop() - > runAction(pAction)进行硬件访问。因此,来自中断处理程序和定时器处理程序以及我的pAction的所有硬件访问都被序列化。 但是,我从IOCommandGate发现了另一个runAction。我不知道两个runAction的区别。 我查看了一些iokit内核文档,但没有得到明确的答案。GetWorkLoop() - > runAction和GetCommandGate() - > runAction之间的区别?
在XNU源:
IOReturn IOWorkLoop::runAction(Action inAction, OSObject *target,
void *arg0, void *arg1,
void *arg2, void *arg3)
{
IOReturn res;
// closeGate is recursive so don't worry if we already hold the lock.
closeGate();
res = (*inAction)(target, arg0, arg1, arg2, arg3);
openGate();
return res;
}
我指当我打电话GetWorkLoop() - > runAction(无为)。 inAction在我的线程上下文中运行,而不是在workloop线程上下文中运行。它是否正确?
IOReturn IOCommandGate::runAction(Action inAction,
void *arg0, void *arg1,
void *arg2, void *arg3)
{
if (!inAction)
return kIOReturnBadArgument;
// closeGate is recursive needn't worry if we already hold the lock.
closeGate();
// If the command gate is disabled and we aren't on the workloop thread
// itself then sleep until we get enabled.
IOReturn res;
if (!workLoop->onThread()) {
while (!enabled) {
uintptr_t *sleepersP = (uintptr_t *) &reserved;
*sleepersP += 2;
IOReturn res = sleepGate(&enabled, THREAD_ABORTSAFE);
*sleepersP -= 2;
bool wakeupTearDown = (*sleepersP & 1);
if (res || wakeupTearDown) {
openGate();
if (wakeupTearDown)
commandWakeup(sleepersP); // No further resources used
return kIOReturnAborted;
}
}
}
bool trace = (gIOKitTrace & kIOTraceCommandGates) ? true : false;
if (trace)
IOTimeStampStartConstant(IODBG_CMDQ(IOCMDQ_ACTION),
VM_KERNEL_UNSLIDE(inAction), (uintptr_t) owner);
IOStatisticsActionCall();
// Must be gated and on the work loop or enabled
res = (*inAction)(owner, arg0, arg1, arg2, arg3);
if (trace)
IOTimeStampEndConstant(IODBG_CMDQ(IOCMDQ_ACTION),
VM_KERNEL_UNSLIDE(inAction), (uintptr_t) owner);
openGate();
return res;
}
该代码似乎GetCommandGate() - > runAction也运行在我的线程上下文中。不workloop线程?
所以,他们几乎是相同的。很好听,有时我使用IOTimerEventSource来实现workloop线程上的延迟调用。将函数注册到IOTimerEventSource实例,将addEventSource注册到workloop并设置超时值, – Song