diff --git a/Core/CoreTiming.cpp b/Core/CoreTiming.cpp index f4c3868498..e49283cf65 100644 --- a/Core/CoreTiming.cpp +++ b/Core/CoreTiming.cpp @@ -71,7 +71,7 @@ Event *eventPool = 0; Event *eventTsPool = 0; int allocatedTsEvents = 0; // Optimization to skip MoveEvents when possible. -volatile u32 hasTsEvents = false; +volatile u32 hasTsEvents = 0; // Downcount has been moved to currentMIPS, to save a couple of clocks in every ARM JIT block // as we can already reach that structure through a register. diff --git a/Core/HW/AsyncIOManager.cpp b/Core/HW/AsyncIOManager.cpp index 3ff26be160..89dfaf6481 100644 --- a/Core/HW/AsyncIOManager.cpp +++ b/Core/HW/AsyncIOManager.cpp @@ -32,9 +32,11 @@ bool AsyncIOManager::HasOperation(u32 handle) { } void AsyncIOManager::ScheduleOperation(AsyncIOEvent ev) { - lock_guard guard(resultsLock_); - if (!resultsPending_.insert(ev.handle).second) { - ERROR_LOG_REPORT(SCEIO, "Scheduling operation for file %d while one is pending (type %d)", ev.handle, ev.type); + { + lock_guard guard(resultsLock_); + if (!resultsPending_.insert(ev.handle).second) { + ERROR_LOG_REPORT(SCEIO, "Scheduling operation for file %d while one is pending (type %d)", ev.handle, ev.type); + } } ScheduleEvent(ev); } diff --git a/Core/System.cpp b/Core/System.cpp index 31b2c90157..5b421e1415 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -76,6 +76,7 @@ GlobalUIState globalUIState; static CoreParameter coreParameter; static PSPMixer *mixer; static std::thread *cpuThread = NULL; +static std::thread::id cpuThreadID; static recursive_mutex cpuThreadLock; static condition_variable cpuThreadCond; static condition_variable cpuThreadReplyCond; @@ -108,7 +109,7 @@ void Audio_Init() { bool IsOnSeparateCPUThread() { if (cpuThread != NULL) { - return cpuThread->get_id() == std::this_thread::get_id(); + return cpuThreadID == std::this_thread::get_id(); } else { return false; } @@ -336,6 +337,7 @@ bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) { XSetThreadProcessor(cpuThread->native_handle(), 2); ResumeThread(cpuThread->native_handle()); #endif + cpuThreadID = cpuThread->get_id(); cpuThread->detach(); } else { CPU_Init(); @@ -411,6 +413,7 @@ void PSP_Shutdown() { CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsShutdown); delete cpuThread; cpuThread = 0; + cpuThreadID = std::thread::id(); } else { CPU_Shutdown(); } diff --git a/Core/ThreadEventQueue.h b/Core/ThreadEventQueue.h index f18a2df4f1..3fdc0d043a 100644 --- a/Core/ThreadEventQueue.h +++ b/Core/ThreadEventQueue.h @@ -75,6 +75,10 @@ struct ThreadEventQueue : public B { eventsHaveRun_ = true; do { + if (!HasEvents()) { + eventsWait_.wait(eventsLock_); + } + for (Event ev = GetNextEvent(); EventType(ev) != EVENT_INVALID; ev = GetNextEvent()) { eventsLock_.unlock(); switch (EventType(ev)) { @@ -96,11 +100,6 @@ struct ThreadEventQueue : public B { if (ShouldExitEventLoop() || !threadEnabled_) { break; } - - // coreState changes won't wake us, so recheck periodically. - if (!HasEvents()) { - eventsWait_.wait(eventsLock_); - } } while (CoreTiming::GetTicks() < globalticks); // This will force the waiter to check coreState, even if we didn't actually drain. @@ -113,6 +112,22 @@ struct ThreadEventQueue : public B { eventsHaveRun_ = false; } + inline bool ShouldSyncThread(bool force) { + if (!HasEvents()) + return false; + if (coreState != CORE_RUNNING && !force) + return false; + + // Don't run if it's not running, but wait for startup. + if (!eventsRunning_) { + if (eventsHaveRun_ || coreState == CORE_ERROR || coreState == CORE_POWERDOWN) { + return false; + } + } + + return true; + } + // Force ignores coreState. void SyncThread(bool force = false) { if (!threadEnabled_) { @@ -123,7 +138,7 @@ struct ThreadEventQueue : public B { // While processing the last event, HasEvents() will be false even while not done. // So we schedule a nothing event and wait for that to finish. ScheduleEvent(EVENT_SYNC); - while (HasEvents() && (eventsRunning_ || !eventsHaveRun_) && (force || coreState == CORE_RUNNING)) { + while (ShouldSyncThread(force)) { eventsDrain_.wait(eventsLock_); } }