// Returns true if anything was executed. bool __RunOnePendingInterrupt() { if (inInterrupt) { // Already in an interrupt! We'll keep going when it's done. return false; } // Can easily prioritize between different kinds of interrupts if necessary. if (pendingInterrupts.size()) { PendingInterrupt pend = pendingInterrupts.front(); pendingInterrupts.pop_front(); intState.save(); pend.handler->copyArgsToCPU(pend); currentMIPS->r[MIPS_REG_RA] = __KernelInterruptReturnAddress(); inInterrupt = true; return true; } else { // DEBUG_LOG(HLE, "No more interrupts!"); return false; } }
// Returns true if anything was executed. bool __RunOnePendingInterrupt() { bool needsThreadReturn = false; if (inInterrupt || !interruptsEnabled) { // Already in an interrupt! We'll keep going when it's done. return false; } // Can easily prioritize between different kinds of interrupts if necessary. retry: if (!pendingInterrupts.empty()) { PendingInterrupt pend = pendingInterrupts.front(); IntrHandler* handler = intrHandlers[pend.intr]; if (handler == NULL) { WARN_LOG(SCEINTC, "Ignoring interrupt"); pendingInterrupts.pop_front(); goto retry; } // If we came from CoreTiming::Advance(), we might've come from a waiting thread's callback. // To avoid "injecting" return values into our saved state, we context switch here. SceUID savedThread = __KernelGetCurThread(); if (__KernelSwitchOffThread("interrupt")) { threadBeforeInterrupt = savedThread; needsThreadReturn = true; } intState.save(); inInterrupt = true; if (!handler->run(pend)) { pendingInterrupts.pop_front(); inInterrupt = false; goto retry; } currentMIPS->r[MIPS_REG_RA] = __KernelInterruptReturnAddress(); return true; } else { if (needsThreadReturn) __KernelSwitchToThread(threadBeforeInterrupt, "left interrupt"); // DEBUG_LOG(SCEINTC, "No more interrupts!"); return false; } }
// Returns true if anything was executed. bool __RunOnePendingInterrupt() { if (inInterrupt || !interruptsEnabled) { // Already in an interrupt! We'll keep going when it's done. return false; } // Can easily prioritize between different kinds of interrupts if necessary. retry: if (pendingInterrupts.size()) { // If we came from CoreTiming::Advance(), we might've come from a waiting thread's callback. // To avoid "injecting" return values into our saved state, we context switch here. __KernelSwitchOffThread("interrupt"); PendingInterrupt pend = pendingInterrupts.front(); SubIntrHandler *handler = intrHandlers[pend.intr].get(pend.subintr); if (handler == NULL) { WARN_LOG(HLE, "Ignoring interrupt, already been released."); pendingInterrupts.pop_front(); goto retry; } intState.save(); handler->copyArgsToCPU(pend); currentMIPS->r[MIPS_REG_RA] = __KernelInterruptReturnAddress(); inInterrupt = true; return true; } else { // DEBUG_LOG(HLE, "No more interrupts!"); return false; } }