diff options
| author | 2019-11-21 11:03:37 -0400 | |
|---|---|---|
| committer | 2019-11-21 11:13:29 -0400 | |
| commit | 46bb6099814a6ff404d337164ced016ec04ea7b9 (patch) | |
| tree | 2ea68335bff35e36fa0999cef430ca022ecaae43 /src | |
| parent | Kernel: Correct SignalProcessWideKey (diff) | |
| download | yuzu-46bb6099814a6ff404d337164ced016ec04ea7b9.tar.gz yuzu-46bb6099814a6ff404d337164ced016ec04ea7b9.tar.xz yuzu-46bb6099814a6ff404d337164ced016ec04ea7b9.zip | |
Kernel: Optimize condition variable threads management.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 38 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.h | 3 | ||||
| -rw-r--r-- | 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_ | |||
| 64 | } else if (thread->GetStatus() == ThreadStatus::WaitMutex || | 64 | } else if (thread->GetStatus() == ThreadStatus::WaitMutex || |
| 65 | thread->GetStatus() == ThreadStatus::WaitCondVar) { | 65 | thread->GetStatus() == ThreadStatus::WaitCondVar) { |
| 66 | thread->SetMutexWaitAddress(0); | 66 | thread->SetMutexWaitAddress(0); |
| 67 | thread->SetCondVarWaitAddress(0); | ||
| 68 | thread->SetWaitHandle(0); | 67 | thread->SetWaitHandle(0); |
| 69 | if (thread->GetStatus() == ThreadStatus::WaitCondVar) { | 68 | if (thread->GetStatus() == ThreadStatus::WaitCondVar) { |
| 70 | thread->GetOwnerProcess()->RemoveConditionVariableThread(thread); | 69 | thread->GetOwnerProcess()->RemoveConditionVariableThread(thread); |
| 70 | thread->SetCondVarWaitAddress(0); | ||
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | auto* const lock_owner = thread->GetLockOwner(); | 73 | 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 { | |||
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | void Process::InsertConditionVariableThread(SharedPtr<Thread> thread) { | 145 | void Process::InsertConditionVariableThread(SharedPtr<Thread> thread) { |
| 146 | auto it = cond_var_threads.begin(); | 146 | VAddr cond_var_addr = thread->GetCondVarWaitAddress(); |
| 147 | while (it != cond_var_threads.end()) { | 147 | std::list<SharedPtr<Thread>>& thread_list = cond_var_threads[cond_var_addr]; |
| 148 | auto it = thread_list.begin(); | ||
| 149 | while (it != thread_list.end()) { | ||
| 148 | const SharedPtr<Thread> current_thread = *it; | 150 | const SharedPtr<Thread> current_thread = *it; |
| 149 | if (current_thread->GetCondVarWaitAddress() < thread->GetCondVarWaitAddress()) { | 151 | if (current_thread->GetPriority() > thread->GetPriority()) { |
| 150 | if (current_thread->GetCondVarWaitAddress() == thread->GetCondVarWaitAddress()) { | 152 | thread_list.insert(it, thread); |
| 151 | if (current_thread->GetPriority() > thread->GetPriority()) { | 153 | return; |
| 152 | cond_var_threads.insert(it, thread); | ||
| 153 | return; | ||
| 154 | } | ||
| 155 | } else { | ||
| 156 | cond_var_threads.insert(it, thread); | ||
| 157 | return; | ||
| 158 | } | ||
| 159 | } | 154 | } |
| 160 | ++it; | 155 | ++it; |
| 161 | } | 156 | } |
| 162 | cond_var_threads.push_back(thread); | 157 | thread_list.push_back(thread); |
| 163 | } | 158 | } |
| 164 | 159 | ||
| 165 | void Process::RemoveConditionVariableThread(SharedPtr<Thread> thread) { | 160 | void Process::RemoveConditionVariableThread(SharedPtr<Thread> thread) { |
| 166 | auto it = cond_var_threads.begin(); | 161 | VAddr cond_var_addr = thread->GetCondVarWaitAddress(); |
| 167 | while (it != cond_var_threads.end()) { | 162 | std::list<SharedPtr<Thread>>& thread_list = cond_var_threads[cond_var_addr]; |
| 163 | auto it = thread_list.begin(); | ||
| 164 | while (it != thread_list.end()) { | ||
| 168 | const SharedPtr<Thread> current_thread = *it; | 165 | const SharedPtr<Thread> current_thread = *it; |
| 169 | if (current_thread.get() == thread.get()) { | 166 | if (current_thread.get() == thread.get()) { |
| 170 | cond_var_threads.erase(it); | 167 | thread_list.erase(it); |
| 171 | return; | 168 | return; |
| 172 | } | 169 | } |
| 173 | ++it; | 170 | ++it; |
| @@ -177,12 +174,11 @@ void Process::RemoveConditionVariableThread(SharedPtr<Thread> thread) { | |||
| 177 | 174 | ||
| 178 | std::vector<SharedPtr<Thread>> Process::GetConditionVariableThreads(const VAddr cond_var_addr) { | 175 | std::vector<SharedPtr<Thread>> Process::GetConditionVariableThreads(const VAddr cond_var_addr) { |
| 179 | std::vector<SharedPtr<Thread>> result{}; | 176 | std::vector<SharedPtr<Thread>> result{}; |
| 180 | auto it = cond_var_threads.begin(); | 177 | std::list<SharedPtr<Thread>>& thread_list = cond_var_threads[cond_var_addr]; |
| 181 | while (it != cond_var_threads.end()) { | 178 | auto it = thread_list.begin(); |
| 179 | while (it != thread_list.end()) { | ||
| 182 | SharedPtr<Thread> current_thread = *it; | 180 | SharedPtr<Thread> current_thread = *it; |
| 183 | if (current_thread->GetCondVarWaitAddress() == cond_var_addr) { | 181 | result.push_back(current_thread); |
| 184 | result.push_back(current_thread); | ||
| 185 | } | ||
| 186 | ++it; | 182 | ++it; |
| 187 | } | 183 | } |
| 188 | return result; | 184 | 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 @@ | |||
| 8 | #include <cstddef> | 8 | #include <cstddef> |
| 9 | #include <list> | 9 | #include <list> |
| 10 | #include <string> | 10 | #include <string> |
| 11 | #include <unordered_map> | ||
| 11 | #include <vector> | 12 | #include <vector> |
| 12 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 13 | #include "core/hle/kernel/address_arbiter.h" | 14 | #include "core/hle/kernel/address_arbiter.h" |
| @@ -385,7 +386,7 @@ private: | |||
| 385 | std::list<const Thread*> thread_list; | 386 | std::list<const Thread*> thread_list; |
| 386 | 387 | ||
| 387 | /// List of threads waiting for a condition variable | 388 | /// List of threads waiting for a condition variable |
| 388 | std::list<SharedPtr<Thread>> cond_var_threads; | 389 | std::unordered_map<VAddr, std::list<SharedPtr<Thread>>> cond_var_threads; |
| 389 | 390 | ||
| 390 | /// System context | 391 | /// System context |
| 391 | Core::System& system; | 392 | 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 | |||
| 1661 | ASSERT(thread->GetCondVarWaitAddress() == condition_variable_addr); | 1661 | ASSERT(thread->GetCondVarWaitAddress() == condition_variable_addr); |
| 1662 | 1662 | ||
| 1663 | // liberate Cond Var Thread. | 1663 | // liberate Cond Var Thread. |
| 1664 | thread->SetCondVarWaitAddress(0); | ||
| 1665 | current_process->RemoveConditionVariableThread(thread); | 1664 | current_process->RemoveConditionVariableThread(thread); |
| 1665 | thread->SetCondVarWaitAddress(0); | ||
| 1666 | 1666 | ||
| 1667 | const std::size_t current_core = system.CurrentCoreIndex(); | 1667 | const std::size_t current_core = system.CurrentCoreIndex(); |
| 1668 | auto& monitor = system.Monitor(); | 1668 | auto& monitor = system.Monitor(); |