bool IOInterruptEventSource::checkForWork() { unsigned int cacheProdCount = producerCount; int numInts = cacheProdCount - consumerCount; IOInterruptEventAction intAction = (IOInterruptEventAction) action; if (numInts > 0) { IOTimeStampLatency(); IOTimeTypeStampS(IOINTES_CLIENT); IOTimeStampConstant(IODBG_INTES(IOINTES_ACTION), (uintptr_t) intAction, (uintptr_t) owner); (*intAction)(owner, this, numInts); IOTimeTypeStampE(IOINTES_CLIENT); consumerCount = cacheProdCount; if (autoDisable && !explicitDisable) enable(); } else if (numInts < 0) { IOTimeStampLatency(); IOTimeTypeStampS(IOINTES_CLIENT); IOTimeStampConstant(IODBG_INTES(IOINTES_ACTION), (uintptr_t) intAction, (uintptr_t) owner); (*intAction)(owner, this, -numInts); IOTimeTypeStampE(IOINTES_CLIENT); consumerCount = cacheProdCount; if (autoDisable && !explicitDisable) enable(); } return false; }
void IOFilterInterruptEventSource::signalInterrupt() { bool trace = (gIOKitTrace & kIOTraceIntEventSource) ? true : false; IOStatisticsInterrupt(); producerCount++; if (trace) IOTimeStampStartConstant(IODBG_INTES(IOINTES_SEMA), (uintptr_t) this, (uintptr_t) owner); signalWorkAvailable(); if (trace) IOTimeStampEndConstant(IODBG_INTES(IOINTES_SEMA), (uintptr_t) this, (uintptr_t) owner); }
void IOFilterInterruptEventSource::disableInterruptOccurred (void */*refcon*/, IOService *prov, int source) { bool filterRes; uint64_t startTime = 0; uint64_t endTime = 0; bool trace = (gIOKitTrace & kIOTraceIntEventSource) ? true : false; if (trace) IOTimeStampStartConstant(IODBG_INTES(IOINTES_FILTER), VM_KERNEL_UNSLIDE(filterAction), (uintptr_t) owner, (uintptr_t) this, (uintptr_t) workLoop); if (IOInterruptEventSource::reserved->statistics) { if (IA_GET_STATISTIC_ENABLED(kInterruptAccountingFirstLevelTimeIndex)) { startTime = mach_absolute_time(); } } // Call the filter. filterRes = (*filterAction)(owner, this); if (IOInterruptEventSource::reserved->statistics) { if (IA_GET_STATISTIC_ENABLED(kInterruptAccountingFirstLevelCountIndex)) { IA_ADD_VALUE(&IOInterruptEventSource::reserved->statistics->interruptStatistics[kInterruptAccountingFirstLevelCountIndex], 1); } if (IA_GET_STATISTIC_ENABLED(kInterruptAccountingFirstLevelTimeIndex)) { endTime = mach_absolute_time(); IA_ADD_VALUE(&IOInterruptEventSource::reserved->statistics->interruptStatistics[kInterruptAccountingFirstLevelTimeIndex], endTime - startTime); } } if (trace) IOTimeStampEndConstant(IODBG_INTES(IOINTES_FILTER), VM_KERNEL_UNSLIDE(filterAction), (uintptr_t) owner, (uintptr_t) this, (uintptr_t) workLoop); if (filterRes) { prov->disableInterrupt(source); /* disable the interrupt */ signalInterrupt(); } }