Refactor
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
//!
|
||||
//! Scheduler and idle loop utilities.
|
||||
//!
|
||||
//! This module exposes the global process table, the scheduler initialization
|
||||
//! and a simple round-robin scheduler used by the kernel.
|
||||
use core::{arch::riscv64::wfi, array, cell::LazyCell, time::Duration};
|
||||
|
||||
use alloc::string::String;
|
||||
@@ -8,9 +13,17 @@ use crate::{
|
||||
time,
|
||||
};
|
||||
|
||||
/// Maximum number of simultaneous processes supported by the kernel.
|
||||
pub const PROCESS_COUNT: usize = 16;
|
||||
|
||||
/// Currently active PID.
|
||||
///
|
||||
/// Updated by the scheduler when switching contexts.
|
||||
pub static mut ACTIVE_PID: usize = 0;
|
||||
/// Global process table stored in a lazily-initialized container.
|
||||
///
|
||||
/// Each entry represents a process slot which may be `Dead`, `Activable`,
|
||||
/// `Active` or `Asleep`.
|
||||
pub static mut PROCESS_TABLE: LazyCell<[Process; PROCESS_COUNT]> = LazyCell::new(|| {
|
||||
array::from_fn(|_| Process {
|
||||
pid: -1,
|
||||
@@ -33,6 +46,9 @@ pub static mut PROCESS_TABLE: LazyCell<[Process; PROCESS_COUNT]> = LazyCell::new
|
||||
})
|
||||
});
|
||||
|
||||
/// Idle loop executed when there is no runnable process.
|
||||
///
|
||||
/// Uses the `wfi` instruction to yield the CPU while waiting for interrupts.
|
||||
pub fn idle() {
|
||||
loop {
|
||||
// write_string_temp("idle");
|
||||
@@ -43,6 +59,10 @@ pub fn idle() {
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize the scheduler and create the idle process.
|
||||
///
|
||||
/// Marks all process slots as `Dead` then creates the idle process and sets
|
||||
/// it as the active process.
|
||||
pub fn scheduler_init() {
|
||||
info!("scheduler init");
|
||||
for pid in 0..PROCESS_COUNT {
|
||||
@@ -57,6 +77,12 @@ pub fn scheduler_init() {
|
||||
}
|
||||
}
|
||||
|
||||
/// Round-robin scheduler used to select the next runnable process.
|
||||
///
|
||||
/// Saves the provided interrupt context into the previous process slot and
|
||||
/// updates `ACTIVE_PID` to point to the chosen process. This function does
|
||||
/// not return but instead updates `interrupt_state` to the context of the
|
||||
/// next process to run.
|
||||
pub fn scheduler_without_ret(interrupt_state: &mut *mut ExecutionContext) {
|
||||
// info!("scheduler");
|
||||
unsafe {
|
||||
|
||||
Reference in New Issue
Block a user