Kernel: Add some asserts to enforce the invariants in the scheduler.
This commit is contained in:
parent
7f1dca8cd2
commit
dda4ec93be
2 changed files with 13 additions and 2 deletions
|
@ -27,6 +27,9 @@ void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) {
|
||||||
|
|
||||||
void WaitObject::RemoveWaitingThread(Thread* thread) {
|
void WaitObject::RemoveWaitingThread(Thread* thread) {
|
||||||
auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
|
auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
|
||||||
|
// If a thread passed multiple handles to the same object,
|
||||||
|
// the kernel might attempt to remove the thread from the object's
|
||||||
|
// waiting threads list multiple times.
|
||||||
if (itr != waiting_threads.end())
|
if (itr != waiting_threads.end())
|
||||||
waiting_threads.erase(itr);
|
waiting_threads.erase(itr);
|
||||||
}
|
}
|
||||||
|
@ -36,6 +39,11 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {
|
||||||
s32 candidate_priority = THREADPRIO_LOWEST + 1;
|
s32 candidate_priority = THREADPRIO_LOWEST + 1;
|
||||||
|
|
||||||
for (const auto& thread : waiting_threads) {
|
for (const auto& thread : waiting_threads) {
|
||||||
|
// The list of waiting threads must not contain threads that are not waiting to be awakened.
|
||||||
|
ASSERT_MSG(thread->status == THREADSTATUS_WAIT_SYNCH_ANY ||
|
||||||
|
thread->status == THREADSTATUS_WAIT_SYNCH_ALL,
|
||||||
|
"Inconsistent thread statuses in waiting_threads");
|
||||||
|
|
||||||
if (thread->current_priority >= candidate_priority)
|
if (thread->current_priority >= candidate_priority)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -200,8 +200,8 @@ static void SwitchContext(Thread* new_thread) {
|
||||||
|
|
||||||
// Load context of new thread
|
// Load context of new thread
|
||||||
if (new_thread) {
|
if (new_thread) {
|
||||||
DEBUG_ASSERT_MSG(new_thread->status == THREADSTATUS_READY,
|
ASSERT_MSG(new_thread->status == THREADSTATUS_READY,
|
||||||
"Thread must be ready to become running.");
|
"Thread must be ready to become running.");
|
||||||
|
|
||||||
// Cancel any outstanding wakeup events for this thread
|
// Cancel any outstanding wakeup events for this thread
|
||||||
CoreTiming::UnscheduleEvent(ThreadWakeupEventType, new_thread->callback_handle);
|
CoreTiming::UnscheduleEvent(ThreadWakeupEventType, new_thread->callback_handle);
|
||||||
|
@ -307,6 +307,8 @@ void Thread::WakeAfterDelay(s64 nanoseconds) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::ResumeFromWait() {
|
void Thread::ResumeFromWait() {
|
||||||
|
ASSERT_MSG(wait_objects.empty(), "Thread is waking up while waiting for objects");
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case THREADSTATUS_WAIT_SYNCH_ALL:
|
case THREADSTATUS_WAIT_SYNCH_ALL:
|
||||||
case THREADSTATUS_WAIT_SYNCH_ANY:
|
case THREADSTATUS_WAIT_SYNCH_ANY:
|
||||||
|
@ -580,6 +582,7 @@ void Thread::SetWaitSynchronizationOutput(s32 output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 Thread::GetWaitObjectIndex(WaitObject* object) const {
|
s32 Thread::GetWaitObjectIndex(WaitObject* object) const {
|
||||||
|
ASSERT_MSG(!wait_objects.empty(), "Thread is not waiting for anything");
|
||||||
auto match = std::find(wait_objects.rbegin(), wait_objects.rend(), object);
|
auto match = std::find(wait_objects.rbegin(), wait_objects.rend(), object);
|
||||||
return std::distance(match, wait_objects.rend()) - 1;
|
return std::distance(match, wait_objects.rend()) - 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue