void sceKernelExitGame() { INFO_LOG(HLE,"sceKernelExitGame"); if (!PSP_CoreParameter().headLess) PanicAlert("Game exited"); __KernelSwitchOffThread("game exited"); Core_Stop(); }
void sceKernelExitGameWithStatus() { INFO_LOG(SCEKERNEL, "sceKernelExitGameWithStatus"); if (!PSP_CoreParameter().headLess) PanicAlert("Game exited (with status)"); __KernelSwitchOffThread("game exited"); Core_Stop(); }
void __TriggerRunInterrupts(int type) { // If interrupts aren't enabled, we run them later. if (interruptsEnabled && !inInterrupt) { if ((type & PSP_INTR_HLE) != 0) hleRunInterrupts(); else if ((type & PSP_INTR_ALWAYS_RESCHED) != 0) { if (!__RunOnePendingInterrupt()) __KernelSwitchOffThread("interrupt"); } else __RunOnePendingInterrupt(); } }
// 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; } }
void __TriggerRunInterrupts(int type) { // If interrupts aren't enabled, we run them later. if (interruptsEnabled && !inInterrupt) { if ((type & PSP_INTR_HLE) != 0) hleRunInterrupts(); else if ((type & PSP_INTR_ALWAYS_RESCHED) != 0) { // "Always" only means if dispatch is enabled. if (!__RunOnePendingInterrupt() && __KernelIsDispatchEnabled()) { SceUID savedThread = __KernelGetCurThread(); if (__KernelSwitchOffThread("interrupt")) threadBeforeInterrupt = savedThread; } } else __RunOnePendingInterrupt(); } }
// 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; } }
void sceKernelExitGameWithStatus() { INFO_LOG(SCEKERNEL, "sceKernelExitGameWithStatus"); __KernelSwitchOffThread("game exited"); Core_Stop(); }