⚠️ VeridianOS Kernel Documentation - This is low-level kernel code. All functions are unsafe unless explicitly marked otherwise. no_std

veridian_kernel/sched/
mod.rs

1//! Process and thread scheduling module
2//!
3//! Implements a multi-level scheduler with support for:
4//! - Multiple scheduling algorithms (round-robin, priority, CFS)
5//! - Real-time scheduling classes
6//! - SMP load balancing
7//! - CPU affinity
8//! - Context switching for x86_64, AArch64, and RISC-V
9//!
10//! This module is a facade that re-exports the public API from submodules:
11//! - [`scheduler`] - Core scheduler algorithm and state
12//! - [`task`] - Task control block and priority types
13//! - [`metrics`] - Performance metrics and measurement
14//! - [`smp`] - Symmetric multiprocessing support
15//! - [`queue`] - Ready queue management
16//! - [`numa`] - NUMA-aware scheduling
17//! - [`init`] - Initialization and timer setup
18//! - [`runtime`] - Scheduler execution loop and idle task
19//! - [`process_compat`] - Process compatibility wrapper types
20//! - [`ipc_blocking`] - IPC blocking/waking and wait queues
21//! - [`task_management`] - Task creation, exit, and thread scheduling
22//! - [`load_balance`] - Load balancing and task migration
23
24#![allow(dead_code, function_casts_as_integer)]
25
26// ---- Submodule declarations ----
27
28pub mod deadline;
29pub mod init;
30pub mod ipc_blocking;
31pub mod load_balance;
32pub mod metrics;
33pub mod numa;
34pub mod percpu_queue;
35pub mod process_compat;
36pub mod queue;
37pub mod runtime;
38pub mod scheduler;
39pub mod smp;
40pub mod task;
41pub mod task_management;
42pub mod task_ptr;
43
44#[cfg(target_arch = "riscv64")]
45pub mod riscv_scheduler;
46
47// ---- Re-exports: scheduler types ----
48
49#[cfg(not(target_arch = "riscv64"))]
50pub(crate) use queue::READY_QUEUE;
51#[cfg(target_arch = "riscv64")]
52pub use scheduler::SchedAlgorithm;
53#[cfg(not(target_arch = "riscv64"))]
54pub use scheduler::SchedAlgorithm;
55#[cfg(not(target_arch = "riscv64"))]
56pub(crate) use scheduler::SCHEDULER;
57
58#[cfg(target_arch = "riscv64")]
59pub(crate) static SCHEDULER: riscv_scheduler::RiscvScheduler =
60    riscv_scheduler::RiscvScheduler::new();
61
62// ---- Re-exports: initialization ----
63pub use init::{init, init_with_bootstrap};
64// ---- Re-exports: IPC blocking/waking ----
65pub use ipc_blocking::{
66    block_on_ipc, block_process, wake_up_endpoint_waiters, wake_up_process, yield_cpu,
67};
68// ---- Re-exports: load balancing ----
69#[cfg(feature = "alloc")]
70pub use load_balance::{balance_load, cleanup_dead_tasks};
71// ---- Re-exports: process compatibility ----
72pub use process_compat::{
73    alloc_pid, current_process, find_process, switch_to_process, TaskProcessAdapter,
74};
75/// Type alias for backward compatibility.
76pub type Process = TaskProcessAdapter;
77// ---- Re-exports: runtime ----
78pub use runtime::{has_ready_tasks, idle_task_entry, run, set_algorithm, start, timer_tick};
79pub use task::{Priority, SchedClass, SchedPolicy, Task};
80pub use task_management::exit_task;
81// ---- Re-exports: task management ----
82#[cfg(feature = "alloc")]
83pub use task_management::{create_task, create_task_from_thread, schedule_thread};
84
85// Export functions needed by tests
86pub use self::scheduler::should_preempt;
87// ---- Remaining items that stay in mod.rs ----
88
89// Import ProcessState from process module (used by submodules via super::)
90pub(crate) use crate::process::ProcessState;
91// Use process module types (used by submodules via super::)
92pub(crate) use crate::process::{ProcessId, ThreadId};
93
94/// Get the current thread ID from the running task.
95pub fn get_current_thread_id() -> u64 {
96    let sched = scheduler::SCHEDULER.lock();
97    if let Some(current) = sched.current() {
98        // SAFETY: `current` is a valid NonNull<Task> from the scheduler.
99        // We hold the scheduler lock, so the task won't be modified.
100        unsafe { current.as_ref().tid.0 }
101    } else {
102        1 // Fallback: boot thread
103    }
104}
105
106/// Get the PID of the currently running task.
107pub fn current_process_id() -> ProcessId {
108    let sched = scheduler::SCHEDULER.lock();
109    if let Some(current) = sched.current() {
110        // SAFETY: Same as get_current_thread_id.
111        unsafe { current.as_ref().pid }
112    } else {
113        ProcessId(1) // Fallback: init
114    }
115}
116
117/// Set current task (for testing)
118///
119/// # Safety
120/// The caller must ensure that the task pointer is valid and properly
121/// initialized
122pub unsafe fn set_current_task(task: *mut Task) {
123    // This is a test helper function
124    let scheduler = scheduler::current_scheduler();
125    let mut sched = scheduler.lock();
126    if !task.is_null() {
127        // SAFETY: Caller guarantees `task` is a valid, non-null pointer to a
128        // properly initialized Task. `NonNull::new_unchecked` is safe here
129        // because we just checked `!task.is_null()`.
130        sched.current = Some(task_ptr::TaskPtr::new(core::ptr::NonNull::new_unchecked(
131            task,
132        )));
133    } else {
134        sched.current = None;
135    }
136}