kern: update scheduler for new switch count tracking logic

This commit is contained in:
Michael Scire 2023-02-21 03:12:17 -07:00
parent 8176f085f1
commit 3a5f406c5f
6 changed files with 39 additions and 18 deletions

View file

@ -219,12 +219,21 @@ namespace ams::kern {
const s32 core_id = GetCurrentCoreId();
KThread *thread = process->GetRunningThread(core_id);
/* Check that the thread's idle count is correct. */
R_UNLESS(process->GetRunningThreadIdleCount(core_id) == Kernel::GetScheduler(core_id).GetIdleCount(), svc::ResultNoThread());
/* Check that the thread is running on the current core. */
R_UNLESS(thread != nullptr, svc::ResultUnknownThread());
R_UNLESS(thread->GetActiveCore() == core_id, svc::ResultUnknownThread());
/* We want to check that the thread is actually running. */
/* If it is, then the scheduler will have just switched from the thread to the current thread. */
/* This implies exactly one switch will have taken place, and the current thread will be on the current core. */
const auto &scheduler = Kernel::GetScheduler(core_id);
if (!(thread != nullptr && thread->GetActiveCore() == core_id && process->GetRunningThreadSwitchCount(core_id) + 1 == scheduler.GetSwitchCount())) {
/* The most recent thread switch was from a thread other than the expected one to the current one. */
/* We want to use the appropriate result to inform userland about what thread we switched from. */
if (scheduler.GetIdleCount() + 1 == scheduler.GetSwitchCount()) {
/* We switched from the idle thread. */
R_THROW(svc::ResultNoThread());
} else {
/* We switched from some other unknown thread. */
R_THROW(svc::ResultUnknownThread());
}
}
/* Get the thread's exception context. */
GetExceptionContext(thread)->GetSvcThreadContext(out_context);

View file

@ -211,9 +211,10 @@ namespace ams::kern {
/* Set thread fields. */
for (size_t i = 0; i < cpu::NumCores; i++) {
m_running_threads[i] = nullptr;
m_pinned_threads[i] = nullptr;
m_running_thread_idle_counts[i] = 0;
m_running_threads[i] = nullptr;
m_pinned_threads[i] = nullptr;
m_running_thread_idle_counts[i] = 0;
m_running_thread_switch_counts[i] = 0;
}
/* Set max memory based on address space type. */

View file

@ -88,10 +88,12 @@ namespace ams::kern {
if (m_state.should_count_idle) {
if (AMS_LIKELY(highest_thread != nullptr)) {
if (KProcess *process = highest_thread->GetOwnerProcess(); process != nullptr) {
process->SetRunningThread(m_core_id, highest_thread, m_state.idle_count);
/* Set running thread (and increment switch count). */
process->SetRunningThread(m_core_id, highest_thread, m_state.idle_count, ++m_state.switch_count);
}
} else {
m_state.idle_count++;
/* Set idle count and switch count to switch count + 1. */
m_state.idle_count = ++m_state.switch_count;
}
}