예제 #1
0
파일: IOWorkLoop.cpp 프로젝트: SbIm/xnu-env
void IOWorkLoop::enableAllEventSources() const
{
    IOEventSource *event;

    for (event = eventChain; event; event = event->getNext())
        event->enable();
}
예제 #2
0
파일: IOWorkLoop.cpp 프로젝트: SbIm/xnu-env
void IOWorkLoop::disableAllInterrupts() const
{
    IOEventSource *event;

    for (event = eventChain; event; event = event->getNext())
        if (OSDynamicCast(IOInterruptEventSource, event))
            event->disable();
}
예제 #3
0
파일: IOWorkLoop.cpp 프로젝트: SbIm/xnu-env
void IOWorkLoop::disableAllEventSources() const
{
    IOEventSource *event;

    for (event = eventChain; event; event = event->getNext())
        if (event != controlG)	// Don't disable the control gate
            event->disable();
}
예제 #4
0
파일: IOWorkLoop.cpp 프로젝트: Bitesher/xnu
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();
}
예제 #5
0
void IORunLoop::free()
{
	for(uint32_t i=0; i<_eventSources->count(); i++)
	{
		IOEventSource *source = (IOEventSource *)_eventSources->objectAtIndex(i);
		source->disable();
		source->_runLoop = 0;
	}

	_eventSources->release();
	_removedSources->release();

	super::free();
}
예제 #6
0
파일: IOWorkLoop.cpp 프로젝트: Bitesher/xnu
/* 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;
}
예제 #7
0
파일: IOWorkLoop.cpp 프로젝트: SbIm/xnu-env
/* 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;
}
예제 #8
0
void IORunLoop::processEventSources()
{
	static IOSymbol *timerSymbol = 0;
	if(!timerSymbol)
		timerSymbol = IOSymbol::withName("IOTimerEventSource");

	timestamp_t now = time_getTimestamp();

	for(size_t i=0; i<_eventSources->count(); i++)
	{
		IOEventSource *eventSource = (IOEventSource *)_eventSources->objectAtIndex(i);

		if(eventSource->isEnabled())
		{
			eventSource->doWork();

			if(eventSource->isSubclassOf(timerSymbol))
			{
				IOTimerEventSource *timer = (IOTimerEventSource *)eventSource;
				timestamp_t fireDate = timer->_fireDate;

				if(_nextStep > fireDate - now)
					_nextStep = fireDate - now;
			}
		}
	}

	IOIterator *iterator = _removedSources->objectIterator();
	IOEventSource *eventSource;

	while((eventSource = (IOEventSource *)iterator->nextObject()))
	{
		eventSource->setRunLoop(0);
		_eventSources->removeObject(eventSource);
	}

	_removedSources->removeAllObjects();
}
예제 #9
0
파일: IOWorkLoop.cpp 프로젝트: SbIm/xnu-env
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;
}
예제 #10
0
파일: IOWorkLoop.cpp 프로젝트: Bitesher/xnu
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;
}