#pragma once // ke_sched.h - Multi-Level Feedback Queue scheduler // Three run queues (Low / Normal / High). IRQ 0 drives KeSchedulerTick. #include #define SCHED_TICK_MS 10u #define SCHED_HIGH_QUANTUM_TICKS 2u #define SCHED_NORMAL_QUANTUM_TICKS 4u #define SCHED_LOW_QUANTUM_TICKS 8u #define SCHED_DEMOTE_AFTER_BURST_TICKS 16u #define SCHED_AGING_INTERVAL_TICKS 100u typedef struct KE_SCHED_STATS { uint64_t Ticks; uint64_t ContextSwitches; uint64_t KeepCurrentDecisions; uint64_t IdleSelections; uint64_t Demotions; uint64_t AgingPromotions; uint64_t QuantumExpirations; uint64_t PriorityPreemptions; uint64_t VoluntaryBlocks; uint64_t CpuBurstDemotions; } KE_SCHED_STATS; // Called once by KernelMain before any threads are created. void KeInitializeScheduler(void); // Add / remove a thread from the run queues. void KeReadyThread(THREAD* thread); void KeUnreadyThread(THREAD* thread); // Called from the timer ISR every SCHED_TICK_MS. This performs timer // accounting and requests a reschedule only when the current thread has // exhausted its scheduler budget, or when idle work becomes available. The // actual context switch happens from // KiExitInterrupt after the IRQ handler has returned and EOI has been sent. void KeSchedulerTick(void); // Internal scheduler hooks used by the interrupt-exit path. KiRequestReschedule // is cheap and can be called from interrupt context. KiScheduleFromInterrupt // consumes the pending request and performs the context switch, if needed. void KiRequestReschedule(void); int KiIsReschedulePending(void); void KiScheduleFromInterrupt(void); void KiSchedulerNoteVoluntaryBlock(THREAD* thread); // Voluntarily yield the CPU. Picks the next runnable thread immediately. __declspec(dllexport) void KeYield(void); void KeGetSchedulerStats(KE_SCHED_STATS* out); // Returns the thread currently running on this CPU (reads GS:[0]). THREAD* KeGetCurrentThread(void); // Set the current-thread GS slot. Called once per CPU at boot. void KeSetCurrentThread(THREAD* thread);