diff options
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 7 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/svc.cpp | 2 |
3 files changed, 11 insertions, 2 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 653697843..2ddeffcdd 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -38,6 +38,11 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() { | |||
| 38 | return thread->status == THREADSTATUS_RUNNING || thread->status == THREADSTATUS_READY; | 38 | return thread->status == THREADSTATUS_RUNNING || thread->status == THREADSTATUS_READY; |
| 39 | }); | 39 | }); |
| 40 | 40 | ||
| 41 | // TODO(Subv): This call should be performed inside the loop below to check if an object can be | ||
| 42 | // acquired by a particular thread. This is useful for things like recursive locking of Mutexes. | ||
| 43 | if (ShouldWait()) | ||
| 44 | return nullptr; | ||
| 45 | |||
| 41 | Thread* candidate = nullptr; | 46 | Thread* candidate = nullptr; |
| 42 | s32 candidate_priority = THREADPRIO_LOWEST + 1; | 47 | s32 candidate_priority = THREADPRIO_LOWEST + 1; |
| 43 | 48 | ||
| @@ -67,7 +72,7 @@ void WaitObject::WakeupAllWaitingThreads() { | |||
| 67 | thread->wait_set_output = false; | 72 | thread->wait_set_output = false; |
| 68 | } | 73 | } |
| 69 | } else { | 74 | } else { |
| 70 | for (auto object : thread->wait_objects) { | 75 | for (auto& object : thread->wait_objects) { |
| 71 | object->Acquire(); | 76 | object->Acquire(); |
| 72 | object->RemoveWaitingThread(thread.get()); | 77 | object->RemoveWaitingThread(thread.get()); |
| 73 | } | 78 | } |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 49ed9d899..4bbc08516 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -277,6 +277,10 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) { | |||
| 277 | 277 | ||
| 278 | if (thread->status == THREADSTATUS_WAIT_SYNCH || thread->status == THREADSTATUS_WAIT_ARB) { | 278 | if (thread->status == THREADSTATUS_WAIT_SYNCH || thread->status == THREADSTATUS_WAIT_ARB) { |
| 279 | thread->wait_set_output = false; | 279 | thread->wait_set_output = false; |
| 280 | // Remove the thread from each of its waiting objects' waitlists | ||
| 281 | for (auto& object : thread->wait_objects) | ||
| 282 | object->RemoveWaitingThread(thread.get()); | ||
| 283 | thread->wait_objects.clear(); | ||
| 280 | thread->SetWaitSynchronizationResult(ResultCode(ErrorDescription::Timeout, ErrorModule::OS, | 284 | thread->SetWaitSynchronizationResult(ResultCode(ErrorDescription::Timeout, ErrorModule::OS, |
| 281 | ErrorSummary::StatusChanged, | 285 | ErrorSummary::StatusChanged, |
| 282 | ErrorLevel::Info)); | 286 | ErrorLevel::Info)); |
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 14da09883..c81c14443 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp | |||
| @@ -321,7 +321,7 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou | |||
| 321 | }); | 321 | }); |
| 322 | if (all_available) { | 322 | if (all_available) { |
| 323 | // We can acquire all objects right now, do so. | 323 | // We can acquire all objects right now, do so. |
| 324 | for (auto object : objects) | 324 | for (auto& object : objects) |
| 325 | object->Acquire(); | 325 | object->Acquire(); |
| 326 | // Note: In this case, the `out` parameter is not set, and retains whatever value it had before. | 326 | // Note: In this case, the `out` parameter is not set, and retains whatever value it had before. |
| 327 | return RESULT_SUCCESS; | 327 | return RESULT_SUCCESS; |