mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Properly remove a thread from its wait_objects' waitlist when it is awoken by a timeout.
This commit is contained in:
		
							parent
							
								
									17b29d8865
								
							
						
					
					
						commit
						406907d570
					
				@ -38,6 +38,11 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {
 | 
				
			|||||||
        return thread->status == THREADSTATUS_RUNNING || thread->status == THREADSTATUS_READY;
 | 
					        return thread->status == THREADSTATUS_RUNNING || thread->status == THREADSTATUS_READY;
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO(Subv): This call should be performed inside the loop below to check if an object can be
 | 
				
			||||||
 | 
					    // acquired by a particular thread. This is useful for things like recursive locking of Mutexes.
 | 
				
			||||||
 | 
					    if (ShouldWait())
 | 
				
			||||||
 | 
					        return nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Thread* candidate = nullptr;
 | 
					    Thread* candidate = nullptr;
 | 
				
			||||||
    s32 candidate_priority = THREADPRIO_LOWEST + 1;
 | 
					    s32 candidate_priority = THREADPRIO_LOWEST + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -67,7 +72,7 @@ void WaitObject::WakeupAllWaitingThreads() {
 | 
				
			|||||||
                thread->wait_set_output = false;
 | 
					                thread->wait_set_output = false;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            for (auto object : thread->wait_objects) {
 | 
					            for (auto& object : thread->wait_objects) {
 | 
				
			||||||
                object->Acquire();
 | 
					                object->Acquire();
 | 
				
			||||||
                object->RemoveWaitingThread(thread.get());
 | 
					                object->RemoveWaitingThread(thread.get());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -277,6 +277,10 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (thread->status == THREADSTATUS_WAIT_SYNCH || thread->status == THREADSTATUS_WAIT_ARB) {
 | 
					    if (thread->status == THREADSTATUS_WAIT_SYNCH || thread->status == THREADSTATUS_WAIT_ARB) {
 | 
				
			||||||
        thread->wait_set_output = false;
 | 
					        thread->wait_set_output = false;
 | 
				
			||||||
 | 
					        // Remove the thread from each of its waiting objects' waitlists
 | 
				
			||||||
 | 
					        for (auto& object : thread->wait_objects)
 | 
				
			||||||
 | 
					            object->RemoveWaitingThread(thread.get());
 | 
				
			||||||
 | 
					        thread->wait_objects.clear();
 | 
				
			||||||
        thread->SetWaitSynchronizationResult(ResultCode(ErrorDescription::Timeout, ErrorModule::OS,
 | 
					        thread->SetWaitSynchronizationResult(ResultCode(ErrorDescription::Timeout, ErrorModule::OS,
 | 
				
			||||||
                                                        ErrorSummary::StatusChanged,
 | 
					                                                        ErrorSummary::StatusChanged,
 | 
				
			||||||
                                                        ErrorLevel::Info));
 | 
					                                                        ErrorLevel::Info));
 | 
				
			||||||
 | 
				
			|||||||
@ -321,7 +321,7 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
        if (all_available) {
 | 
					        if (all_available) {
 | 
				
			||||||
            // We can acquire all objects right now, do so.
 | 
					            // We can acquire all objects right now, do so.
 | 
				
			||||||
            for (auto object : objects)
 | 
					            for (auto& object : objects)
 | 
				
			||||||
                object->Acquire();
 | 
					                object->Acquire();
 | 
				
			||||||
            // Note: In this case, the `out` parameter is not set, and retains whatever value it had before.
 | 
					            // Note: In this case, the `out` parameter is not set, and retains whatever value it had before.
 | 
				
			||||||
            return RESULT_SUCCESS;
 | 
					            return RESULT_SUCCESS;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user