diff options
| author | 2017-01-04 10:44:38 -0500 | |
|---|---|---|
| committer | 2017-01-04 15:58:50 -0500 | |
| commit | cef5f45de2fd64f0728d4504d0ad7434cb8ac519 (patch) | |
| tree | a8297434a72bc21d1cec17e3414766ece0ec0054 /src/core | |
| parent | Kernel/Mutex: Propagate thread priority changes to other threads inheriting t... (diff) | |
| download | yuzu-cef5f45de2fd64f0728d4504d0ad7434cb8ac519.tar.gz yuzu-cef5f45de2fd64f0728d4504d0ad7434cb8ac519.tar.xz yuzu-cef5f45de2fd64f0728d4504d0ad7434cb8ac519.zip | |
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.
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 11 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.h | 19 | ||||
| -rw-r--r-- | src/core/hle/svc.cpp | 6 |
3 files changed, 20 insertions, 16 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 3a5a67450..aa99d18c7 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -72,7 +72,8 @@ Thread* GetCurrentThread() { | |||
| 72 | * @return True if the thread is waiting, false otherwise | 72 | * @return True if the thread is waiting, false otherwise |
| 73 | */ | 73 | */ |
| 74 | static bool CheckWait_WaitObject(const Thread* thread, WaitObject* wait_object) { | 74 | static bool CheckWait_WaitObject(const Thread* thread, WaitObject* wait_object) { |
| 75 | if (thread->status != THREADSTATUS_WAIT_SYNCH) | 75 | if (thread->status != THREADSTATUS_WAIT_SYNCH_ALL && |
| 76 | thread->status != THREADSTATUS_WAIT_SYNCH_ANY) | ||
| 76 | return false; | 77 | return false; |
| 77 | 78 | ||
| 78 | auto itr = std::find(thread->wait_objects.begin(), thread->wait_objects.end(), wait_object); | 79 | 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 | |||
| 253 | Thread* thread = GetCurrentThread(); | 254 | Thread* thread = GetCurrentThread(); |
| 254 | thread->wait_set_output = wait_set_output; | 255 | thread->wait_set_output = wait_set_output; |
| 255 | thread->wait_objects = std::move(wait_objects); | 256 | thread->wait_objects = std::move(wait_objects); |
| 256 | thread->status = THREADSTATUS_WAIT_SYNCH; | 257 | thread->status = THREADSTATUS_WAIT_SYNCH_ANY; |
| 257 | } | 258 | } |
| 258 | 259 | ||
| 259 | void WaitCurrentThread_ArbitrateAddress(VAddr wait_address) { | 260 | void WaitCurrentThread_ArbitrateAddress(VAddr wait_address) { |
| @@ -281,7 +282,8 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) { | |||
| 281 | return; | 282 | return; |
| 282 | } | 283 | } |
| 283 | 284 | ||
| 284 | if (thread->status == THREADSTATUS_WAIT_SYNCH || thread->status == THREADSTATUS_WAIT_ARB) { | 285 | if (thread->status == THREADSTATUS_WAIT_SYNCH_ANY || |
| 286 | thread->status == THREADSTATUS_WAIT_SYNCH_ALL || thread->status == THREADSTATUS_WAIT_ARB) { | ||
| 285 | thread->wait_set_output = false; | 287 | thread->wait_set_output = false; |
| 286 | // Remove the thread from each of its waiting objects' waitlists | 288 | // Remove the thread from each of its waiting objects' waitlists |
| 287 | for (auto& object : thread->wait_objects) | 289 | for (auto& object : thread->wait_objects) |
| @@ -306,7 +308,8 @@ void Thread::WakeAfterDelay(s64 nanoseconds) { | |||
| 306 | 308 | ||
| 307 | void Thread::ResumeFromWait() { | 309 | void Thread::ResumeFromWait() { |
| 308 | switch (status) { | 310 | switch (status) { |
| 309 | case THREADSTATUS_WAIT_SYNCH: | 311 | case THREADSTATUS_WAIT_SYNCH_ALL: |
| 312 | case THREADSTATUS_WAIT_SYNCH_ANY: | ||
| 310 | case THREADSTATUS_WAIT_ARB: | 313 | case THREADSTATUS_WAIT_ARB: |
| 311 | case THREADSTATUS_WAIT_SLEEP: | 314 | case THREADSTATUS_WAIT_SLEEP: |
| 312 | break; | 315 | break; |
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index e2f0cc831..6cd8c20e2 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -31,13 +31,14 @@ enum ThreadProcessorId : s32 { | |||
| 31 | }; | 31 | }; |
| 32 | 32 | ||
| 33 | enum ThreadStatus { | 33 | enum ThreadStatus { |
| 34 | THREADSTATUS_RUNNING, ///< Currently running | 34 | THREADSTATUS_RUNNING, ///< Currently running |
| 35 | THREADSTATUS_READY, ///< Ready to run | 35 | THREADSTATUS_READY, ///< Ready to run |
| 36 | THREADSTATUS_WAIT_ARB, ///< Waiting on an address arbiter | 36 | THREADSTATUS_WAIT_ARB, ///< Waiting on an address arbiter |
| 37 | THREADSTATUS_WAIT_SLEEP, ///< Waiting due to a SleepThread SVC | 37 | THREADSTATUS_WAIT_SLEEP, ///< Waiting due to a SleepThread SVC |
| 38 | THREADSTATUS_WAIT_SYNCH, ///< Waiting due to a WaitSynchronization SVC | 38 | THREADSTATUS_WAIT_SYNCH_ANY, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false |
| 39 | THREADSTATUS_DORMANT, ///< Created but not yet made ready | 39 | THREADSTATUS_WAIT_SYNCH_ALL, ///< Waiting due to WaitSynchronizationN with wait_all = true |
| 40 | THREADSTATUS_DEAD ///< Run to completion, or forcefully terminated | 40 | THREADSTATUS_DORMANT, ///< Created but not yet made ready |
| 41 | THREADSTATUS_DEAD ///< Run to completion, or forcefully terminated | ||
| 41 | }; | 42 | }; |
| 42 | 43 | ||
| 43 | namespace Kernel { | 44 | namespace Kernel { |
| @@ -158,10 +159,10 @@ public: | |||
| 158 | /** | 159 | /** |
| 159 | * Returns whether this thread is waiting for all the objects in | 160 | * Returns whether this thread is waiting for all the objects in |
| 160 | * its wait list to become ready, as a result of a WaitSynchronizationN call | 161 | * its wait list to become ready, as a result of a WaitSynchronizationN call |
| 161 | * with wait_all = true, or a ReplyAndReceive call. | 162 | * with wait_all = true. |
| 162 | */ | 163 | */ |
| 163 | bool IsSleepingOnWaitAll() const { | 164 | bool IsSleepingOnWaitAll() const { |
| 164 | return !wait_objects.empty(); | 165 | return status == THREADSTATUS_WAIT_SYNCH_ALL; |
| 165 | } | 166 | } |
| 166 | 167 | ||
| 167 | ARM_Interface::ThreadContext context; | 168 | ARM_Interface::ThreadContext context; |
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 160f27c98..1e1ca5180 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp | |||
| @@ -278,7 +278,7 @@ static ResultCode WaitSynchronization1(Kernel::Handle handle, s64 nano_seconds) | |||
| 278 | return ERR_SYNC_TIMEOUT; | 278 | return ERR_SYNC_TIMEOUT; |
| 279 | 279 | ||
| 280 | object->AddWaitingThread(thread); | 280 | object->AddWaitingThread(thread); |
| 281 | thread->status = THREADSTATUS_WAIT_SYNCH; | 281 | thread->status = THREADSTATUS_WAIT_SYNCH_ANY; |
| 282 | 282 | ||
| 283 | // Create an event to wake the thread up after the specified nanosecond delay has passed | 283 | // Create an event to wake the thread up after the specified nanosecond delay has passed |
| 284 | thread->WakeAfterDelay(nano_seconds); | 284 | thread->WakeAfterDelay(nano_seconds); |
| @@ -351,7 +351,7 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha | |||
| 351 | return ERR_SYNC_TIMEOUT; | 351 | return ERR_SYNC_TIMEOUT; |
| 352 | 352 | ||
| 353 | // Put the thread to sleep | 353 | // Put the thread to sleep |
| 354 | thread->status = THREADSTATUS_WAIT_SYNCH; | 354 | thread->status = THREADSTATUS_WAIT_SYNCH_ALL; |
| 355 | 355 | ||
| 356 | // Add the thread to each of the objects' waiting threads. | 356 | // Add the thread to each of the objects' waiting threads. |
| 357 | for (auto& object : objects) { | 357 | for (auto& object : objects) { |
| @@ -393,7 +393,7 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha | |||
| 393 | return ERR_SYNC_TIMEOUT; | 393 | return ERR_SYNC_TIMEOUT; |
| 394 | 394 | ||
| 395 | // Put the thread to sleep | 395 | // Put the thread to sleep |
| 396 | thread->status = THREADSTATUS_WAIT_SYNCH; | 396 | thread->status = THREADSTATUS_WAIT_SYNCH_ANY; |
| 397 | 397 | ||
| 398 | // Clear the thread's waitlist, we won't use it for wait_all = false | 398 | // Clear the thread's waitlist, we won't use it for wait_all = false |
| 399 | thread->wait_objects.clear(); | 399 | thread->wait_objects.clear(); |