diff options
| author | 2017-01-04 12:48:13 -0500 | |
|---|---|---|
| committer | 2017-01-05 09:40:18 -0500 | |
| commit | dda4ec93bea089e3286e9a965378d9411f480acd (patch) | |
| tree | 29b3fcb87e02fc92e514e28877b588f09264c026 /src/core | |
| parent | Kernel: Remove a thread from all of its waiting objects' waiting_threads list... (diff) | |
| download | yuzu-dda4ec93bea089e3286e9a965378d9411f480acd.tar.gz yuzu-dda4ec93bea089e3286e9a965378d9411f480acd.tar.xz yuzu-dda4ec93bea089e3286e9a965378d9411f480acd.zip | |
Kernel: Add some asserts to enforce the invariants in the scheduler.
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 7 |
2 files changed, 13 insertions, 2 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 47d4df69c..f599916f0 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -27,6 +27,9 @@ void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) { | |||
| 27 | 27 | ||
| 28 | void WaitObject::RemoveWaitingThread(Thread* thread) { | 28 | void WaitObject::RemoveWaitingThread(Thread* thread) { |
| 29 | auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread); | 29 | auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread); |
| 30 | // If a thread passed multiple handles to the same object, | ||
| 31 | // the kernel might attempt to remove the thread from the object's | ||
| 32 | // waiting threads list multiple times. | ||
| 30 | if (itr != waiting_threads.end()) | 33 | if (itr != waiting_threads.end()) |
| 31 | waiting_threads.erase(itr); | 34 | waiting_threads.erase(itr); |
| 32 | } | 35 | } |
| @@ -36,6 +39,11 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() { | |||
| 36 | s32 candidate_priority = THREADPRIO_LOWEST + 1; | 39 | s32 candidate_priority = THREADPRIO_LOWEST + 1; |
| 37 | 40 | ||
| 38 | for (const auto& thread : waiting_threads) { | 41 | for (const auto& thread : waiting_threads) { |
| 42 | // The list of waiting threads must not contain threads that are not waiting to be awakened. | ||
| 43 | ASSERT_MSG(thread->status == THREADSTATUS_WAIT_SYNCH_ANY || | ||
| 44 | thread->status == THREADSTATUS_WAIT_SYNCH_ALL, | ||
| 45 | "Inconsistent thread statuses in waiting_threads"); | ||
| 46 | |||
| 39 | if (thread->current_priority >= candidate_priority) | 47 | if (thread->current_priority >= candidate_priority) |
| 40 | continue; | 48 | continue; |
| 41 | 49 | ||
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 568cef5b9..9109bd10b 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -200,8 +200,8 @@ static void SwitchContext(Thread* new_thread) { | |||
| 200 | 200 | ||
| 201 | // Load context of new thread | 201 | // Load context of new thread |
| 202 | if (new_thread) { | 202 | if (new_thread) { |
| 203 | DEBUG_ASSERT_MSG(new_thread->status == THREADSTATUS_READY, | 203 | ASSERT_MSG(new_thread->status == THREADSTATUS_READY, |
| 204 | "Thread must be ready to become running."); | 204 | "Thread must be ready to become running."); |
| 205 | 205 | ||
| 206 | // Cancel any outstanding wakeup events for this thread | 206 | // Cancel any outstanding wakeup events for this thread |
| 207 | CoreTiming::UnscheduleEvent(ThreadWakeupEventType, new_thread->callback_handle); | 207 | CoreTiming::UnscheduleEvent(ThreadWakeupEventType, new_thread->callback_handle); |
| @@ -307,6 +307,8 @@ void Thread::WakeAfterDelay(s64 nanoseconds) { | |||
| 307 | } | 307 | } |
| 308 | 308 | ||
| 309 | void Thread::ResumeFromWait() { | 309 | void Thread::ResumeFromWait() { |
| 310 | ASSERT_MSG(wait_objects.empty(), "Thread is waking up while waiting for objects"); | ||
| 311 | |||
| 310 | switch (status) { | 312 | switch (status) { |
| 311 | case THREADSTATUS_WAIT_SYNCH_ALL: | 313 | case THREADSTATUS_WAIT_SYNCH_ALL: |
| 312 | case THREADSTATUS_WAIT_SYNCH_ANY: | 314 | case THREADSTATUS_WAIT_SYNCH_ANY: |
| @@ -580,6 +582,7 @@ void Thread::SetWaitSynchronizationOutput(s32 output) { | |||
| 580 | } | 582 | } |
| 581 | 583 | ||
| 582 | s32 Thread::GetWaitObjectIndex(WaitObject* object) const { | 584 | s32 Thread::GetWaitObjectIndex(WaitObject* object) const { |
| 585 | ASSERT_MSG(!wait_objects.empty(), "Thread is not waiting for anything"); | ||
| 583 | auto match = std::find(wait_objects.rbegin(), wait_objects.rend(), object); | 586 | auto match = std::find(wait_objects.rbegin(), wait_objects.rend(), object); |
| 584 | return std::distance(match, wait_objects.rend()) - 1; | 587 | return std::distance(match, wait_objects.rend()) - 1; |
| 585 | } | 588 | } |