mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-10-31 16:09:03 -05:00 
			
		
		
		
	Kernel: Optimize condition variable threads management.
This commit is contained in:
		 Fernando Sahmkow
					Fernando Sahmkow
				
			
				
					committed by
					
						 FernandoS27
						FernandoS27
					
				
			
			
				
	
			
			
			 FernandoS27
						FernandoS27
					
				
			
						parent
						
							2ab41ceff4
						
					
				
				
					commit
					46bb609981
				
			| @@ -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(); | ||||
|   | ||||
| @@ -143,31 +143,28 @@ u64 Process::GetTotalPhysicalMemoryUsedWithoutSystemResource() const { | ||||
| } | ||||
|  | ||||
| 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; | ||||
|         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> 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; | ||||
|         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> thread) { | ||||
|  | ||||
| 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()) { | ||||
|     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; | ||||
|         if (current_thread->GetCondVarWaitAddress() == cond_var_addr) { | ||||
|             result.push_back(current_thread); | ||||
|         } | ||||
|         result.push_back(current_thread); | ||||
|         ++it; | ||||
|     } | ||||
|     return result; | ||||
|   | ||||
| @@ -8,6 +8,7 @@ | ||||
| #include <cstddef> | ||||
| #include <list> | ||||
| #include <string> | ||||
| #include <unordered_map> | ||||
| #include <vector> | ||||
| #include "common/common_types.h" | ||||
| #include "core/hle/kernel/address_arbiter.h" | ||||
| @@ -385,7 +386,7 @@ private: | ||||
|     std::list<const Thread*> thread_list; | ||||
|  | ||||
|     /// 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 | ||||
|     Core::System& system; | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user