diff options
| -rw-r--r-- | src/core/hle/kernel/address_arbiter.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 19 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 1 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.h | 3 | ||||
| -rw-r--r-- | src/yuzu/debugger/wait_tree.cpp | 4 |
6 files changed, 22 insertions, 14 deletions
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 352190da8..c8842410b 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp | |||
| @@ -26,7 +26,7 @@ void WakeThreads(const std::vector<SharedPtr<Thread>>& waiting_threads, s32 num_ | |||
| 26 | // them all. | 26 | // them all. |
| 27 | std::size_t last = waiting_threads.size(); | 27 | std::size_t last = waiting_threads.size(); |
| 28 | if (num_to_wake > 0) { | 28 | if (num_to_wake > 0) { |
| 29 | last = num_to_wake; | 29 | last = std::min(last, static_cast<std::size_t>(num_to_wake)); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | // Signal the waiting threads. | 32 | // Signal the waiting threads. |
| @@ -90,9 +90,9 @@ ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr a | |||
| 90 | // Determine the modified value depending on the waiting count. | 90 | // Determine the modified value depending on the waiting count. |
| 91 | s32 updated_value; | 91 | s32 updated_value; |
| 92 | if (waiting_threads.empty()) { | 92 | if (waiting_threads.empty()) { |
| 93 | updated_value = value - 1; | ||
| 94 | } else if (num_to_wake <= 0 || waiting_threads.size() <= static_cast<u32>(num_to_wake)) { | ||
| 95 | updated_value = value + 1; | 93 | updated_value = value + 1; |
| 94 | } else if (num_to_wake <= 0 || waiting_threads.size() <= static_cast<u32>(num_to_wake)) { | ||
| 95 | updated_value = value - 1; | ||
| 96 | } else { | 96 | } else { |
| 97 | updated_value = value; | 97 | updated_value = value; |
| 98 | } | 98 | } |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index a7e4ddc05..3b73be67b 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -62,7 +62,8 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_ | |||
| 62 | 62 | ||
| 63 | if (thread->GetMutexWaitAddress() != 0 || thread->GetCondVarWaitAddress() != 0 || | 63 | if (thread->GetMutexWaitAddress() != 0 || thread->GetCondVarWaitAddress() != 0 || |
| 64 | thread->GetWaitHandle() != 0) { | 64 | thread->GetWaitHandle() != 0) { |
| 65 | ASSERT(thread->GetStatus() == ThreadStatus::WaitMutex); | 65 | ASSERT(thread->GetStatus() == ThreadStatus::WaitMutex || |
| 66 | thread->GetStatus() == ThreadStatus::WaitCondVar); | ||
| 66 | thread->SetMutexWaitAddress(0); | 67 | thread->SetMutexWaitAddress(0); |
| 67 | thread->SetCondVarWaitAddress(0); | 68 | thread->SetCondVarWaitAddress(0); |
| 68 | thread->SetWaitHandle(0); | 69 | thread->SetWaitHandle(0); |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 09d1eadb6..11796e5e5 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -1353,7 +1353,7 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var | |||
| 1353 | current_thread->SetCondVarWaitAddress(condition_variable_addr); | 1353 | current_thread->SetCondVarWaitAddress(condition_variable_addr); |
| 1354 | current_thread->SetMutexWaitAddress(mutex_addr); | 1354 | current_thread->SetMutexWaitAddress(mutex_addr); |
| 1355 | current_thread->SetWaitHandle(thread_handle); | 1355 | current_thread->SetWaitHandle(thread_handle); |
| 1356 | current_thread->SetStatus(ThreadStatus::WaitMutex); | 1356 | current_thread->SetStatus(ThreadStatus::WaitCondVar); |
| 1357 | current_thread->InvalidateWakeupCallback(); | 1357 | current_thread->InvalidateWakeupCallback(); |
| 1358 | 1358 | ||
| 1359 | current_thread->WakeAfterDelay(nano_seconds); | 1359 | current_thread->WakeAfterDelay(nano_seconds); |
| @@ -1397,10 +1397,10 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target | |||
| 1397 | // them all. | 1397 | // them all. |
| 1398 | std::size_t last = waiting_threads.size(); | 1398 | std::size_t last = waiting_threads.size(); |
| 1399 | if (target != -1) | 1399 | if (target != -1) |
| 1400 | last = target; | 1400 | last = std::min(waiting_threads.size(), static_cast<std::size_t>(target)); |
| 1401 | 1401 | ||
| 1402 | // If there are no threads waiting on this condition variable, just exit | 1402 | // If there are no threads waiting on this condition variable, just exit |
| 1403 | if (last > waiting_threads.size()) | 1403 | if (last == 0) |
| 1404 | return RESULT_SUCCESS; | 1404 | return RESULT_SUCCESS; |
| 1405 | 1405 | ||
| 1406 | for (std::size_t index = 0; index < last; ++index) { | 1406 | for (std::size_t index = 0; index < last; ++index) { |
| @@ -1408,6 +1408,9 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target | |||
| 1408 | 1408 | ||
| 1409 | ASSERT(thread->GetCondVarWaitAddress() == condition_variable_addr); | 1409 | ASSERT(thread->GetCondVarWaitAddress() == condition_variable_addr); |
| 1410 | 1410 | ||
| 1411 | // liberate Cond Var Thread. | ||
| 1412 | thread->SetCondVarWaitAddress(0); | ||
| 1413 | |||
| 1411 | std::size_t current_core = Core::System::GetInstance().CurrentCoreIndex(); | 1414 | std::size_t current_core = Core::System::GetInstance().CurrentCoreIndex(); |
| 1412 | 1415 | ||
| 1413 | auto& monitor = Core::System::GetInstance().Monitor(); | 1416 | auto& monitor = Core::System::GetInstance().Monitor(); |
| @@ -1426,10 +1429,9 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target | |||
| 1426 | } | 1429 | } |
| 1427 | } while (!monitor.ExclusiveWrite32(current_core, thread->GetMutexWaitAddress(), | 1430 | } while (!monitor.ExclusiveWrite32(current_core, thread->GetMutexWaitAddress(), |
| 1428 | thread->GetWaitHandle())); | 1431 | thread->GetWaitHandle())); |
| 1429 | |||
| 1430 | if (mutex_val == 0) { | 1432 | if (mutex_val == 0) { |
| 1431 | // We were able to acquire the mutex, resume this thread. | 1433 | // We were able to acquire the mutex, resume this thread. |
| 1432 | ASSERT(thread->GetStatus() == ThreadStatus::WaitMutex); | 1434 | ASSERT(thread->GetStatus() == ThreadStatus::WaitCondVar); |
| 1433 | thread->ResumeFromWait(); | 1435 | thread->ResumeFromWait(); |
| 1434 | 1436 | ||
| 1435 | auto* const lock_owner = thread->GetLockOwner(); | 1437 | auto* const lock_owner = thread->GetLockOwner(); |
| @@ -1439,8 +1441,8 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target | |||
| 1439 | 1441 | ||
| 1440 | thread->SetLockOwner(nullptr); | 1442 | thread->SetLockOwner(nullptr); |
| 1441 | thread->SetMutexWaitAddress(0); | 1443 | thread->SetMutexWaitAddress(0); |
| 1442 | thread->SetCondVarWaitAddress(0); | ||
| 1443 | thread->SetWaitHandle(0); | 1444 | thread->SetWaitHandle(0); |
| 1445 | Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); | ||
| 1444 | } else { | 1446 | } else { |
| 1445 | // Atomically signal that the mutex now has a waiting thread. | 1447 | // Atomically signal that the mutex now has a waiting thread. |
| 1446 | do { | 1448 | do { |
| @@ -1459,12 +1461,11 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target | |||
| 1459 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 1461 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 1460 | auto owner = handle_table.Get<Thread>(owner_handle); | 1462 | auto owner = handle_table.Get<Thread>(owner_handle); |
| 1461 | ASSERT(owner); | 1463 | ASSERT(owner); |
| 1462 | ASSERT(thread->GetStatus() == ThreadStatus::WaitMutex); | 1464 | ASSERT(thread->GetStatus() == ThreadStatus::WaitCondVar); |
| 1463 | thread->InvalidateWakeupCallback(); | 1465 | thread->InvalidateWakeupCallback(); |
| 1466 | thread->SetStatus(ThreadStatus::WaitMutex); | ||
| 1464 | 1467 | ||
| 1465 | owner->AddMutexWaiter(thread); | 1468 | owner->AddMutexWaiter(thread); |
| 1466 | |||
| 1467 | Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); | ||
| 1468 | } | 1469 | } |
| 1469 | } | 1470 | } |
| 1470 | 1471 | ||
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 3b22e8e0d..e5853c46f 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -105,6 +105,7 @@ void Thread::ResumeFromWait() { | |||
| 105 | case ThreadStatus::WaitSleep: | 105 | case ThreadStatus::WaitSleep: |
| 106 | case ThreadStatus::WaitIPC: | 106 | case ThreadStatus::WaitIPC: |
| 107 | case ThreadStatus::WaitMutex: | 107 | case ThreadStatus::WaitMutex: |
| 108 | case ThreadStatus::WaitCondVar: | ||
| 108 | case ThreadStatus::WaitArb: | 109 | case ThreadStatus::WaitArb: |
| 109 | break; | 110 | break; |
| 110 | 111 | ||
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index faad5f391..9c684758c 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -51,7 +51,8 @@ enum class ThreadStatus { | |||
| 51 | WaitIPC, ///< Waiting for the reply from an IPC request | 51 | WaitIPC, ///< Waiting for the reply from an IPC request |
| 52 | WaitSynchAny, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false | 52 | WaitSynchAny, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false |
| 53 | WaitSynchAll, ///< Waiting due to WaitSynchronizationN with wait_all = true | 53 | WaitSynchAll, ///< Waiting due to WaitSynchronizationN with wait_all = true |
| 54 | WaitMutex, ///< Waiting due to an ArbitrateLock/WaitProcessWideKey svc | 54 | WaitMutex, ///< Waiting due to an ArbitrateLock svc |
| 55 | WaitCondVar, ///< Waiting due to an WaitProcessWideKey svc | ||
| 55 | WaitArb, ///< Waiting due to a SignalToAddress/WaitForAddress svc | 56 | WaitArb, ///< Waiting due to a SignalToAddress/WaitForAddress svc |
| 56 | Dormant, ///< Created but not yet made ready | 57 | Dormant, ///< Created but not yet made ready |
| 57 | Dead ///< Run to completion, or forcefully terminated | 58 | Dead ///< Run to completion, or forcefully terminated |
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index 06ad74ffe..593bb681f 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp | |||
| @@ -234,6 +234,9 @@ QString WaitTreeThread::GetText() const { | |||
| 234 | case Kernel::ThreadStatus::WaitMutex: | 234 | case Kernel::ThreadStatus::WaitMutex: |
| 235 | status = tr("waiting for mutex"); | 235 | status = tr("waiting for mutex"); |
| 236 | break; | 236 | break; |
| 237 | case Kernel::ThreadStatus::WaitCondVar: | ||
| 238 | status = tr("waiting for condition variable"); | ||
| 239 | break; | ||
| 237 | case Kernel::ThreadStatus::WaitArb: | 240 | case Kernel::ThreadStatus::WaitArb: |
| 238 | status = tr("waiting for address arbiter"); | 241 | status = tr("waiting for address arbiter"); |
| 239 | break; | 242 | break; |
| @@ -269,6 +272,7 @@ QColor WaitTreeThread::GetColor() const { | |||
| 269 | case Kernel::ThreadStatus::WaitSynchAll: | 272 | case Kernel::ThreadStatus::WaitSynchAll: |
| 270 | case Kernel::ThreadStatus::WaitSynchAny: | 273 | case Kernel::ThreadStatus::WaitSynchAny: |
| 271 | case Kernel::ThreadStatus::WaitMutex: | 274 | case Kernel::ThreadStatus::WaitMutex: |
| 275 | case Kernel::ThreadStatus::WaitCondVar: | ||
| 272 | case Kernel::ThreadStatus::WaitArb: | 276 | case Kernel::ThreadStatus::WaitArb: |
| 273 | return QColor(Qt::GlobalColor::red); | 277 | return QColor(Qt::GlobalColor::red); |
| 274 | case Kernel::ThreadStatus::Dormant: | 278 | case Kernel::ThreadStatus::Dormant: |