diff --git a/Core/HLE/sceKernelAlarm.cpp b/Core/HLE/sceKernelAlarm.cpp index ac66523265..da59a6d8f9 100644 --- a/Core/HLE/sceKernelAlarm.cpp +++ b/Core/HLE/sceKernelAlarm.cpp @@ -70,12 +70,17 @@ public: bool run(PendingInterrupt& pend) override { u32 error; + if (triggeredAlarm.empty()) { + return false; + } int alarmID = triggeredAlarm.front(); PSPAlarm *alarm = kernelObjects.Get(alarmID, error); if (error) { + // handleResult won't run, so the alarm is popped here, or every later alarm runs this one's entry. WARN_LOG(Log::sceKernel, "Ignoring deleted alarm %08x", alarmID); + triggeredAlarm.pop_front(); return false; } diff --git a/Core/HLE/sceKernelVTimer.cpp b/Core/HLE/sceKernelVTimer.cpp index 51f1bc9821..2b128ea220 100644 --- a/Core/HLE/sceKernelVTimer.cpp +++ b/Core/HLE/sceKernelVTimer.cpp @@ -139,12 +139,18 @@ public: bool run(PendingInterrupt &pend) override { u32 error; + if (vtimers.empty()) { + return false; + } SceUID vtimerID = vtimers.front(); VTimer *vtimer = kernelObjects.Get(vtimerID, error); - - if (error) + if (error) { + // Deleted while its interrupt was pending. handleResult won't run, so it's popped here. + WARN_LOG(Log::sceKernel, "Ignoring deleted vtimer %08x", vtimerID); + vtimers.pop_front(); return false; + } // Reserve some stack space for arguments. u32 argArea = currentMIPS->r[MIPS_REG_SP]; @@ -246,12 +252,9 @@ u32 sceKernelDeleteVTimer(SceUID uid) { return hleLogError(Log::sceKernel, error, "bad timer ID"); } - for (std::list::iterator it = vtimers.begin(); it != vtimers.end(); ++it) { - if (*it == vt->GetUID()) { - vtimers.erase(it); - break; - } - } + // Its entry in vtimers stays: each one belongs to a pending interrupt, which pops it when it runs + // (or right away, finding the timer gone), so erasing it here would hand that interrupt to the + // next timer's entry, or to an empty list if the handler is deleting its own timer. return hleLogDebugOrError(Log::sceKernel, kernelObjects.Destroy(uid)); } diff --git a/pspautotests b/pspautotests index 2533d2d44c..aa60f4bfec 160000 --- a/pspautotests +++ b/pspautotests @@ -1 +1 @@ -Subproject commit 2533d2d44c94de8808024bf079111c44accc9965 +Subproject commit aa60f4bfecacb1abe8fcbe71e6ead1b6a3de5745 diff --git a/test.py b/test.py index 46607b9718..69651d8b51 100755 --- a/test.py +++ b/test.py @@ -371,6 +371,7 @@ tests_good = [ "sysmem/volatile", "threads/alarm/alarm", "threads/alarm/cancel/cancel", + "threads/alarm/pending/pending", "threads/alarm/refer/refer", "threads/alarm/set/set", "threads/callbacks/afterwait", @@ -508,6 +509,7 @@ tests_good = [ "threads/vtimers/getbase", "threads/vtimers/gettime", "threads/vtimers/interrupt", + "threads/vtimers/pending/pending", "threads/vtimers/refer", "threads/vtimers/sethandler", "threads/vtimers/settime",