/* 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 */ void IOWorkLoop::threadMain() { restartThread: do { if ( !runEventSources() ) goto exitThread; IOInterruptState is = IOSimpleLockLockDisableInterrupt(workToDoLock); if ( !ISSETP(&fFlags, kLoopTerminate) && !workToDo) { assert_wait((void *) &workToDo, false); IOSimpleLockUnlockEnableInterrupt(workToDoLock, is); thread_continue_t cptr = NULL; if (!reserved || !(kPreciousStack & reserved->options)) cptr = OSMemberFunctionCast( thread_continue_t, this, &IOWorkLoop::threadMain); thread_block_parameter(cptr, this); goto restartThread; /* NOTREACHED */ } // At this point we either have work to do or we need // to commit suicide. But no matter // Clear the simple lock and retore the interrupt state IOSimpleLockUnlockEnableInterrupt(workToDoLock, is); } while(workToDo); exitThread: thread_t thread = workThread; workThread = 0; // Say we don't have a loop and free ourselves free(); thread_deallocate(thread); (void) thread_terminate(thread); }
/* 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; }