forked from koniifer/ableos
Feature| afetch update, scheduler rework
This commit is contained in:
parent
c18035feb4
commit
8e66a677fa
2
ableos/Cargo.lock
generated
2
ableos/Cargo.lock
generated
|
@ -802,7 +802,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "versioning"
|
name = "versioning"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
source = "git+https://git.ablecorp.us/able/versioning#ef472283e6e7a2e395ee56434087b3a6fad53ff2"
|
source = "git+https://git.ablecorp.us/able/versioning#b86e53ab8461ee4f28807bf2254d543f6d8f4727"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vga"
|
name = "vga"
|
||||||
|
|
|
@ -41,6 +41,8 @@ test-args = [
|
||||||
"stdio",
|
"stdio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
linked_list_allocator = "0.9.0"
|
linked_list_allocator = "0.9.0"
|
||||||
lliw = "0.2.0"
|
lliw = "0.2.0"
|
||||||
|
|
|
@ -70,3 +70,7 @@ pub fn shutdown() {}
|
||||||
|
|
||||||
use crate::print;
|
use crate::print;
|
||||||
use crate::println;
|
use crate::println;
|
||||||
|
|
||||||
|
pub fn generate_process_pass() -> u128 {
|
||||||
|
123
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
// #![allow(clippy::print_literal)]
|
// #![allow(clippy::print_literal)]
|
||||||
use crate::{logger, scheduler::SCHEDULER, serial_println};
|
use crate::{
|
||||||
|
logger,
|
||||||
|
scheduler::{capabilities::Capabilities, SCHEDULER},
|
||||||
|
serial_println,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{gdt, interrupts};
|
use super::{gdt, interrupts};
|
||||||
|
|
||||||
|
@ -20,10 +24,17 @@ pub fn init() {
|
||||||
}
|
}
|
||||||
gdt::init();
|
gdt::init();
|
||||||
|
|
||||||
use crate::scheduler::Priority::High;
|
use crate::scheduler::priority::Priority::High;
|
||||||
|
use crate::stdio::StdIO;
|
||||||
let mut scheduler = SCHEDULER.lock();
|
let mut scheduler = SCHEDULER.lock();
|
||||||
let process_0 = scheduler.new_process(High);
|
let process_0 = scheduler.new_process(
|
||||||
|
Capabilities::empty(),
|
||||||
|
High,
|
||||||
|
"".to_string(),
|
||||||
|
StdIO::new(crate::stdio::Device::VTerm),
|
||||||
|
);
|
||||||
scheduler.add_process(process_0);
|
scheduler.add_process(process_0);
|
||||||
|
|
||||||
drop(scheduler);
|
drop(scheduler);
|
||||||
|
|
||||||
interrupts::init_idt();
|
interrupts::init_idt();
|
||||||
|
|
|
@ -47,3 +47,13 @@ pub fn sloop() -> ! {
|
||||||
hlt();
|
hlt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Split up into the randomness and the password generation
|
||||||
|
pub fn generate_process_pass() -> u128 {
|
||||||
|
// TODO: Move this into entropy_pool module
|
||||||
|
use rdrand::RdRand;
|
||||||
|
let gen = RdRand::new().unwrap();
|
||||||
|
|
||||||
|
let ret = (gen.try_next_u64().unwrap() as u128) << 64 | (gen.try_next_u64().unwrap() as u128);
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,35 @@
|
||||||
pub trait Serial {
|
use kernel::device_interface::character::CharacterDevice;
|
||||||
fn print();
|
|
||||||
fn recieve();
|
pub struct Serial {
|
||||||
|
pub base: usize,
|
||||||
|
}
|
||||||
|
impl CharacterDevice for Serial {
|
||||||
|
fn can_read(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn can_write(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_char(&mut self) -> Option<char> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_char(&mut self, c: char) -> bool {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reset(&mut self) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn initialize(&mut self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn new_serial_test() {
|
||||||
|
let mut serial = Serial { base: 0x3F8 };
|
||||||
|
serial.initialize();
|
||||||
|
serial.write_char('a');
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ pub mod absi;
|
||||||
pub mod clip;
|
pub mod clip;
|
||||||
pub mod futex;
|
pub mod futex;
|
||||||
// pub mod info;
|
// pub mod info;
|
||||||
|
pub mod info;
|
||||||
pub mod kinfo;
|
pub mod kinfo;
|
||||||
pub mod mail;
|
pub mod mail;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
|
|
|
@ -30,13 +30,10 @@ pub fn kernel_main() -> ! {
|
||||||
log::set_max_level(log::LevelFilter::Off);
|
log::set_max_level(log::LevelFilter::Off);
|
||||||
}
|
}
|
||||||
let mut scheduler = SCHEDULER.lock();
|
let mut scheduler = SCHEDULER.lock();
|
||||||
use crate::scheduler::Priority::*;
|
for proc in &scheduler.execution_queue {
|
||||||
let mut process_1 = scheduler.new_process(High);
|
trace!("{:?}", proc);
|
||||||
process_1.capabilities.files = FileAccess::Some(vec![]);
|
|
||||||
scheduler.add_process(process_1);
|
|
||||||
for ref_process in &scheduler.list {
|
|
||||||
trace!("{:?}", ref_process);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
drop(scheduler);
|
drop(scheduler);
|
||||||
|
|
||||||
// start_facepalm();
|
// start_facepalm();
|
||||||
|
@ -54,29 +51,18 @@ pub fn cpu_socket_startup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn log_version_data() {
|
pub fn log_version_data() {
|
||||||
info!("{} v{:?}", RELEASE_TYPE, KERNEL_VERSION);
|
info!("{} v{}", RELEASE_TYPE, KERNEL_VERSION);
|
||||||
info!(
|
info!(
|
||||||
"Brand String: ",
|
"Brand String: {}",
|
||||||
// master().unwrap().brand_string().unwrap()
|
master().unwrap().brand_string().unwrap()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Split up into the randomness and the password generation
|
use crate::info::master;
|
||||||
pub fn generate_process_pass() -> u128 {
|
|
||||||
// TODO: Move this into entropy_pool module
|
|
||||||
// use rdrand::RdRand;
|
|
||||||
// let gen = RdRand::new().unwrap();
|
|
||||||
|
|
||||||
// TODO: Split off into process module
|
|
||||||
// let ret = (gen.try_next_u64().unwrap() as u128) << 64 | (gen.try_next_u64().unwrap() as u128);
|
|
||||||
// ret
|
|
||||||
123
|
|
||||||
}
|
|
||||||
|
|
||||||
use kernel::KERNEL_VERSION;
|
use kernel::KERNEL_VERSION;
|
||||||
|
|
||||||
|
use crate::scheduler::SCHEDULER;
|
||||||
use crate::{
|
use crate::{
|
||||||
boot_conf::KernelConfig,
|
boot_conf::KernelConfig, scheduler::capabilities::FileAccess, systeminfo::RELEASE_TYPE,
|
||||||
scheduler::{capabilities::FileAccess, SCHEDULER},
|
|
||||||
systeminfo::RELEASE_TYPE,
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -110,3 +110,5 @@ pub mod prelude;
|
||||||
|
|
||||||
#[prelude_import]
|
#[prelude_import]
|
||||||
pub use prelude::rust_2021::*;
|
pub use prelude::rust_2021::*;
|
||||||
|
|
||||||
|
pub mod stdio;
|
||||||
|
|
11
ableos/src/rhai_shell/balloon.txt
Normal file
11
ableos/src/rhai_shell/balloon.txt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
,-""""-. OS: AbleOS
|
||||||
|
,' _ `. Host: {}
|
||||||
|
/ )_) \ Kernel: AKern-{}-v{}
|
||||||
|
: : Uptime: {}
|
||||||
|
\ / Packages: None
|
||||||
|
\ / Shell: RhaiShell
|
||||||
|
`. ,' Resolution: 640x480
|
||||||
|
`. ,' Terminal: VGABuffer
|
||||||
|
`.,' CPU: {}
|
||||||
|
/\`. ,-._ GPU: VGA Compatible
|
||||||
|
`-' Memory: {}/{}
|
|
@ -35,9 +35,12 @@ lazy_static::lazy_static!(
|
||||||
);
|
);
|
||||||
|
|
||||||
use rhai::Engine;
|
use rhai::Engine;
|
||||||
|
use x86_64::instructions::interrupts::{disable, enable};
|
||||||
|
|
||||||
|
use crate::info::master;
|
||||||
use crate::time::fetch_time;
|
use crate::time::fetch_time;
|
||||||
use crate::wasm_jumploader::interp;
|
use crate::wasm_jumploader::interp;
|
||||||
|
use crate::{allocator, ALLOCATOR};
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::{shutdown, sloop},
|
arch::{shutdown, sloop},
|
||||||
systeminfo::{KERNEL_VERSION, RELEASE_TYPE},
|
systeminfo::{KERNEL_VERSION, RELEASE_TYPE},
|
||||||
|
@ -49,14 +52,24 @@ pub fn afetch() {
|
||||||
|
|
||||||
let tick_time = fetch_time();
|
let tick_time = fetch_time();
|
||||||
|
|
||||||
println!(
|
disable();
|
||||||
"OS: AbleOS
|
let allocator = ALLOCATOR.lock();
|
||||||
Host: {}
|
let size = allocator.size();
|
||||||
Kernel: AKern-{}-v{}
|
let used = allocator.used();
|
||||||
Uptime: {}",
|
enable();
|
||||||
kstate.hostname, RELEASE_TYPE, KERNEL_VERSION, tick_time
|
|
||||||
);
|
|
||||||
|
|
||||||
|
// let mem = format!("{}/{}", used, size);
|
||||||
|
println!(
|
||||||
|
include_str!("balloon.txt"),
|
||||||
|
kstate.hostname,
|
||||||
|
RELEASE_TYPE,
|
||||||
|
KERNEL_VERSION,
|
||||||
|
tick_time,
|
||||||
|
master().unwrap().brand_string().unwrap(),
|
||||||
|
// mem
|
||||||
|
used,
|
||||||
|
size
|
||||||
|
);
|
||||||
drop(kstate);
|
drop(kstate);
|
||||||
}
|
}
|
||||||
pub fn set_hostname(name: String) {
|
pub fn set_hostname(name: String) {
|
||||||
|
|
|
@ -1,197 +1,96 @@
|
||||||
// #![warn(missing_docs)]
|
use crate::{arch::generate_process_pass, stdio::StdIO};
|
||||||
|
|
||||||
//! The standard ableOS scheduler named
|
use crate::scheduler::capabilities::Capabilities;
|
||||||
//!
|
|
||||||
//! # Notes
|
|
||||||
//! The scheduler is also responsible for choosing the priority of a process.
|
|
||||||
//! The scheduler is responsible for choosing which process to execute next.
|
|
||||||
|
|
||||||
|
use kernel::proccess::PID;
|
||||||
pub mod capabilities;
|
pub mod capabilities;
|
||||||
|
pub mod priority;
|
||||||
pub mod proc;
|
pub mod proc;
|
||||||
|
use priority::Priority;
|
||||||
mod new_sched;
|
use proc::Process;
|
||||||
use proc::{Process, PID};
|
/// Add additional wake conditions to the list
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
#[cfg(test)]
|
pub enum WakeCondition {
|
||||||
mod tests;
|
/// Wake when the process has been blocked for a certain amount of time
|
||||||
|
TimerInterrupt(u64),
|
||||||
use crate::kmain::generate_process_pass;
|
SocketRead(PID),
|
||||||
|
SocketWrite(PID),
|
||||||
use self::capabilities::Capabilities;
|
SocketOpen(PID),
|
||||||
|
SocketClose(PID),
|
||||||
lazy_static::lazy_static!(
|
// HardwareEvent,
|
||||||
/// The standard implementation for ableOS
|
|
||||||
pub static ref SCHEDULER: spin::Mutex<Scheduler> = spin::Mutex::new(Scheduler::new());
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Scheduler priority model
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
|
||||||
pub enum Priority {
|
|
||||||
/// Exclusively Kernel space | 20 Timer Tick execution time
|
|
||||||
High,
|
|
||||||
/// Kernel / User space | 15 Timer Tick execution time
|
|
||||||
Medium,
|
|
||||||
/// low priority userspace code | 10 Timer Tick execution time
|
|
||||||
Low,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: Define what is a sleeping process in the context of the ableOS kernel.
|
||||||
|
// Blocked processes are processes that are waiting for a certain event to occur.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum FileAccessTypes {
|
pub struct BlockedProcess {
|
||||||
All,
|
pub pid: PID,
|
||||||
Some(Vec<u8>),
|
pub wake_condition: WakeCondition,
|
||||||
None,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This structure handles the process scheduling and execution
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
/// ```
|
|
||||||
/// use crate::scheduler::Priority;
|
|
||||||
/// use crate::scheduler::Scheduler;
|
|
||||||
///
|
|
||||||
/// let mut scheduler = Scheduler::new();
|
|
||||||
///
|
|
||||||
/// let pid = scheduler.new_process(Priority::High);
|
|
||||||
/// scheduler.run_process(pid);
|
|
||||||
/// ```
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct Scheduler {
|
pub struct Scheduler {
|
||||||
/// The highest free process ID
|
|
||||||
pub free_pid: PID,
|
pub free_pid: PID,
|
||||||
/// The execution time of the current process in ticks
|
|
||||||
pub process_exec_time: u64,
|
pub process_exec_time: u64,
|
||||||
/// The list of processes
|
pub execution_queue: Vec<Process>,
|
||||||
pub list: Vec<Process>,
|
pub sleeping_queue: Vec<BlockedProcess>,
|
||||||
|
pub blocked_queue: Vec<BlockedProcess>,
|
||||||
|
// / All timed processes sorted by wake time
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scheduler {
|
impl Scheduler {
|
||||||
/// Create a new scheduler
|
/// Create a new scheduler
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
/// ```
|
|
||||||
/// use ableos::scheduler::Priority;
|
|
||||||
/// let mut scheduler = Scheduler::new();
|
|
||||||
/// ```
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
free_pid: PID(0),
|
free_pid: 0,
|
||||||
process_exec_time: 0,
|
process_exec_time: 0,
|
||||||
list: Vec::new(),
|
execution_queue: Vec::new(),
|
||||||
|
sleeping_queue: Vec::new(),
|
||||||
|
blocked_queue: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change the current process to the next process in the list
|
/// Change the current process to the next process in the list
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// let mut scheduler = scheduler();
|
|
||||||
/// let mut process = scheduler.next_process();
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics if there are no processes in the list
|
|
||||||
pub fn next_process(&mut self) {
|
pub fn next_process(&mut self) {
|
||||||
self.process_exec_time = 0;
|
self.process_exec_time = 0;
|
||||||
let previous_task = self.list[0].clone();
|
let previous_task = self.execution_queue[0].clone();
|
||||||
self.list.remove(0);
|
self.execution_queue.remove(0);
|
||||||
self.list.push(previous_task);
|
self.execution_queue.push(previous_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new process
|
pub fn add_process(&mut self, mut process: Process) {
|
||||||
///
|
process.pid = self.free_pid;
|
||||||
/// # Arguments
|
self.free_pid += 1;
|
||||||
///
|
self.execution_queue.push(process);
|
||||||
/// * `priority` - The priority of the process
|
}
|
||||||
///
|
|
||||||
/// # Example
|
pub fn new_process(
|
||||||
///
|
&mut self,
|
||||||
/// ```
|
capabilities: Capabilities,
|
||||||
/// let mut scheduler = scheduler();
|
priority: Priority,
|
||||||
/// let mut process = scheduler.new_process(Priority::Medium);
|
working_dir: String,
|
||||||
/// ```
|
stdio: StdIO,
|
||||||
pub fn new_process(&mut self, priority: Priority) -> Process {
|
) -> Process {
|
||||||
let process = Process {
|
let mut process = Process {
|
||||||
id: self.free_pid.clone(),
|
pid: 0,
|
||||||
password: generate_process_pass(),
|
|
||||||
capabilities: Capabilities::empty(),
|
|
||||||
priority,
|
priority,
|
||||||
working_dir: "todo!()".to_string(),
|
working_dir,
|
||||||
|
stdio,
|
||||||
|
password: generate_process_pass(),
|
||||||
|
capabilities,
|
||||||
};
|
};
|
||||||
// self.free_pid.0 += 1;
|
|
||||||
// self.list.push(process);
|
|
||||||
process
|
process
|
||||||
}
|
}
|
||||||
/// Add a created process to the scheduler
|
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `process` - The process to add
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// let mut scheduler = Scheduler::new();
|
|
||||||
/// let mut process = scheduler.new_process(Priority::Medium);
|
|
||||||
/// scheduler.add_process(process);
|
|
||||||
/// ```
|
|
||||||
pub fn add_process(&mut self, process: Process) {
|
|
||||||
self.list.push(process);
|
|
||||||
|
|
||||||
self.free_pid.0 += 1;
|
pub fn sleep_process(&mut self, process: &mut Process) {
|
||||||
}
|
let sleeping_process = BlockedProcess {
|
||||||
/// Terminate the process with the matching PID
|
pid: process.pid,
|
||||||
///
|
wake_condition: WakeCondition::TimerInterrupt(0),
|
||||||
/// # Arguments
|
};
|
||||||
///
|
|
||||||
/// * `pid` - The PID of the process to terminate
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// let mut scheduler = scheduler();
|
|
||||||
/// let mut process = scheduler.new_process(Priority::Medium);
|
|
||||||
/// scheduler.terminate_process(process.id);
|
|
||||||
/// ```
|
|
||||||
pub fn term_process(&mut self, pid: PID) {
|
|
||||||
let mut process_index = 0;
|
|
||||||
for x in &self.list {
|
|
||||||
if x.id == pid {
|
|
||||||
self.list.remove(process_index);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
process_index += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// Bump the current process' execution time
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// let mut scheduler = scheduler();
|
|
||||||
/// let mut process = scheduler.new_process(Priority::Medium);
|
|
||||||
/// scheduler.bump_exec();
|
|
||||||
/// ```
|
|
||||||
pub fn bump_exec(&mut self) {
|
|
||||||
self.process_exec_time += 1;
|
|
||||||
|
|
||||||
use Priority::*;
|
self.sleeping_queue.push(sleeping_process.clone());
|
||||||
if self.list.len() > 0 {
|
self.execution_queue.remove(0);
|
||||||
match (self.process_exec_time, self.list[0].priority) {
|
|
||||||
(20, High) => {
|
|
||||||
self.next_process();
|
|
||||||
}
|
|
||||||
(15, Medium) => {
|
|
||||||
self.next_process();
|
|
||||||
}
|
|
||||||
(10, Low) => {
|
|
||||||
self.next_process();
|
|
||||||
}
|
|
||||||
|
|
||||||
(_, _) => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lazy_static::lazy_static! {
|
||||||
|
pub static ref SCHEDULER: spin::Mutex<Scheduler> = spin::Mutex::new(Scheduler::new());
|
||||||
|
}
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
use crate::{
|
|
||||||
kmain::generate_process_pass,
|
|
||||||
scheduler::capabilities::Capabilities,
|
|
||||||
scheduler::proc::{Process, PID},
|
|
||||||
scheduler::Priority,
|
|
||||||
};
|
|
||||||
/// Add additional wake conditions to the list
|
|
||||||
pub enum WakeCondition {
|
|
||||||
/// Wake when the process has been blocked for a certain amount of time
|
|
||||||
TimerInterrupt(u64),
|
|
||||||
SocketRead(PID),
|
|
||||||
SocketWrite(PID),
|
|
||||||
SocketOpen(PID),
|
|
||||||
SocketClose(PID),
|
|
||||||
// HardwareEvent,
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: Define what is a sleeping process in the context of the ableOS kernel.
|
|
||||||
// Blocked processes are processes that are waiting for a certain event to occur.
|
|
||||||
pub struct BlockedProcess {
|
|
||||||
pub pid: PID,
|
|
||||||
pub wake_time: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Scheduler {
|
|
||||||
pub free_pid: PID,
|
|
||||||
pub process_exec_time: u64,
|
|
||||||
pub execution_queue: Vec<Process>,
|
|
||||||
pub sleeping_queue: Vec<Process>,
|
|
||||||
// pub blocked_queue: Vec<BlockedProcess>,
|
|
||||||
// / All timed processes sorted by wake time
|
|
||||||
// pub timed_blocked_queue: Vec<BlockedProcess>,
|
|
||||||
}
|
|
||||||
impl Scheduler {
|
|
||||||
/// Create a new scheduler
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
free_pid: PID(0),
|
|
||||||
process_exec_time: 0,
|
|
||||||
execution_queue: Vec::new(),
|
|
||||||
sleeping_queue: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Change the current process to the next process in the list
|
|
||||||
pub fn next_process(&mut self) {
|
|
||||||
self.process_exec_time = 0;
|
|
||||||
let previous_task = self.execution_queue[0].clone();
|
|
||||||
self.execution_queue.remove(0);
|
|
||||||
self.execution_queue.push(previous_task);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new process
|
|
||||||
/// # Arguments
|
|
||||||
/// * `priority` - The priority of the process
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// let mut scheduler = scheduler();
|
|
||||||
/// let mut process = scheduler.new_process(Priority::Medium);
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// TODO: Add a priority queue
|
|
||||||
/// TODO: Add a process queue
|
|
||||||
pub fn new_process(&mut self, priority: Priority) -> Process {
|
|
||||||
let process = Process {
|
|
||||||
id: self.free_pid,
|
|
||||||
password: generate_process_pass(),
|
|
||||||
priority,
|
|
||||||
capabilities: Capabilities::empty(),
|
|
||||||
working_dir: "todo!()".to_string(),
|
|
||||||
};
|
|
||||||
self.free_pid.0 += 1;
|
|
||||||
process
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn sleep_process(&mut self, process: &mut Process) {
|
|
||||||
let sleeping_process = BlockedProcess {
|
|
||||||
pid: process.id,
|
|
||||||
wake_time: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
self.sleeping_queue.push(process.clone());
|
|
||||||
self.execution_queue.remove(0);
|
|
||||||
}
|
|
||||||
}
|
|
10
ableos/src/scheduler/priority.rs
Normal file
10
ableos/src/scheduler/priority.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
/// Scheduler priority model
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub enum Priority {
|
||||||
|
/// Exclusively Kernel space | 20 Timer Tick execution time
|
||||||
|
High,
|
||||||
|
/// Kernel / User space | 15 Timer Tick execution time
|
||||||
|
Medium,
|
||||||
|
/// low priority userspace code | 10 Timer Tick execution time
|
||||||
|
Low,
|
||||||
|
}
|
|
@ -1,17 +1,15 @@
|
||||||
//! Process definition and general utilities surrounding them
|
//! Process definition and general utilities surrounding them
|
||||||
|
|
||||||
use super::{capabilities::Capabilities, Priority};
|
use super::capabilities::Capabilities;
|
||||||
|
use super::priority::Priority;
|
||||||
/// Process Identification
|
use crate::stdio::StdIO;
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
use kernel::proccess::PID;
|
||||||
#[repr(C)]
|
|
||||||
pub struct PID(pub usize);
|
|
||||||
|
|
||||||
/// A process
|
/// A process
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Process {
|
pub struct Process {
|
||||||
/// Internal PID
|
/// Internal PID
|
||||||
pub id: PID,
|
pub pid: PID,
|
||||||
|
|
||||||
/// Process password
|
/// Process password
|
||||||
pub password: u128,
|
pub password: u128,
|
||||||
|
@ -20,8 +18,9 @@ pub struct Process {
|
||||||
/// A process's priority
|
/// A process's priority
|
||||||
pub priority: Priority,
|
pub priority: Priority,
|
||||||
|
|
||||||
///
|
/// A process's current working directory
|
||||||
pub working_dir: String,
|
pub working_dir: String,
|
||||||
|
pub stdio: StdIO,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Process {}
|
impl Process {}
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
use super::*;
|
|
||||||
|
|
||||||
use crate::scheduler::{
|
|
||||||
capabilities::{ControllerAccess, FileAccess, KeyboardAccess, MouseAccess, SoundCardAccess},
|
|
||||||
proc::PID,
|
|
||||||
Priority::*,
|
|
||||||
Scheduler,
|
|
||||||
};
|
|
||||||
|
|
||||||
// #[test]
|
|
||||||
fn test_new_process() {
|
|
||||||
let mut scheduler = Scheduler::new();
|
|
||||||
scheduler.new_process(High);
|
|
||||||
assert_eq!(scheduler.list.len(), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// #[test]
|
|
||||||
fn test_next_process() {
|
|
||||||
let mut scheduler = Scheduler::new();
|
|
||||||
scheduler.new_process(High);
|
|
||||||
scheduler.next_process();
|
|
||||||
assert_eq!(scheduler.list.len(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// #[test]
|
|
||||||
fn test_term_process() {
|
|
||||||
let mut scheduler = Scheduler::new();
|
|
||||||
scheduler.new_process(High);
|
|
||||||
scheduler.term_process(PID(1));
|
|
||||||
assert_eq!(scheduler.list.len(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// #[test]
|
|
||||||
fn test_bump_exec() {
|
|
||||||
let mut scheduler = Scheduler::new();
|
|
||||||
scheduler.new_process(High);
|
|
||||||
scheduler.bump_exec();
|
|
||||||
assert_eq!(scheduler.process_exec_time, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// #[test]
|
|
||||||
fn test_capabilities() {
|
|
||||||
let caps = Capabilities::empty();
|
|
||||||
assert_eq!(caps.files, FileAccess::None);
|
|
||||||
assert_eq!(caps.mouse, MouseAccess::No);
|
|
||||||
assert_eq!(caps.keyboard, KeyboardAccess::No);
|
|
||||||
assert_eq!(caps.controllers, ControllerAccess::None);
|
|
||||||
assert_eq!(caps.sound_cards, SoundCardAccess::None);
|
|
||||||
}
|
|
|
@ -2,13 +2,17 @@ use acpi::AcpiTables;
|
||||||
|
|
||||||
use crate::rhai_shell::shell;
|
use crate::rhai_shell::shell;
|
||||||
|
|
||||||
|
use crate::stdio::StdIO;
|
||||||
/// Experimental scratchpad for testing.
|
/// Experimental scratchpad for testing.
|
||||||
pub fn scratchpad() {
|
pub fn scratchpad() {
|
||||||
// pci_fun();
|
let mut stdio = StdIO::new(crate::stdio::Device::Serial);
|
||||||
|
stdio.write();
|
||||||
|
|
||||||
shell();
|
shell();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use core::fmt::Write;
|
||||||
|
|
||||||
pub fn pci_fun() {}
|
pub fn pci_fun() {}
|
||||||
|
|
||||||
pub fn acpi() {
|
pub fn acpi() {
|
||||||
|
|
34
ableos/src/stdio.rs
Normal file
34
ableos/src/stdio.rs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
use core::fmt::Arguments;
|
||||||
|
use core::fmt::Error;
|
||||||
|
use core::fmt::Write;
|
||||||
|
|
||||||
|
use crate::kprintln;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum Device {
|
||||||
|
VTerm,
|
||||||
|
Serial,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct StdIO {
|
||||||
|
device: Device,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StdIO {
|
||||||
|
pub fn new(device: Device) -> StdIO {
|
||||||
|
StdIO { device }
|
||||||
|
}
|
||||||
|
pub fn write(&mut self) {
|
||||||
|
match self.device {
|
||||||
|
Device::VTerm => {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
||||||
|
Device::Serial => {
|
||||||
|
serial_println!("Hello, world!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn read(&mut self) {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
22
kernel/Cargo.lock
generated
22
kernel/Cargo.lock
generated
|
@ -1,22 +0,0 @@
|
||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "kernel"
|
|
||||||
version = "0.1.2"
|
|
||||||
dependencies = [
|
|
||||||
"lazy_static",
|
|
||||||
"versioning",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lazy_static"
|
|
||||||
version = "1.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "versioning"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "git+https://git.ablecorp.us/able/versioning#ef472283e6e7a2e395ee56434087b3a6fad53ff2"
|
|
|
@ -8,6 +8,7 @@ pub mod device_interface;
|
||||||
pub mod messaging;
|
pub mod messaging;
|
||||||
pub mod panic;
|
pub mod panic;
|
||||||
pub mod proccess;
|
pub mod proccess;
|
||||||
|
pub mod syscalls;
|
||||||
pub mod time;
|
pub mod time;
|
||||||
|
|
||||||
use core::sync::atomic::{AtomicU64, Ordering::Relaxed};
|
use core::sync::atomic::{AtomicU64, Ordering::Relaxed};
|
||||||
|
|
|
@ -2,3 +2,12 @@
|
||||||
|
|
||||||
/// A process ID
|
/// A process ID
|
||||||
pub type PID = u64;
|
pub type PID = u64;
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
/// Signals that can be sent to a process
|
||||||
|
pub enum Signals {
|
||||||
|
/// Terminate the process
|
||||||
|
Terminate,
|
||||||
|
/// Shutdown the process and allow it to shutdown cleanly
|
||||||
|
Quit,
|
||||||
|
}
|
||||||
|
|
24
kernel/src/syscalls.rs
Normal file
24
kernel/src/syscalls.rs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
//!
|
||||||
|
|
||||||
|
use crate::proccess::{Signals, PID};
|
||||||
|
/// All possible system calls
|
||||||
|
pub enum Syscall {
|
||||||
|
/// Create a new process and return its PID
|
||||||
|
CreateProcess,
|
||||||
|
/// Send a signal to a process
|
||||||
|
SendSignal(PID, Signals),
|
||||||
|
|
||||||
|
/// Get the current process ID
|
||||||
|
GetPID,
|
||||||
|
/// Get the current time
|
||||||
|
GetTime,
|
||||||
|
/// Set the time
|
||||||
|
SetTime,
|
||||||
|
/*
|
||||||
|
ListInodes,
|
||||||
|
CreateInode,
|
||||||
|
RemoveInode,
|
||||||
|
OpenInode,
|
||||||
|
CloseInode,
|
||||||
|
*/
|
||||||
|
}
|
Loading…
Reference in a new issue