diff options
author | Subv <subv2112@gmail.com> | 2018-01-08 17:35:03 +0100 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2018-01-09 03:12:49 +0100 |
commit | 2a3f8e8484fca54767c9874cc21f5985d2be1463 (patch) | |
tree | 0976e02e0b495f07b11a51811618199d791d4c4e /src/core/hle/kernel/svc.cpp | |
parent | cmake: Use LIBUNICORN_* on Windows. (diff) | |
download | yuzu-2a3f8e8484fca54767c9874cc21f5985d2be1463.tar yuzu-2a3f8e8484fca54767c9874cc21f5985d2be1463.tar.gz yuzu-2a3f8e8484fca54767c9874cc21f5985d2be1463.tar.bz2 yuzu-2a3f8e8484fca54767c9874cc21f5985d2be1463.tar.lz yuzu-2a3f8e8484fca54767c9874cc21f5985d2be1463.tar.xz yuzu-2a3f8e8484fca54767c9874cc21f5985d2be1463.tar.zst yuzu-2a3f8e8484fca54767c9874cc21f5985d2be1463.zip |
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r-- | src/core/hle/kernel/svc.cpp | 56 |
1 files changed, 41 insertions, 15 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 74643f598..73793955a 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -120,17 +120,19 @@ static ResultCode GetProcessId(u32* process_id, Handle process_handle) { } /// Default thread wakeup callback for WaitSynchronization -static void DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread, - SharedPtr<WaitObject> object) { +static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread, + SharedPtr<WaitObject> object, size_t index) { ASSERT(thread->status == THREADSTATUS_WAIT_SYNCH_ANY); if (reason == ThreadWakeupReason::Timeout) { thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); - return; + return true; } ASSERT(reason == ThreadWakeupReason::Signal); thread->SetWaitSynchronizationResult(RESULT_SUCCESS); + + return true; }; /// Wait for a kernel object to synchronize, timeout after the specified nanoseconds @@ -499,20 +501,44 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr semaphore_add ASSERT(semaphore->available_count == 0); ASSERT(semaphore->mutex_addr == mutex_addr); - CASCADE_CODE(WaitSynchronization1( - semaphore, thread.get(), nano_seconds, - [mutex](ThreadWakeupReason reason, SharedPtr<Thread> thread, SharedPtr<WaitObject> object) { - ASSERT(thread->status == THREADSTATUS_WAIT_SYNCH_ANY); + auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason, + SharedPtr<Thread> thread, + SharedPtr<WaitObject> object, size_t index) { + ASSERT(thread->status == THREADSTATUS_WAIT_SYNCH_ANY); + + if (reason == ThreadWakeupReason::Timeout) { + thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); + return true; + } + + ASSERT(reason == ThreadWakeupReason::Signal); + + // Now try to acquire the mutex and don't resume if it's not available. + if (!mutex->ShouldWait(thread.get())) { + mutex->Acquire(thread.get()); + thread->SetWaitSynchronizationResult(RESULT_SUCCESS); + return true; + } - if (reason == ThreadWakeupReason::Timeout) { - thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); - return; - } + if (nano_seconds == 0) { + thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); + return true; + } + + thread->wait_objects = {mutex}; + mutex->AddWaitingThread(thread); + thread->status = THREADSTATUS_WAIT_SYNCH_ANY; + + // Create an event to wake the thread up after the + // specified nanosecond delay has passed + thread->WakeAfterDelay(nano_seconds); + thread->wakeup_callback = DefaultThreadWakeupCallback; + + Core::System::GetInstance().PrepareReschedule(); - ASSERT(reason == ThreadWakeupReason::Signal); - thread->SetWaitSynchronizationResult(WaitSynchronization1(mutex, thread.get())); - thread->SetWaitSynchronizationOutput(thread->GetWaitObjectIndex(object.get())); - })); + return false; + }; + CASCADE_CODE(WaitSynchronization1(semaphore, thread.get(), nano_seconds, wakeup_callback)); mutex->Release(thread.get()); |