Просмотр исходного кода

Kernel: Optimize condition variable threads management.

Fernando Sahmkow 6 лет назад
Родитель
Сommit
46bb609981
4 измененных файлов с 21 добавлено и 24 удалено
  1. 1 1
      src/core/hle/kernel/kernel.cpp
  2. 17 21
      src/core/hle/kernel/process.cpp
  3. 2 1
      src/core/hle/kernel/process.h
  4. 1 1
      src/core/hle/kernel/svc.cpp

+ 1 - 1
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 ||
     } else if (thread->GetStatus() == ThreadStatus::WaitMutex ||
                thread->GetStatus() == ThreadStatus::WaitCondVar) {
                thread->GetStatus() == ThreadStatus::WaitCondVar) {
         thread->SetMutexWaitAddress(0);
         thread->SetMutexWaitAddress(0);
-        thread->SetCondVarWaitAddress(0);
         thread->SetWaitHandle(0);
         thread->SetWaitHandle(0);
         if (thread->GetStatus() == ThreadStatus::WaitCondVar) {
         if (thread->GetStatus() == ThreadStatus::WaitCondVar) {
             thread->GetOwnerProcess()->RemoveConditionVariableThread(thread);
             thread->GetOwnerProcess()->RemoveConditionVariableThread(thread);
+            thread->SetCondVarWaitAddress(0);
         }
         }
 
 
         auto* const lock_owner = thread->GetLockOwner();
         auto* const lock_owner = thread->GetLockOwner();

+ 17 - 21
src/core/hle/kernel/process.cpp

@@ -143,31 +143,28 @@ u64 Process::GetTotalPhysicalMemoryUsedWithoutSystemResource() const {
 }
 }
 
 
 void Process::InsertConditionVariableThread(SharedPtr<Thread> thread) {
 void Process::InsertConditionVariableThread(SharedPtr<Thread> thread) {
-    auto it = cond_var_threads.begin();
-    while (it != cond_var_threads.end()) {
+    VAddr cond_var_addr = thread->GetCondVarWaitAddress();
+    std::list<SharedPtr<Thread>>& thread_list = cond_var_threads[cond_var_addr];
+    auto it = thread_list.begin();
+    while (it != thread_list.end()) {
         const SharedPtr<Thread> current_thread = *it;
         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;
-            }
+        if (current_thread->GetPriority() > thread->GetPriority()) {
+            thread_list.insert(it, thread);
+            return;
         }
         }
         ++it;
         ++it;
     }
     }
-    cond_var_threads.push_back(thread);
+    thread_list.push_back(thread);
 }
 }
 
 
 void Process::RemoveConditionVariableThread(SharedPtr<Thread> thread) {
 void Process::RemoveConditionVariableThread(SharedPtr<Thread> thread) {
-    auto it = cond_var_threads.begin();
-    while (it != cond_var_threads.end()) {
+    VAddr cond_var_addr = thread->GetCondVarWaitAddress();
+    std::list<SharedPtr<Thread>>& thread_list = cond_var_threads[cond_var_addr];
+    auto it = thread_list.begin();
+    while (it != thread_list.end()) {
         const SharedPtr<Thread> current_thread = *it;
         const SharedPtr<Thread> current_thread = *it;
         if (current_thread.get() == thread.get()) {
         if (current_thread.get() == thread.get()) {
-            cond_var_threads.erase(it);
+            thread_list.erase(it);
             return;
             return;
         }
         }
         ++it;
         ++it;
@@ -177,12 +174,11 @@ void Process::RemoveConditionVariableThread(SharedPtr<Thread> thread) {
 
 
 std::vector<SharedPtr<Thread>> Process::GetConditionVariableThreads(const VAddr cond_var_addr) {
 std::vector<SharedPtr<Thread>> Process::GetConditionVariableThreads(const VAddr cond_var_addr) {
     std::vector<SharedPtr<Thread>> result{};
     std::vector<SharedPtr<Thread>> result{};
-    auto it = cond_var_threads.begin();
-    while (it != cond_var_threads.end()) {
+    std::list<SharedPtr<Thread>>& thread_list = cond_var_threads[cond_var_addr];
+    auto it = thread_list.begin();
+    while (it != thread_list.end()) {
         SharedPtr<Thread> current_thread = *it;
         SharedPtr<Thread> current_thread = *it;
-        if (current_thread->GetCondVarWaitAddress() == cond_var_addr) {
-            result.push_back(current_thread);
-        }
+        result.push_back(current_thread);
         ++it;
         ++it;
     }
     }
     return result;
     return result;

+ 2 - 1
src/core/hle/kernel/process.h

@@ -8,6 +8,7 @@
 #include <cstddef>
 #include <cstddef>
 #include <list>
 #include <list>
 #include <string>
 #include <string>
+#include <unordered_map>
 #include <vector>
 #include <vector>
 #include "common/common_types.h"
 #include "common/common_types.h"
 #include "core/hle/kernel/address_arbiter.h"
 #include "core/hle/kernel/address_arbiter.h"
@@ -385,7 +386,7 @@ private:
     std::list<const Thread*> thread_list;
     std::list<const Thread*> thread_list;
 
 
     /// List of threads waiting for a condition variable
     /// List of threads waiting for a condition variable
-    std::list<SharedPtr<Thread>> cond_var_threads;
+    std::unordered_map<VAddr, std::list<SharedPtr<Thread>>> cond_var_threads;
 
 
     /// System context
     /// System context
     Core::System& system;
     Core::System& system;

+ 1 - 1
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);
         ASSERT(thread->GetCondVarWaitAddress() == condition_variable_addr);
 
 
         // liberate Cond Var Thread.
         // liberate Cond Var Thread.
-        thread->SetCondVarWaitAddress(0);
         current_process->RemoveConditionVariableThread(thread);
         current_process->RemoveConditionVariableThread(thread);
+        thread->SetCondVarWaitAddress(0);
 
 
         const std::size_t current_core = system.CurrentCoreIndex();
         const std::size_t current_core = system.CurrentCoreIndex();
         auto& monitor = system.Monitor();
         auto& monitor = system.Monitor();