Files
nt-lite/code/kernel/include/kernel/ke_sched.h
T

131 lines
5.1 KiB
C

// Kernel ke sched declarations shared by implementation files and kernel clients.
#pragma once
#include <stdbool.h>
// The scheduler combines dynamic normal queues with static real-time queues.
// Per-processor timer IRQs drive KeSchedulerTick.
#include <kernel/ke_thread.h>
struct KCPU;
#define SCHED_TICK_MS 10u
#define SCHED_REALTIME_QUANTUM_TICKS 1u
#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
#define KE_PRIORITY_INHERITANCE_MAX_DEPTH 64u
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;
uint64_t SmtSiblingDeferrals;
uint64_t SmtPrimaryPokes;
uint64_t RealtimeDispatches;
uint64_t RealtimePreemptions;
uint64_t PriorityInheritanceBoosts;
uint64_t PriorityInheritanceDrops;
uint64_t PriorityInheritancePropagations;
uint64_t PriorityInheritanceMaxDepth;
} KE_SCHED_STATS;
struct MUTEX;
typedef struct KE_THREAD_SCHEDULER_SNAPSHOT {
THREAD_STATE State;
KE_SCHEDULING_CLASS BaseSchedulingClass;
uint32_t BasePriority;
KE_SCHEDULING_CLASS EffectiveSchedulingClass;
uint32_t EffectivePriority;
uint32_t RunningCpu;
uint32_t LastCpu;
uint32_t QuantumRemaining;
uint32_t QuantumTicks;
uint32_t CpuBurstTicks;
uint32_t LastRunTicks;
uint32_t WaitObjectType;
KSTATUS WaitStatus;
struct MUTEX* WaitingMutex;
bool Queued;
bool AlertableWait;
} KE_THREAD_SCHEDULER_SNAPSHOT;
// Copies scheduler-owned thread state into a stable diagnostic snapshot.
void KiSchedulerSnapshotThread(THREAD* thread, KE_THREAD_SCHEDULER_SNAPSHOT* snapshot);
// Selects waiters and refreshes donations while the mutex lock is held.
struct THREAD* KiSchedulerSelectMutexWaiter(struct MUTEX* mutex);
bool KiSchedulerRefreshMutexDonation(struct MUTEX* mutex);
// Updates one thread's normal-class base priority.
KSTATUS KiSchedulerSetNormalPriority(THREAD* thread, THREAD_PRIORITY priority);
// Publishes one mutex dependency atomically with cycle detection.
KSTATUS KiSchedulerPrepareMutexWait(THREAD* thread, struct MUTEX* mutex, THREAD* owner);
void KiSchedulerCancelMutexWait(THREAD* thread, struct MUTEX* mutex);
// Associates mutex ownership with priority-inheritance bookkeeping.
void KiSchedulerAcquireMutexOwnership(THREAD* thread, struct MUTEX* mutex);
void KiSchedulerTransferMutexOwnership(THREAD* oldOwner, THREAD* newOwner,
struct MUTEX* mutex);
void KiSchedulerReleaseMutexOwnership(THREAD* thread, struct MUTEX* mutex);
struct MUTEX* KiSchedulerFirstOwnedMutex(THREAD* thread);
void KiSchedulerNotePriorityPropagation(uint32_t depth);
// Recomputes effective rank and optionally returns a referenced upstream mutex.
bool KiSchedulerRefreshEffectivePriority(THREAD* thread, struct MUTEX** waitingMutexOut);
// Called once by KernelMain before any threads are created.
void KeInitializeScheduler(void);
// Split global scheduler setup from per-CPU idle-thread creation so AP bring-up
// can add one idle thread per CPU without reinitializing the global queues.
void KiInitializeSchedulerGlobal(void);
KSTATUS KiCreateIdleThreadForCpu(struct KCPU* cpu);
// Add / remove a thread from the run queues.
void KeReadyThread(THREAD* thread);
void KeUnreadyThread(THREAD* thread);
// Called from each CPU timer ISR every SCHED_TICK_MS. Every CPU performs local
// quantum accounting and may request a local reschedule. Only the boot processor advances
// global scheduler time and services sleepers, waitable timers, input repeat,
// and priority aging. 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);
bool KiIsReschedulePending(void);
void KiScheduleFromInterrupt(void);
void KiSchedulerNoteVoluntaryBlock(THREAD* thread);
void KiSchedulerMarkThreadWaiting(THREAD* thread);
void KiSchedulerWakeThread(THREAD* thread, KSTATUS status);
// Blocks the current thread until at least the requested delay has elapsed.
__declspec(dllexport) KSTATUS KeDelayThread(uint64_t milliseconds);
KSTATUS KeArmCurrentThreadTimeout(uint64_t milliseconds, KSTATUS timeoutStatus);
// 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.
THREAD* KeGetCurrentThread(void);
// Set the current thread for the current CPU. Used during CPU/scheduler bring-up.
void KeSetCurrentThread(THREAD* thread);