diff options
| author | 2019-11-14 20:13:18 -0400 | |
|---|---|---|
| committer | 2019-11-21 10:46:55 -0400 | |
| commit | 2d16507f9fa06e868349d6f57a78585aec8628fd (patch) | |
| tree | 7931e2bb9db6d55e7be760f1a1dcff14de09db78 /src/core/hle/kernel/svc.cpp | |
| parent | Merge pull request #3142 from ReinUsesLisp/depbar-log (diff) | |
| download | yuzu-2d16507f9fa06e868349d6f57a78585aec8628fd.tar.gz yuzu-2d16507f9fa06e868349d6f57a78585aec8628fd.tar.xz yuzu-2d16507f9fa06e868349d6f57a78585aec8628fd.zip | |
Kernel: Correct behavior of Condition Variables to be more similar to real hardware.
This commit ensures cond var threads act exactly as they do in the real
console. The original implementation uses an RBTree and the behavior of
cond var threads is that at the same priority level they act like a
FIFO.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 20 |
1 files changed, 5 insertions, 15 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index c63a9ba8b..c27529f4d 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -1626,6 +1626,7 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add | |||
| 1626 | current_thread->SetWaitHandle(thread_handle); | 1626 | current_thread->SetWaitHandle(thread_handle); |
| 1627 | current_thread->SetStatus(ThreadStatus::WaitCondVar); | 1627 | current_thread->SetStatus(ThreadStatus::WaitCondVar); |
| 1628 | current_thread->InvalidateWakeupCallback(); | 1628 | current_thread->InvalidateWakeupCallback(); |
| 1629 | current_process->InsertConditionVariableThread(current_thread); | ||
| 1629 | 1630 | ||
| 1630 | current_thread->WakeAfterDelay(nano_seconds); | 1631 | current_thread->WakeAfterDelay(nano_seconds); |
| 1631 | 1632 | ||
| @@ -1644,21 +1645,9 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var | |||
| 1644 | ASSERT(condition_variable_addr == Common::AlignDown(condition_variable_addr, 4)); | 1645 | ASSERT(condition_variable_addr == Common::AlignDown(condition_variable_addr, 4)); |
| 1645 | 1646 | ||
| 1646 | // Retrieve a list of all threads that are waiting for this condition variable. | 1647 | // Retrieve a list of all threads that are waiting for this condition variable. |
| 1647 | std::vector<SharedPtr<Thread>> waiting_threads; | 1648 | auto* const current_process = system.Kernel().CurrentProcess(); |
| 1648 | const auto& scheduler = system.GlobalScheduler(); | 1649 | std::vector<SharedPtr<Thread>> waiting_threads = |
| 1649 | const auto& thread_list = scheduler.GetThreadList(); | 1650 | current_process->GetConditionVariableThreads(condition_variable_addr); |
| 1650 | |||
| 1651 | for (const auto& thread : thread_list) { | ||
| 1652 | if (thread->GetCondVarWaitAddress() == condition_variable_addr) { | ||
| 1653 | waiting_threads.push_back(thread); | ||
| 1654 | } | ||
| 1655 | } | ||
| 1656 | |||
| 1657 | // Sort them by priority, such that the highest priority ones come first. | ||
| 1658 | std::sort(waiting_threads.begin(), waiting_threads.end(), | ||
| 1659 | [](const SharedPtr<Thread>& lhs, const SharedPtr<Thread>& rhs) { | ||
| 1660 | return lhs->GetPriority() < rhs->GetPriority(); | ||
| 1661 | }); | ||
| 1662 | 1651 | ||
| 1663 | // Only process up to 'target' threads, unless 'target' is -1, in which case process | 1652 | // Only process up to 'target' threads, unless 'target' is -1, in which case process |
| 1664 | // them all. | 1653 | // them all. |
| @@ -1677,6 +1666,7 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var | |||
| 1677 | 1666 | ||
| 1678 | // liberate Cond Var Thread. | 1667 | // liberate Cond Var Thread. |
| 1679 | thread->SetCondVarWaitAddress(0); | 1668 | thread->SetCondVarWaitAddress(0); |
| 1669 | current_process->RemoveConditionVariableThread(thread); | ||
| 1680 | 1670 | ||
| 1681 | const std::size_t current_core = system.CurrentCoreIndex(); | 1671 | const std::size_t current_core = system.CurrentCoreIndex(); |
| 1682 | auto& monitor = system.Monitor(); | 1672 | auto& monitor = system.Monitor(); |