mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Kernel: Remove a thread from all of its waiting objects' waiting_threads list when it is awoken.
This fixes a potential bug where threads would not get removed from said list if they awoke after waiting with WaitSynchronizationN with wait_all = false
This commit is contained in:
		
							parent
							
								
									fd95b6ee26
								
							
						
					
					
						commit
						7f1dca8cd2
					
				
					 1 changed files with 4 additions and 18 deletions
				
			
		|  | @ -32,19 +32,6 @@ void WaitObject::RemoveWaitingThread(Thread* thread) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() { | SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() { | ||||||
|     // Remove the threads that are ready or already running from our waitlist
 |  | ||||||
|     auto to_remove = waiting_threads.end(); |  | ||||||
|     do { |  | ||||||
|         to_remove = std::find_if(waiting_threads.begin(), waiting_threads.end(), |  | ||||||
|                                  [](const SharedPtr<Thread>& thread) { |  | ||||||
|                                     return thread->status == THREADSTATUS_RUNNING || |  | ||||||
|                                            thread->status == THREADSTATUS_READY || |  | ||||||
|                                            thread->status == THREADSTATUS_DEAD; |  | ||||||
|         }); |  | ||||||
|         // Call RemoveWaitingThread so that child classes can override the behavior.
 |  | ||||||
|         RemoveWaitingThread(to_remove->get()); |  | ||||||
|     } while (to_remove != waiting_threads.end()); |  | ||||||
| 
 |  | ||||||
|     Thread* candidate = nullptr; |     Thread* candidate = nullptr; | ||||||
|     s32 candidate_priority = THREADPRIO_LOWEST + 1; |     s32 candidate_priority = THREADPRIO_LOWEST + 1; | ||||||
| 
 | 
 | ||||||
|  | @ -86,17 +73,16 @@ void WaitObject::WakeupAllWaitingThreads() { | ||||||
|         } else { |         } else { | ||||||
|             for (auto& object : thread->wait_objects) { |             for (auto& object : thread->wait_objects) { | ||||||
|                 object->Acquire(thread.get()); |                 object->Acquire(thread.get()); | ||||||
|                 object->RemoveWaitingThread(thread.get()); |  | ||||||
|             } |             } | ||||||
|             // Note: This case doesn't update the output index of WaitSynchronizationN.
 |             // Note: This case doesn't update the output index of WaitSynchronizationN.
 | ||||||
|             // Clear the thread's waitlist
 |  | ||||||
|             thread->wait_objects.clear(); |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         for (auto& object : thread->wait_objects) | ||||||
|  |             object->RemoveWaitingThread(thread.get()); | ||||||
|  |         thread->wait_objects.clear(); | ||||||
|  | 
 | ||||||
|         thread->SetWaitSynchronizationResult(RESULT_SUCCESS); |         thread->SetWaitSynchronizationResult(RESULT_SUCCESS); | ||||||
|         thread->ResumeFromWait(); |         thread->ResumeFromWait(); | ||||||
|         // Note: Removing the thread from the object's waitlist will be
 |  | ||||||
|         // done by GetHighestPriorityReadyThread.
 |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue