IOReturn IOWorkLoop::_maintRequest(void *inC, void *inD, void *, void *) { maintCommandEnum command = (maintCommandEnum) (uintptr_t) inC; IOEventSource *inEvent = (IOEventSource *) inD; IOReturn res = kIOReturnSuccess; switch (command) { case mAddEvent: if (!inEvent->getWorkLoop()) { SETP(&fFlags, kLoopRestart); inEvent->retain(); inEvent->setWorkLoop(this); inEvent->setNext(0); if (!eventChain) eventChain = inEvent; else { IOEventSource *event, *next; for (event = eventChain; (next = event->getNext()); event = next) ; event->setNext(inEvent); } } break; case mRemoveEvent: if (inEvent->getWorkLoop()) { if (eventChain == inEvent) eventChain = inEvent->getNext(); else { IOEventSource *event, *next; event = eventChain; while ((next = event->getNext()) && next != inEvent) event = next; if (!next) { res = kIOReturnBadArgument; break; } event->setNext(inEvent->getNext()); } inEvent->setWorkLoop(0); inEvent->setNext(0); inEvent->release(); SETP(&fFlags, kLoopRestart); } break; default: return kIOReturnUnsupported; } return res; }
void IOWorkLoop::enableAllEventSources() const { IOEventSource *event; for (event = eventChain; event; event = event->getNext()) event->enable(); for (event = passiveEventChain; event; event = event->getNext()) event->enable(); }
void IOWorkLoop::disableAllEventSources() const { IOEventSource *event; for (event = eventChain; event; event = event->getNext()) event->disable(); /* NOTE: controlG is in passiveEventChain since it's an IOCommandGate */ for (event = passiveEventChain; event; event = event->getNext()) if (event != controlG) // Don't disable the control gate event->disable(); }
void IOWorkLoop::disableAllInterrupts() const { IOEventSource *event; for (event = eventChain; event; event = event->getNext()) if (OSDynamicCast(IOInterruptEventSource, event)) event->disable(); }
void IOWorkLoop::disableAllEventSources() const { IOEventSource *event; for (event = eventChain; event; event = event->getNext()) if (event != controlG) // Don't disable the control gate event->disable(); }
/* virtual */ bool IOWorkLoop::runEventSources() { bool res = false; bool traceWL = (gIOKitTrace & kIOTraceWorkLoops) ? true : false; bool traceES = (gIOKitTrace & kIOTraceEventSources) ? true : false; closeGate(); if (ISSETP(&fFlags, kLoopTerminate)) goto abort; if (traceWL) IOTimeStampStartConstant(IODBG_WORKLOOP(IOWL_WORK), (uintptr_t) this); bool more; do { CLRP(&fFlags, kLoopRestart); more = false; IOInterruptState is = IOSimpleLockLockDisableInterrupt(workToDoLock); workToDo = false; IOSimpleLockUnlockEnableInterrupt(workToDoLock, is); /* NOTE: only loop over event sources in eventChain. Bypass "passive" event sources for performance */ for (IOEventSource *evnt = eventChain; evnt; evnt = evnt->getNext()) { if (traceES) IOTimeStampStartConstant(IODBG_WORKLOOP(IOWL_CLIENT), (uintptr_t) this, (uintptr_t) evnt); more |= evnt->checkForWork(); if (traceES) IOTimeStampEndConstant(IODBG_WORKLOOP(IOWL_CLIENT), (uintptr_t) this, (uintptr_t) evnt); if (ISSETP(&fFlags, kLoopTerminate)) goto abort; else if (fFlags & kLoopRestart) { more = true; break; } } } while (more); res = true; if (traceWL) IOTimeStampEndConstant(IODBG_WORKLOOP(IOWL_WORK), (uintptr_t) this); abort: openGate(); return res; }
/* virtual */ bool IOWorkLoop::runEventSources() { bool res = false; closeGate(); if (ISSETP(&fFlags, kLoopTerminate)) goto abort; IOTimeWorkS(); bool more; do { CLRP(&fFlags, kLoopRestart); more = false; IOInterruptState is = IOSimpleLockLockDisableInterrupt(workToDoLock); workToDo = false; IOSimpleLockUnlockEnableInterrupt(workToDoLock, is); for (IOEventSource *evnt = eventChain; evnt; evnt = evnt->getNext()) { IOTimeClientS(); more |= evnt->checkForWork(); IOTimeClientE(); if (ISSETP(&fFlags, kLoopTerminate)) goto abort; else if (fFlags & kLoopRestart) { more = true; break; } } } while (more); res = true; IOTimeWorkE(); abort: openGate(); return res; }
IOReturn IOWorkLoop::_maintRequest(void *inC, void *inD, void *, void *) { maintCommandEnum command = (maintCommandEnum) (uintptr_t) inC; IOEventSource *inEvent = (IOEventSource *) inD; IOReturn res = kIOReturnSuccess; switch (command) { case mAddEvent: if (!inEvent->getWorkLoop()) { SETP(&fFlags, kLoopRestart); inEvent->retain(); inEvent->setWorkLoop(this); inEvent->setNext(0); /* Check if this is a passive or active event source being added */ if (eventSourcePerformsWork(inEvent)) { if (!eventChain) eventChain = inEvent; else { IOEventSource *event, *next; for (event = eventChain; (next = event->getNext()); event = next) ; event->setNext(inEvent); } } else { if (!passiveEventChain) passiveEventChain = inEvent; else { IOEventSource *event, *next; for (event = passiveEventChain; (next = event->getNext()); event = next) ; event->setNext(inEvent); } } IOStatisticsAttachEventSource(); } break; case mRemoveEvent: if (inEvent->getWorkLoop()) { IOStatisticsDetachEventSource(); if (eventSourcePerformsWork(inEvent)) { if (eventChain == inEvent) eventChain = inEvent->getNext(); else { IOEventSource *event, *next; event = eventChain; while ((next = event->getNext()) && next != inEvent) event = next; if (!next) { res = kIOReturnBadArgument; break; } event->setNext(inEvent->getNext()); } } else { if (passiveEventChain == inEvent) passiveEventChain = inEvent->getNext(); else { IOEventSource *event, *next; event = passiveEventChain; while ((next = event->getNext()) && next != inEvent) event = next; if (!next) { res = kIOReturnBadArgument; break; } event->setNext(inEvent->getNext()); } } inEvent->setWorkLoop(0); inEvent->setNext(0); inEvent->release(); SETP(&fFlags, kLoopRestart); } break; default: return kIOReturnUnsupported; } return res; }