mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Kernel: Use different thread statuses when a thread calls WaitSynchronization1 and WaitSynchronizationN with wait_all = true.
This commit removes the overly general THREADSTATUS_WAIT_SYNCH and replaces it with two more granular statuses: THREADSTATUS_WAIT_SYNCH_ANY when a thread waits on objects via WaitSynchronization1 or WaitSynchronizationN with wait_all = false. THREADSTATUS_WAIT_SYNCH_ALL when a thread waits on objects via WaitSynchronizationN with wait_all = true.
This commit is contained in:
		
							parent
							
								
									d3ff5b91e1
								
							
						
					
					
						commit
						cef5f45de2
					
				
					 4 changed files with 26 additions and 19 deletions
				
			
		|  | @ -153,7 +153,8 @@ QString WaitTreeThread::GetText() const { | |||
|     case THREADSTATUS_WAIT_SLEEP: | ||||
|         status = tr("sleeping"); | ||||
|         break; | ||||
|     case THREADSTATUS_WAIT_SYNCH: | ||||
|     case THREADSTATUS_WAIT_SYNCH_ALL: | ||||
|     case THREADSTATUS_WAIT_SYNCH_ANY: | ||||
|         status = tr("waiting for objects"); | ||||
|         break; | ||||
|     case THREADSTATUS_DORMANT: | ||||
|  | @ -180,7 +181,8 @@ QColor WaitTreeThread::GetColor() const { | |||
|         return QColor(Qt::GlobalColor::darkRed); | ||||
|     case THREADSTATUS_WAIT_SLEEP: | ||||
|         return QColor(Qt::GlobalColor::darkYellow); | ||||
|     case THREADSTATUS_WAIT_SYNCH: | ||||
|     case THREADSTATUS_WAIT_SYNCH_ALL: | ||||
|     case THREADSTATUS_WAIT_SYNCH_ANY: | ||||
|         return QColor(Qt::GlobalColor::red); | ||||
|     case THREADSTATUS_DORMANT: | ||||
|         return QColor(Qt::GlobalColor::darkCyan); | ||||
|  | @ -228,7 +230,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { | |||
|     } else { | ||||
|         list.push_back(std::make_unique<WaitTreeMutexList>(thread.held_mutexes)); | ||||
|     } | ||||
|     if (thread.status == THREADSTATUS_WAIT_SYNCH) { | ||||
|     if (thread.status == THREADSTATUS_WAIT_SYNCH_ANY || | ||||
|         thread.status == THREADSTATUS_WAIT_SYNCH_ALL) { | ||||
|         list.push_back(std::make_unique<WaitTreeObjectList>(thread.wait_objects, | ||||
|                                                             thread.IsSleepingOnWaitAll())); | ||||
|     } | ||||
|  |  | |||
|  | @ -72,7 +72,8 @@ Thread* GetCurrentThread() { | |||
|  * @return True if the thread is waiting, false otherwise | ||||
|  */ | ||||
| static bool CheckWait_WaitObject(const Thread* thread, WaitObject* wait_object) { | ||||
|     if (thread->status != THREADSTATUS_WAIT_SYNCH) | ||||
|     if (thread->status != THREADSTATUS_WAIT_SYNCH_ALL && | ||||
|         thread->status != THREADSTATUS_WAIT_SYNCH_ANY) | ||||
|         return false; | ||||
| 
 | ||||
|     auto itr = std::find(thread->wait_objects.begin(), thread->wait_objects.end(), wait_object); | ||||
|  | @ -253,7 +254,7 @@ void WaitCurrentThread_WaitSynchronization(std::vector<SharedPtr<WaitObject>> wa | |||
|     Thread* thread = GetCurrentThread(); | ||||
|     thread->wait_set_output = wait_set_output; | ||||
|     thread->wait_objects = std::move(wait_objects); | ||||
|     thread->status = THREADSTATUS_WAIT_SYNCH; | ||||
|     thread->status = THREADSTATUS_WAIT_SYNCH_ANY; | ||||
| } | ||||
| 
 | ||||
| void WaitCurrentThread_ArbitrateAddress(VAddr wait_address) { | ||||
|  | @ -281,7 +282,8 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) { | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (thread->status == THREADSTATUS_WAIT_SYNCH || thread->status == THREADSTATUS_WAIT_ARB) { | ||||
|     if (thread->status == THREADSTATUS_WAIT_SYNCH_ANY || | ||||
|         thread->status == THREADSTATUS_WAIT_SYNCH_ALL || thread->status == THREADSTATUS_WAIT_ARB) { | ||||
|         thread->wait_set_output = false; | ||||
|         // Remove the thread from each of its waiting objects' waitlists
 | ||||
|         for (auto& object : thread->wait_objects) | ||||
|  | @ -306,7 +308,8 @@ void Thread::WakeAfterDelay(s64 nanoseconds) { | |||
| 
 | ||||
| void Thread::ResumeFromWait() { | ||||
|     switch (status) { | ||||
|     case THREADSTATUS_WAIT_SYNCH: | ||||
|     case THREADSTATUS_WAIT_SYNCH_ALL: | ||||
|     case THREADSTATUS_WAIT_SYNCH_ANY: | ||||
|     case THREADSTATUS_WAIT_ARB: | ||||
|     case THREADSTATUS_WAIT_SLEEP: | ||||
|         break; | ||||
|  |  | |||
|  | @ -31,13 +31,14 @@ enum ThreadProcessorId : s32 { | |||
| }; | ||||
| 
 | ||||
| enum ThreadStatus { | ||||
|     THREADSTATUS_RUNNING,    ///< Currently running
 | ||||
|     THREADSTATUS_READY,      ///< Ready to run
 | ||||
|     THREADSTATUS_WAIT_ARB,   ///< Waiting on an address arbiter
 | ||||
|     THREADSTATUS_WAIT_SLEEP, ///< Waiting due to a SleepThread SVC
 | ||||
|     THREADSTATUS_WAIT_SYNCH, ///< Waiting due to a WaitSynchronization SVC
 | ||||
|     THREADSTATUS_DORMANT,    ///< Created but not yet made ready
 | ||||
|     THREADSTATUS_DEAD        ///< Run to completion, or forcefully terminated
 | ||||
|     THREADSTATUS_RUNNING,        ///< Currently running
 | ||||
|     THREADSTATUS_READY,          ///< Ready to run
 | ||||
|     THREADSTATUS_WAIT_ARB,       ///< Waiting on an address arbiter
 | ||||
|     THREADSTATUS_WAIT_SLEEP,     ///< Waiting due to a SleepThread SVC
 | ||||
|     THREADSTATUS_WAIT_SYNCH_ANY, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false
 | ||||
|     THREADSTATUS_WAIT_SYNCH_ALL, ///< Waiting due to WaitSynchronizationN with wait_all = true
 | ||||
|     THREADSTATUS_DORMANT,        ///< Created but not yet made ready
 | ||||
|     THREADSTATUS_DEAD            ///< Run to completion, or forcefully terminated
 | ||||
| }; | ||||
| 
 | ||||
| namespace Kernel { | ||||
|  | @ -158,10 +159,10 @@ public: | |||
|     /**
 | ||||
|      * Returns whether this thread is waiting for all the objects in | ||||
|      * its wait list to become ready, as a result of a WaitSynchronizationN call | ||||
|      * with wait_all = true, or a ReplyAndReceive call. | ||||
|      * with wait_all = true. | ||||
|      */ | ||||
|     bool IsSleepingOnWaitAll() const { | ||||
|         return !wait_objects.empty(); | ||||
|         return status == THREADSTATUS_WAIT_SYNCH_ALL; | ||||
|     } | ||||
| 
 | ||||
|     ARM_Interface::ThreadContext context; | ||||
|  |  | |||
|  | @ -278,7 +278,7 @@ static ResultCode WaitSynchronization1(Kernel::Handle handle, s64 nano_seconds) | |||
|             return ERR_SYNC_TIMEOUT; | ||||
| 
 | ||||
|         object->AddWaitingThread(thread); | ||||
|         thread->status = THREADSTATUS_WAIT_SYNCH; | ||||
|         thread->status = THREADSTATUS_WAIT_SYNCH_ANY; | ||||
| 
 | ||||
|         // Create an event to wake the thread up after the specified nanosecond delay has passed
 | ||||
|         thread->WakeAfterDelay(nano_seconds); | ||||
|  | @ -351,7 +351,7 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha | |||
|             return ERR_SYNC_TIMEOUT; | ||||
| 
 | ||||
|         // Put the thread to sleep
 | ||||
|         thread->status = THREADSTATUS_WAIT_SYNCH; | ||||
|         thread->status = THREADSTATUS_WAIT_SYNCH_ALL; | ||||
| 
 | ||||
|         // Add the thread to each of the objects' waiting threads.
 | ||||
|         for (auto& object : objects) { | ||||
|  | @ -393,7 +393,7 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha | |||
|             return ERR_SYNC_TIMEOUT; | ||||
| 
 | ||||
|         // Put the thread to sleep
 | ||||
|         thread->status = THREADSTATUS_WAIT_SYNCH; | ||||
|         thread->status = THREADSTATUS_WAIT_SYNCH_ANY; | ||||
| 
 | ||||
|         // Clear the thread's waitlist, we won't use it for wait_all = false
 | ||||
|         thread->wait_objects.clear(); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue