[kernel] Change to one-shot timer scheduler

Instead of many timer interrupts and decrementing a process' remaining
quanta, change to setting a single timer for when a process should be
preempted. If it uses its whole timeslice, demote it. If it uses less
than half before blocking, promote it. Determine timeslice based on
priority as well.

This change also required changing the apic timer interface to be purely
interval (in microseconds) based instead of its previous interval/tick
hybrid.
This commit is contained in:
Justin C. Miller
2020-06-03 20:56:59 -07:00
parent ea1224e213
commit a10aca573d
7 changed files with 125 additions and 77 deletions

View File

@@ -32,18 +32,16 @@ public:
/// Enable interrupts for the LAPIC timer.
/// \arg vector Interrupt vector the timer should use
/// \arg interval The timer interval, in microseconds
/// \arg repeat If false, this timer is one-off, otherwise repeating
/// \returns The count of ticks the timer is set for
uint32_t enable_timer(isr vector, uint64_t interval, bool repeat = true);
void enable_timer(isr vector, bool repeat = true);
/// Reset the timer countdown.
/// \arg count The count of ticks before an interrupt, or 0 to stop the timer
/// \returns The count of ticks that were remaining before reset
uint32_t reset_timer(uint32_t count);
/// \arg interval The interval in us before an interrupt, or 0 to stop the timer
/// \returns The interval in us that was remaining before reset
uint32_t reset_timer(uint64_t interval);
/// Stop the timer.
/// \returns The count of ticks remaining before an interrupt was to happen
/// \returns The interval in us remaining before an interrupt was to happen
inline uint32_t stop_timer() { return reset_timer(0); }
/// Enable interrupts for the LAPIC LINT0 pin.
@@ -60,8 +58,19 @@ public:
void calibrate_timer();
private:
inline uint64_t ticks_to_us(uint32_t ticks) const {
return static_cast<uint64_t>(ticks) / m_ticks_per_us;
}
inline uint64_t us_to_ticks(uint64_t interval) const {
return interval * m_ticks_per_us;
}
void set_divisor(uint8_t divisor);
void set_repeat(bool repeat);
uint32_t enable_timer_internal(isr vector, uint8_t divisor, uint32_t count, bool repeat);
uint32_t m_divisor;
uint32_t m_ticks_per_us;
};