diff options
| author | Fernando Sahmkow <fsahmkow27@gmail.com> | 2019-11-14 20:13:18 -0400 |
|---|---|---|
| committer | FernandoS27 <fsahmkow27@gmail.com> | 2019-11-21 10:46:55 -0400 |
| commit | 2d16507f9fa06e868349d6f57a78585aec8628fd (patch) | |
| tree | 7931e2bb9db6d55e7be760f1a1dcff14de09db78 /src/core/hle/kernel/process.cpp | |
| parent | c52f37f259372485ac5902d9cae8de327c984a55 (diff) | |
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/process.cpp')
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 12a900bcc..43576c6ab 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -142,6 +142,52 @@ u64 Process::GetTotalPhysicalMemoryUsedWithoutSystemResource() const { return GetTotalPhysicalMemoryUsed() - GetSystemResourceUsage(); } +void Process::InsertConditionVariableThread(SharedPtr<Thread> thread) { + auto it = cond_var_threads.begin(); + while (it != cond_var_threads.end()) { + const SharedPtr<Thread> current_thread = *it; + if (current_thread->GetCondVarWaitAddress() < thread->GetCondVarWaitAddress()) { + if (current_thread->GetCondVarWaitAddress() == thread->GetCondVarWaitAddress()) { + if (current_thread->GetPriority() > thread->GetPriority()) { + cond_var_threads.insert(it, thread); + return; + } + } else { + cond_var_threads.insert(it, thread); + return; + } + } + ++it; + } + cond_var_threads.push_back(thread); +} + +void Process::RemoveConditionVariableThread(SharedPtr<Thread> thread) { + auto it = cond_var_threads.begin(); + while (it != cond_var_threads.end()) { + const SharedPtr<Thread> current_thread = *it; + if (current_thread.get() == thread.get()) { + cond_var_threads.erase(it); + return; + } + ++it; + } + UNREACHABLE(); +} + +std::vector<SharedPtr<Thread>> Process::GetConditionVariableThreads(const VAddr cond_var_addr) { + std::vector<SharedPtr<Thread>> result{}; + auto it = cond_var_threads.begin(); + while (it != cond_var_threads.end()) { + SharedPtr<Thread> current_thread = *it; + if (current_thread->GetCondVarWaitAddress() == cond_var_addr) { + result.push_back(current_thread); + } + ++it; + } + return result; +} + void Process::RegisterThread(const Thread* thread) { thread_list.push_back(thread); } |
