Scheduler
Design intent, written before the code. What is actually built, and how, is in sched/ and implementation_progress/sched.md.
Goals
- low wake-up latency
- fairness under mixed interactive and background workloads
- multicore scalability
- affinity and topology awareness
- support for real-time and near-real-time classes in later phases
Scheduling model
VibeOS uses a preemptive priority-based scheduler with fair scheduling within priority bands.
Thread classes
- realtime reserved for strict bounded-latency system tasks in later phases
- interactive for UI and latency-sensitive applications
- normal for standard user workloads
- background for maintenance and batch work
Core design
Per-CPU run queues
Each CPU maintains a local run queue to reduce lock contention and cache disruption.
Load balancing
Periodic and event-driven balancing migrates threads across CPUs based on:
- CPU utilization
- thread affinity
- cache locality hints
- NUMA domain awareness in future phases
Priority handling
- dynamic boosts for wake-up responsiveness
- starvation prevention through aging
- priority ceilings for specific kernel-mediated synchronization paths when necessary
Timeslice policy
- interactive threads receive shorter slices with stronger latency preference
- throughput-oriented threads receive longer slices
- kernel workers should avoid monopolizing CPU time by default
Multicore strategy
- minimal global scheduler state
- per-CPU timer events where possible
- explicit handling for idle CPUs and wake-up targets
- future support for heterogeneous core topologies
Roadmap
Early implementation
- fixed priority bands
- round-robin within queues
- basic SMP balancing
Mid-stage evolution
- fair scheduling weights
- better I/O wake heuristics
- CPU topology awareness
Advanced stage
- real-time scheduling class
- deadline scheduling for selected workloads
- energy-aware placement for mobile-class platforms
Current runtime prototype status
- class-based default timeslice selection is implemented (
background=8,normal=4,interactive=2,realtime=1). - enqueue paths normalize zero-timeslice threads to class defaults.
- per-CPU and aggregate scheduler counters remain available through runtime telemetry helpers and syscall observability paths.
- runqueue aging helpers are available (
age_cpu,age_all) to apply bounded timeslice boosts and reduce starvation risk. - the x86-64 runtime runs preemptively on four cores, and the boot gate asserts
all four are online rather than assuming it. Two cores ending up on one task
and a lost TLS base both reproduced at roughly one boot in three, which is
why scheduler changes here are checked with
scripts/dev/repeat-boot.shand not with a single green run.