forked from eden-emu/eden
		
	Kernel: Optimize condition variable threads management.
This commit is contained in:
		
							parent
							
								
									eef3236ecd
								
							
						
					
					
						commit
						eb03767206
					
				
					 4 changed files with 21 additions and 24 deletions
				
			
		|  | @ -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(); | ||||||
|  |  | ||||||
|  | @ -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(); |     VAddr cond_var_addr = thread->GetCondVarWaitAddress(); | ||||||
|     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()) { | ||||||
|         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()) { |         if (current_thread->GetPriority() > thread->GetPriority()) { | ||||||
|                     cond_var_threads.insert(it, thread); |             thread_list.insert(it, thread); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|             } else { |  | ||||||
|                 cond_var_threads.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(); |     VAddr cond_var_addr = thread->GetCondVarWaitAddress(); | ||||||
|     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()) { | ||||||
|         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(); |     std::list<SharedPtr<Thread>>& thread_list = cond_var_threads[cond_var_addr]; | ||||||
|     while (it != cond_var_threads.end()) { |     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; | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
|  |  | ||||||
|  | @ -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(); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Fernando Sahmkow
						Fernando Sahmkow