mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #5987 from unknownbrackets/multithread
Fix another race in multithread, and ge sync
This commit is contained in:
commit
9164e70ae6
4 changed files with 31 additions and 11 deletions
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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_);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue