From 46bb6099814a6ff404d337164ced016ec04ea7b9 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 21 Nov 2019 11:03:37 -0400 Subject: Kernel: Optimize condition variable threads management. --- src/core/hle/kernel/kernel.cpp | 2 +- src/core/hle/kernel/process.cpp | 38 +++++++++++++++++--------------------- src/core/hle/kernel/process.h | 3 ++- src/core/hle/kernel/svc.cpp | 2 +- 4 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index cdf7944f7..9d3b309b3 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -64,10 +64,10 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_ } else if (thread->GetStatus() == ThreadStatus::WaitMutex || thread->GetStatus() == ThreadStatus::WaitCondVar) { thread->SetMutexWaitAddress(0); - thread->SetCondVarWaitAddress(0); thread->SetWaitHandle(0); if (thread->GetStatus() == ThreadStatus::WaitCondVar) { thread->GetOwnerProcess()->RemoveConditionVariableThread(thread); + thread->SetCondVarWaitAddress(0); } auto* const lock_owner = thread->GetLockOwner(); diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 43576c6ab..a4e0dd385 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -143,31 +143,28 @@ u64 Process::GetTotalPhysicalMemoryUsedWithoutSystemResource() const { } void Process::InsertConditionVariableThread(SharedPtr thread) { - auto it = cond_var_threads.begin(); - while (it != cond_var_threads.end()) { + VAddr cond_var_addr = thread->GetCondVarWaitAddress(); + std::list>& thread_list = cond_var_threads[cond_var_addr]; + auto it = thread_list.begin(); + while (it != thread_list.end()) { const SharedPtr 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; - } + if (current_thread->GetPriority() > thread->GetPriority()) { + thread_list.insert(it, thread); + return; } ++it; } - cond_var_threads.push_back(thread); + thread_list.push_back(thread); } void Process::RemoveConditionVariableThread(SharedPtr thread) { - auto it = cond_var_threads.begin(); - while (it != cond_var_threads.end()) { + VAddr cond_var_addr = thread->GetCondVarWaitAddress(); + std::list>& thread_list = cond_var_threads[cond_var_addr]; + auto it = thread_list.begin(); + while (it != thread_list.end()) { const SharedPtr current_thread = *it; if (current_thread.get() == thread.get()) { - cond_var_threads.erase(it); + thread_list.erase(it); return; } ++it; @@ -177,12 +174,11 @@ void Process::RemoveConditionVariableThread(SharedPtr thread) { std::vector> Process::GetConditionVariableThreads(const VAddr cond_var_addr) { std::vector> result{}; - auto it = cond_var_threads.begin(); - while (it != cond_var_threads.end()) { + std::list>& thread_list = cond_var_threads[cond_var_addr]; + auto it = thread_list.begin(); + while (it != thread_list.end()) { SharedPtr current_thread = *it; - if (current_thread->GetCondVarWaitAddress() == cond_var_addr) { - result.push_back(current_thread); - } + result.push_back(current_thread); ++it; } return result; diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index e8bff709b..e2eda26b9 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "common/common_types.h" #include "core/hle/kernel/address_arbiter.h" @@ -385,7 +386,7 @@ private: std::list thread_list; /// List of threads waiting for a condition variable - std::list> cond_var_threads; + std::unordered_map>> cond_var_threads; /// System context Core::System& system; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 4fdb6d429..e2cf84624 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1661,8 +1661,8 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var ASSERT(thread->GetCondVarWaitAddress() == condition_variable_addr); // liberate Cond Var Thread. - thread->SetCondVarWaitAddress(0); current_process->RemoveConditionVariableThread(thread); + thread->SetCondVarWaitAddress(0); const std::size_t current_core = system.CurrentCoreIndex(); auto& monitor = system.Monitor(); -- cgit v1.2.3