mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Kernel: Remove Thread::wait_objects_index and use wait_objects to hold all the objects that a thread is waiting on.
This commit is contained in:
		
							parent
							
								
									cef5f45de2
								
							
						
					
					
						commit
						fd95b6ee26
					
				
					 4 changed files with 22 additions and 21 deletions
				
			
		|  | @ -55,10 +55,16 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() { | |||
|         if (ShouldWait(thread.get())) | ||||
|             continue; | ||||
| 
 | ||||
|         bool ready_to_run = std::none_of(thread->wait_objects.begin(), thread->wait_objects.end(), | ||||
|         // A thread is ready to run if it's either in THREADSTATUS_WAIT_SYNCH_ANY or
 | ||||
|         // in THREADSTATUS_WAIT_SYNCH_ALL and the rest of the objects it is waiting on are ready.
 | ||||
|         bool ready_to_run = true; | ||||
|         if (thread->status == THREADSTATUS_WAIT_SYNCH_ALL) { | ||||
|             ready_to_run = std::none_of(thread->wait_objects.begin(), thread->wait_objects.end(), | ||||
|                                         [&thread](const SharedPtr<WaitObject>& object) { | ||||
|                                             return object->ShouldWait(thread.get()); | ||||
|                                         }); | ||||
|         } | ||||
| 
 | ||||
|         if (ready_to_run) { | ||||
|             candidate = thread.get(); | ||||
|             candidate_priority = thread->current_priority; | ||||
|  |  | |||
|  | @ -579,6 +579,11 @@ void Thread::SetWaitSynchronizationOutput(s32 output) { | |||
|     context.cpu_registers[1] = output; | ||||
| } | ||||
| 
 | ||||
| s32 Thread::GetWaitObjectIndex(WaitObject* object) const { | ||||
|     auto match = std::find(wait_objects.rbegin(), wait_objects.rend(), object); | ||||
|     return std::distance(match, wait_objects.rend()) - 1; | ||||
| } | ||||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| void ThreadingInit() { | ||||
|  |  | |||
|  | @ -135,13 +135,14 @@ public: | |||
| 
 | ||||
|     /**
 | ||||
|      * Retrieves the index that this particular object occupies in the list of objects | ||||
|      * that the thread passed to WaitSynchronizationN. | ||||
|      * that the thread passed to WaitSynchronizationN, starting the search from the last element. | ||||
|      * It is used to set the output value of WaitSynchronizationN when the thread is awakened. | ||||
|      * When a thread wakes up due to an object signal, the kernel will use the index of the last | ||||
|      * matching object in the wait objects list in case of having multiple instances of the same | ||||
|      * object in the list. | ||||
|      * @param object Object to query the index of. | ||||
|      */ | ||||
|     s32 GetWaitObjectIndex(const WaitObject* object) const { | ||||
|         return wait_objects_index.at(object->GetObjectId()); | ||||
|     } | ||||
|     s32 GetWaitObjectIndex(WaitObject* object) const; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Stops a thread, invalidating it from further use | ||||
|  | @ -190,13 +191,10 @@ public: | |||
| 
 | ||||
|     SharedPtr<Process> owner_process; ///< Process that owns this thread
 | ||||
| 
 | ||||
|     /// Objects that the thread is waiting on.
 | ||||
|     /// This is only populated when the thread should wait for all the objects to become ready.
 | ||||
|     /// Objects that the thread is waiting on, in the same order as they were
 | ||||
|     // passed to WaitSynchronization1/N.
 | ||||
|     std::vector<SharedPtr<WaitObject>> wait_objects; | ||||
| 
 | ||||
|     /// Mapping of Object ids to their position in the last waitlist that this object waited on.
 | ||||
|     boost::container::flat_map<int, s32> wait_objects_index; | ||||
| 
 | ||||
|     VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address
 | ||||
| 
 | ||||
|     /// True if the WaitSynchronizationN output parameter should be set on thread wakeup.
 | ||||
|  |  | |||
|  | @ -277,6 +277,7 @@ static ResultCode WaitSynchronization1(Kernel::Handle handle, s64 nano_seconds) | |||
|         if (nano_seconds == 0) | ||||
|             return ERR_SYNC_TIMEOUT; | ||||
| 
 | ||||
|         thread->wait_objects = {object}; | ||||
|         object->AddWaitingThread(thread); | ||||
|         thread->status = THREADSTATUS_WAIT_SYNCH_ANY; | ||||
| 
 | ||||
|  | @ -325,11 +326,6 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha | |||
|         objects[i] = object; | ||||
|     } | ||||
| 
 | ||||
|     // Clear the mapping of wait object indices.
 | ||||
|     // We don't want any lingering state in this map.
 | ||||
|     // It will be repopulated later in the wait_all = false case.
 | ||||
|     thread->wait_objects_index.clear(); | ||||
| 
 | ||||
|     if (wait_all) { | ||||
|         bool all_available = | ||||
|             std::all_of(objects.begin(), objects.end(), | ||||
|  | @ -358,7 +354,6 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha | |||
|             object->AddWaitingThread(thread); | ||||
|         } | ||||
| 
 | ||||
|         // Set the thread's waitlist to the list of objects passed to WaitSynchronizationN
 | ||||
|         thread->wait_objects = std::move(objects); | ||||
| 
 | ||||
|         // Create an event to wake the thread up after the specified nanosecond delay has passed
 | ||||
|  | @ -395,17 +390,14 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha | |||
|         // Put the thread to sleep
 | ||||
|         thread->status = THREADSTATUS_WAIT_SYNCH_ANY; | ||||
| 
 | ||||
|         // Clear the thread's waitlist, we won't use it for wait_all = false
 | ||||
|         thread->wait_objects.clear(); | ||||
| 
 | ||||
|         // Add the thread to each of the objects' waiting threads.
 | ||||
|         for (size_t i = 0; i < objects.size(); ++i) { | ||||
|             Kernel::WaitObject* object = objects[i].get(); | ||||
|             // Set the index of this object in the mapping of Objects -> index for this thread.
 | ||||
|             thread->wait_objects_index[object->GetObjectId()] = static_cast<int>(i); | ||||
|             object->AddWaitingThread(thread); | ||||
|         } | ||||
| 
 | ||||
|         thread->wait_objects = std::move(objects); | ||||
| 
 | ||||
|         // Note: If no handles and no timeout were given, then the thread will deadlock, this is
 | ||||
|         // consistent with hardware behavior.
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue