diff options
| author | 2019-03-28 21:42:24 -0400 | |
|---|---|---|
| committer | 2019-03-28 21:42:24 -0400 | |
| commit | f770c17d011e76cb268df5ba5d687609a0f514d4 (patch) | |
| tree | 95638bae93a71b58d4c58ff5adb03d1256b3cb8a /src/core/hle/kernel/svc.cpp | |
| parent | Merge pull request #2265 from FernandoS27/multilevelqueue (diff) | |
| parent | Fix small bug that kept a thread as a condvar thread after being signalled. (diff) | |
| download | yuzu-f770c17d011e76cb268df5ba5d687609a0f514d4.tar.gz yuzu-f770c17d011e76cb268df5ba5d687609a0f514d4.tar.xz yuzu-f770c17d011e76cb268df5ba5d687609a0f514d4.zip | |
Merge pull request #2266 from FernandoS27/arbitration
Kernel: Fixes to Arbitration and SignalProcessWideKey Management
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 19 |
1 files changed, 10 insertions, 9 deletions
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 | ||