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
					
				@ -153,7 +153,8 @@ QString WaitTreeThread::GetText() const {
 | 
				
			|||||||
    case THREADSTATUS_WAIT_SLEEP:
 | 
					    case THREADSTATUS_WAIT_SLEEP:
 | 
				
			||||||
        status = tr("sleeping");
 | 
					        status = tr("sleeping");
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case THREADSTATUS_WAIT_SYNCH:
 | 
					    case THREADSTATUS_WAIT_SYNCH_ALL:
 | 
				
			||||||
 | 
					    case THREADSTATUS_WAIT_SYNCH_ANY:
 | 
				
			||||||
        status = tr("waiting for objects");
 | 
					        status = tr("waiting for objects");
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case THREADSTATUS_DORMANT:
 | 
					    case THREADSTATUS_DORMANT:
 | 
				
			||||||
@ -180,7 +181,8 @@ QColor WaitTreeThread::GetColor() const {
 | 
				
			|||||||
        return QColor(Qt::GlobalColor::darkRed);
 | 
					        return QColor(Qt::GlobalColor::darkRed);
 | 
				
			||||||
    case THREADSTATUS_WAIT_SLEEP:
 | 
					    case THREADSTATUS_WAIT_SLEEP:
 | 
				
			||||||
        return QColor(Qt::GlobalColor::darkYellow);
 | 
					        return QColor(Qt::GlobalColor::darkYellow);
 | 
				
			||||||
    case THREADSTATUS_WAIT_SYNCH:
 | 
					    case THREADSTATUS_WAIT_SYNCH_ALL:
 | 
				
			||||||
 | 
					    case THREADSTATUS_WAIT_SYNCH_ANY:
 | 
				
			||||||
        return QColor(Qt::GlobalColor::red);
 | 
					        return QColor(Qt::GlobalColor::red);
 | 
				
			||||||
    case THREADSTATUS_DORMANT:
 | 
					    case THREADSTATUS_DORMANT:
 | 
				
			||||||
        return QColor(Qt::GlobalColor::darkCyan);
 | 
					        return QColor(Qt::GlobalColor::darkCyan);
 | 
				
			||||||
@ -228,7 +230,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const {
 | 
				
			|||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        list.push_back(std::make_unique<WaitTreeMutexList>(thread.held_mutexes));
 | 
					        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,
 | 
					        list.push_back(std::make_unique<WaitTreeObjectList>(thread.wait_objects,
 | 
				
			||||||
                                                            thread.IsSleepingOnWaitAll()));
 | 
					                                                            thread.IsSleepingOnWaitAll()));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -72,7 +72,8 @@ Thread* GetCurrentThread() {
 | 
				
			|||||||
 * @return True if the thread is waiting, false otherwise
 | 
					 * @return True if the thread is waiting, false otherwise
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static bool CheckWait_WaitObject(const Thread* thread, WaitObject* wait_object) {
 | 
					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;
 | 
					        return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto itr = std::find(thread->wait_objects.begin(), thread->wait_objects.end(), wait_object);
 | 
					    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* thread = GetCurrentThread();
 | 
				
			||||||
    thread->wait_set_output = wait_set_output;
 | 
					    thread->wait_set_output = wait_set_output;
 | 
				
			||||||
    thread->wait_objects = std::move(wait_objects);
 | 
					    thread->wait_objects = std::move(wait_objects);
 | 
				
			||||||
    thread->status = THREADSTATUS_WAIT_SYNCH;
 | 
					    thread->status = THREADSTATUS_WAIT_SYNCH_ANY;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void WaitCurrentThread_ArbitrateAddress(VAddr wait_address) {
 | 
					void WaitCurrentThread_ArbitrateAddress(VAddr wait_address) {
 | 
				
			||||||
@ -281,7 +282,8 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) {
 | 
				
			|||||||
        return;
 | 
					        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;
 | 
					        thread->wait_set_output = false;
 | 
				
			||||||
        // Remove the thread from each of its waiting objects' waitlists
 | 
					        // Remove the thread from each of its waiting objects' waitlists
 | 
				
			||||||
        for (auto& object : thread->wait_objects)
 | 
					        for (auto& object : thread->wait_objects)
 | 
				
			||||||
@ -306,7 +308,8 @@ void Thread::WakeAfterDelay(s64 nanoseconds) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void Thread::ResumeFromWait() {
 | 
					void Thread::ResumeFromWait() {
 | 
				
			||||||
    switch (status) {
 | 
					    switch (status) {
 | 
				
			||||||
    case THREADSTATUS_WAIT_SYNCH:
 | 
					    case THREADSTATUS_WAIT_SYNCH_ALL:
 | 
				
			||||||
 | 
					    case THREADSTATUS_WAIT_SYNCH_ANY:
 | 
				
			||||||
    case THREADSTATUS_WAIT_ARB:
 | 
					    case THREADSTATUS_WAIT_ARB:
 | 
				
			||||||
    case THREADSTATUS_WAIT_SLEEP:
 | 
					    case THREADSTATUS_WAIT_SLEEP:
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
				
			|||||||
@ -31,13 +31,14 @@ enum ThreadProcessorId : s32 {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum ThreadStatus {
 | 
					enum ThreadStatus {
 | 
				
			||||||
    THREADSTATUS_RUNNING,    ///< Currently running
 | 
					    THREADSTATUS_RUNNING,        ///< Currently running
 | 
				
			||||||
    THREADSTATUS_READY,      ///< Ready to run
 | 
					    THREADSTATUS_READY,          ///< Ready to run
 | 
				
			||||||
    THREADSTATUS_WAIT_ARB,   ///< Waiting on an address arbiter
 | 
					    THREADSTATUS_WAIT_ARB,       ///< Waiting on an address arbiter
 | 
				
			||||||
    THREADSTATUS_WAIT_SLEEP, ///< Waiting due to a SleepThread SVC
 | 
					    THREADSTATUS_WAIT_SLEEP,     ///< Waiting due to a SleepThread SVC
 | 
				
			||||||
    THREADSTATUS_WAIT_SYNCH, ///< Waiting due to a WaitSynchronization SVC
 | 
					    THREADSTATUS_WAIT_SYNCH_ANY, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false
 | 
				
			||||||
    THREADSTATUS_DORMANT,    ///< Created but not yet made ready
 | 
					    THREADSTATUS_WAIT_SYNCH_ALL, ///< Waiting due to WaitSynchronizationN with wait_all = true
 | 
				
			||||||
    THREADSTATUS_DEAD        ///< Run to completion, or forcefully terminated
 | 
					    THREADSTATUS_DORMANT,        ///< Created but not yet made ready
 | 
				
			||||||
 | 
					    THREADSTATUS_DEAD            ///< Run to completion, or forcefully terminated
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kernel {
 | 
					namespace Kernel {
 | 
				
			||||||
@ -158,10 +159,10 @@ public:
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns whether this thread is waiting for all the objects in
 | 
					     * Returns whether this thread is waiting for all the objects in
 | 
				
			||||||
     * its wait list to become ready, as a result of a WaitSynchronizationN call
 | 
					     * 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 {
 | 
					    bool IsSleepingOnWaitAll() const {
 | 
				
			||||||
        return !wait_objects.empty();
 | 
					        return status == THREADSTATUS_WAIT_SYNCH_ALL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ARM_Interface::ThreadContext context;
 | 
					    ARM_Interface::ThreadContext context;
 | 
				
			||||||
 | 
				
			|||||||
@ -278,7 +278,7 @@ static ResultCode WaitSynchronization1(Kernel::Handle handle, s64 nano_seconds)
 | 
				
			|||||||
            return ERR_SYNC_TIMEOUT;
 | 
					            return ERR_SYNC_TIMEOUT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        object->AddWaitingThread(thread);
 | 
					        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
 | 
					        // Create an event to wake the thread up after the specified nanosecond delay has passed
 | 
				
			||||||
        thread->WakeAfterDelay(nano_seconds);
 | 
					        thread->WakeAfterDelay(nano_seconds);
 | 
				
			||||||
@ -351,7 +351,7 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha
 | 
				
			|||||||
            return ERR_SYNC_TIMEOUT;
 | 
					            return ERR_SYNC_TIMEOUT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Put the thread to sleep
 | 
					        // 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.
 | 
					        // Add the thread to each of the objects' waiting threads.
 | 
				
			||||||
        for (auto& object : objects) {
 | 
					        for (auto& object : objects) {
 | 
				
			||||||
@ -393,7 +393,7 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha
 | 
				
			|||||||
            return ERR_SYNC_TIMEOUT;
 | 
					            return ERR_SYNC_TIMEOUT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Put the thread to sleep
 | 
					        // 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
 | 
					        // Clear the thread's waitlist, we won't use it for wait_all = false
 | 
				
			||||||
        thread->wait_objects.clear();
 | 
					        thread->wait_objects.clear();
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user