From 0a28d2db07e8d97d7d52521a2fc559a9c7b0208b Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Sun, 28 Jun 2020 17:50:29 -0700 Subject: [PATCH] [kernel] Update scheduler policies A few updates to scheduler policies: * Grant processes a startup timeslice bonus for time spent loading the process * Grant processes a small fraction of a timeslice for yielding the CPU with time left --- src/kernel/clock.h | 2 +- src/kernel/scheduler.cpp | 24 +++++++++++++++++------- src/kernel/scheduler.h | 3 +++ 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/kernel/clock.h b/src/kernel/clock.h index 4b73843..bf4657f 100644 --- a/src/kernel/clock.h +++ b/src/kernel/clock.h @@ -25,7 +25,7 @@ public: /// Update the internal state via the source /// \returns Current value of the clock - inline void update() { m_current = value(); return m_current; } + inline void update() { m_current = value(); } /// Wait in a tight loop /// \arg interval Time to wait, in ns diff --git a/src/kernel/scheduler.cpp b/src/kernel/scheduler.cpp index ca78340..16ec416 100644 --- a/src/kernel/scheduler.cpp +++ b/src/kernel/scheduler.cpp @@ -1,4 +1,5 @@ #include "apic.h" +#include "clock.h" #include "console.h" #include "cpu.h" #include "debug.h" @@ -122,7 +123,11 @@ scheduler::create_process(pid_t pid) auto *proc = new process_node; proc->pid = pid ? pid : m_next_pid++; proc->priority = default_priority; - proc->time_left = quantum(default_priority); + proc->time_left = quantum(default_priority) + startup_bonus; + + log::debug(logs::task, "Creating process %d, priority %d, time slice %d", + proc->pid, proc->priority, proc->time_left); + return proc; } @@ -213,7 +218,7 @@ scheduler::start() log::info(logs::task, "Starting scheduler."); wrmsr(msr::ia32_gs_base, reinterpret_cast(&bsp_cpu_data)); m_apic->enable_timer(isr::isrTimer, false); - schedule(); + m_apic->reset_timer(10); } void scheduler::prune(uint64_t now) @@ -302,6 +307,11 @@ scheduler::schedule() log::debug(logs::task, "Scheduler demoting process %d, priority %d", m_current->pid, m_current->priority); m_current->time_left = quantum(m_current->priority); + } else if (remaining > 0) { + // Process gave up CPU, give it a small bonus to its + // remaining timeslice. + uint32_t bonus = quantum(priority) >> 4; + m_current->time_left += bonus; } m_runlists[priority].remove(m_current); @@ -321,17 +331,17 @@ scheduler::schedule() } m_current->last_ran = m_clock; + m_current = m_runlists[priority].pop_front(); + m_current->last_ran = m_clock; + m_apic->reset_timer(m_current->time_left); if (lastpid != m_current->pid) { task_switch(m_current); - bool loading = m_current->flags && process_flags::loading; - log::debug(logs::task, "Scheduler switched to process %d, priority %d @ %lld.", - m_current->pid, m_current->priority, m_clock); + log::debug(logs::task, "Scheduler switched to process %d, priority %d time left %d @ %lld.", + m_current->pid, m_current->priority, m_current->time_left, m_clock); } - - m_apic->reset_timer(m_current->time_left); } process_node * diff --git a/src/kernel/scheduler.h b/src/kernel/scheduler.h index 70ac537..efcf857 100644 --- a/src/kernel/scheduler.h +++ b/src/kernel/scheduler.h @@ -33,6 +33,9 @@ public: /// How long the base timer quantum is, in us static const uint64_t quantum_micros = 500; + /// How much extra time (in us) to give a process to let it load + static const uint64_t startup_bonus = 16000; + /// How many quanta a process gets before being rescheduled static const uint16_t process_quanta = 10;