/** * Switches the CPU's active thread context to that of the specified thread * @param new_thread The thread to switch to */ static void SwitchContext(Thread* new_thread) { DEBUG_ASSERT_MSG(new_thread->status == THREADSTATUS_READY, "Thread must be ready to become running."); Thread* previous_thread = GetCurrentThread(); // Save context for previous thread if (previous_thread) { Core::g_app_core->SaveContext(previous_thread->context); if (previous_thread->status == THREADSTATUS_RUNNING) { // This is only the case when a reschedule is triggered without the current thread // yielding execution (i.e. an event triggered, system core time-sliced, etc) ready_queue.push_front(previous_thread->current_priority, previous_thread); previous_thread->status = THREADSTATUS_READY; } } // Load context of new thread if (new_thread) { current_thread = new_thread; ready_queue.remove(new_thread->current_priority, new_thread); new_thread->status = THREADSTATUS_RUNNING; Core::g_app_core->LoadContext(new_thread->context); } else { current_thread = nullptr; } }
/// Change a thread to "ready" state void ChangeReadyState(Thread* t, bool ready) { Handle handle = t->GetHandle(); if (t->IsReady()) { if (!ready) { g_thread_ready_queue.remove(t->current_priority, handle); } } else if (ready) { if (t->IsRunning()) { g_thread_ready_queue.push_front(t->current_priority, handle); } else { g_thread_ready_queue.push_back(t->current_priority, handle); } t->status = THREADSTATUS_READY; } }