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();
    }
}