diff options
Diffstat (limited to 'src/core/hle/kernel/thread.cpp')
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 845672702..00b72477e 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -65,7 +65,7 @@ static void ResetThread(Thread* t, u32 arg, s32 lowest_priority) { | |||
| 65 | t->current_priority = t->initial_priority; | 65 | t->current_priority = t->initial_priority; |
| 66 | } | 66 | } |
| 67 | t->wait_type = WAITTYPE_NONE; | 67 | t->wait_type = WAITTYPE_NONE; |
| 68 | t->wait_object = nullptr; | 68 | t->wait_objects.clear(); |
| 69 | t->wait_address = 0; | 69 | t->wait_address = 0; |
| 70 | } | 70 | } |
| 71 | 71 | ||
| @@ -92,7 +92,11 @@ static bool CheckWaitType(const Thread* thread, WaitType type) { | |||
| 92 | 92 | ||
| 93 | /// Check if a thread is blocking on a specified wait type with a specified handle | 93 | /// Check if a thread is blocking on a specified wait type with a specified handle |
| 94 | static bool CheckWaitType(const Thread* thread, WaitType type, Object* wait_object) { | 94 | static bool CheckWaitType(const Thread* thread, WaitType type, Object* wait_object) { |
| 95 | return CheckWaitType(thread, type) && wait_object == thread->wait_object; | 95 | auto itr = std::find(thread->wait_objects.begin(), thread->wait_objects.end(), wait_object); |
| 96 | if (itr == thread->wait_objects.end()) { | ||
| 97 | return false; | ||
| 98 | } | ||
| 99 | return CheckWaitType(thread, type); | ||
| 96 | } | 100 | } |
| 97 | 101 | ||
| 98 | /// Check if a thread is blocking on a specified wait type with a specified handle and address | 102 | /// Check if a thread is blocking on a specified wait type with a specified handle and address |
| @@ -111,7 +115,7 @@ void Thread::Stop(const char* reason) { | |||
| 111 | 115 | ||
| 112 | // Stopped threads are never waiting. | 116 | // Stopped threads are never waiting. |
| 113 | wait_type = WAITTYPE_NONE; | 117 | wait_type = WAITTYPE_NONE; |
| 114 | wait_object = nullptr; | 118 | wait_objects.clear(); |
| 115 | wait_address = 0; | 119 | wait_address = 0; |
| 116 | } | 120 | } |
| 117 | 121 | ||
| @@ -216,14 +220,18 @@ static Thread* NextThread() { | |||
| 216 | return next; | 220 | return next; |
| 217 | } | 221 | } |
| 218 | 222 | ||
| 219 | void WaitCurrentThread(WaitType wait_type, Object* wait_object) { | 223 | void WaitCurrentThread(WaitType wait_type, WaitObject* wait_object) { |
| 220 | Thread* thread = GetCurrentThread(); | 224 | Thread* thread = GetCurrentThread(); |
| 221 | thread->wait_type = wait_type; | 225 | thread->wait_type = wait_type; |
| 222 | thread->wait_object = wait_object; | 226 | |
| 227 | auto res = std::find(thread->wait_objects.begin(), thread->wait_objects.end(), wait_object); | ||
| 228 | if (res == thread->wait_objects.end()) { | ||
| 229 | thread->wait_objects.push_back(wait_object); | ||
| 230 | } | ||
| 223 | ChangeThreadState(thread, ThreadStatus(THREADSTATUS_WAIT | (thread->status & THREADSTATUS_SUSPEND))); | 231 | ChangeThreadState(thread, ThreadStatus(THREADSTATUS_WAIT | (thread->status & THREADSTATUS_SUSPEND))); |
| 224 | } | 232 | } |
| 225 | 233 | ||
| 226 | void WaitCurrentThread(WaitType wait_type, Object* wait_object, VAddr wait_address) { | 234 | void WaitCurrentThread(WaitType wait_type, WaitObject* wait_object, VAddr wait_address) { |
| 227 | WaitCurrentThread(wait_type, wait_object); | 235 | WaitCurrentThread(wait_type, wait_object); |
| 228 | GetCurrentThread()->wait_address = wait_address; | 236 | GetCurrentThread()->wait_address = wait_address; |
| 229 | } | 237 | } |
| @@ -260,7 +268,13 @@ void Thread::ResumeFromWait() { | |||
| 260 | CoreTiming::UnscheduleEvent(ThreadWakeupEventType, GetHandle()); | 268 | CoreTiming::UnscheduleEvent(ThreadWakeupEventType, GetHandle()); |
| 261 | 269 | ||
| 262 | status &= ~THREADSTATUS_WAIT; | 270 | status &= ~THREADSTATUS_WAIT; |
| 263 | wait_object = nullptr; | 271 | |
| 272 | // Remove this thread from all other WaitObjects | ||
| 273 | for (auto wait_object : wait_objects) | ||
| 274 | wait_object->RemoveWaitingThread(this); | ||
| 275 | |||
| 276 | wait_objects.clear(); | ||
| 277 | |||
| 264 | wait_type = WAITTYPE_NONE; | 278 | wait_type = WAITTYPE_NONE; |
| 265 | if (!(status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) { | 279 | if (!(status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) { |
| 266 | ChangeReadyState(this, true); | 280 | ChangeReadyState(this, true); |
| @@ -328,7 +342,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | |||
| 328 | thread->initial_priority = thread->current_priority = priority; | 342 | thread->initial_priority = thread->current_priority = priority; |
| 329 | thread->processor_id = processor_id; | 343 | thread->processor_id = processor_id; |
| 330 | thread->wait_type = WAITTYPE_NONE; | 344 | thread->wait_type = WAITTYPE_NONE; |
| 331 | thread->wait_object = nullptr; | 345 | thread->wait_objects.clear(); |
| 332 | thread->wait_address = 0; | 346 | thread->wait_address = 0; |
| 333 | thread->name = std::move(name); | 347 | thread->name = std::move(name); |
| 334 | 348 | ||
| @@ -412,9 +426,8 @@ void Reschedule() { | |||
| 412 | LOG_TRACE(Kernel, "cannot context switch from 0x%08X, no higher priority thread!", prev->GetHandle()); | 426 | LOG_TRACE(Kernel, "cannot context switch from 0x%08X, no higher priority thread!", prev->GetHandle()); |
| 413 | 427 | ||
| 414 | for (auto& thread : thread_list) { | 428 | for (auto& thread : thread_list) { |
| 415 | LOG_TRACE(Kernel, "\thandle=0x%08X prio=0x%02X, status=0x%08X wait_type=0x%08X wait_handle=0x%08X", | 429 | LOG_TRACE(Kernel, "\thandle=0x%08X prio=0x%02X, status=0x%08X wait_type=0x%08X", |
| 416 | thread->GetHandle(), thread->current_priority, thread->status, thread->wait_type, | 430 | thread->GetHandle(), thread->current_priority, thread->status, thread->wait_type); |
| 417 | (thread->wait_object ? thread->wait_object->GetHandle() : INVALID_HANDLE)); | ||
| 418 | } | 431 | } |
| 419 | } | 432 | } |
| 420 | } | 433 | } |