Refactor of scheduler's
This commit is contained in:
parent
84865e8248
commit
ab39b02bb9
|
@ -5,22 +5,22 @@ use super::{gdt, interrupts};
|
||||||
|
|
||||||
/// x86_64 initialization
|
/// x86_64 initialization
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
let result = logger::init();
|
let result = logger::init();
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(err) => error!("{}", err),
|
Err(err) => error!("{}", err),
|
||||||
}
|
}
|
||||||
gdt::init();
|
gdt::init();
|
||||||
|
|
||||||
use crate::scheduler::Priority;
|
use crate::scheduler::Priority;
|
||||||
let mut scheduler = SCHEDULER.lock();
|
let mut scheduler = SCHEDULER.lock();
|
||||||
use Priority::*;
|
use Priority::*;
|
||||||
let process_0 = scheduler.new_process(High);
|
let process_0 = scheduler.new_process(High);
|
||||||
scheduler.add_process(process_0);
|
scheduler.add_process(process_0);
|
||||||
drop(scheduler);
|
drop(scheduler);
|
||||||
|
|
||||||
interrupts::init_idt();
|
interrupts::init_idt();
|
||||||
|
|
||||||
unsafe { interrupts::PICS.lock().initialize() };
|
unsafe { interrupts::PICS.lock().initialize() };
|
||||||
x86_64::instructions::interrupts::enable();
|
x86_64::instructions::interrupts::enable();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,110 +3,110 @@
|
||||||
// use crate::scheduler;
|
// use crate::scheduler;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
arch::{init, sloop},
|
arch::{init, sloop},
|
||||||
boot_conf,
|
boot_conf,
|
||||||
boot_conf::BootConfig,
|
boot_conf::BootConfig,
|
||||||
capabilities::FileAccess,
|
capabilities,
|
||||||
experiments::{
|
experiments::{
|
||||||
info::master,
|
info::master,
|
||||||
systeminfo::{KERNEL_VERSION, RELEASE_TYPE},
|
systeminfo::{KERNEL_VERSION, RELEASE_TYPE},
|
||||||
},
|
},
|
||||||
file::{File, PathRep},
|
file::{File, PathRep},
|
||||||
relib::network::socket::SimpleSock,
|
relib::network::socket::SimpleSock,
|
||||||
relib::network::socket::Socket,
|
relib::network::socket::Socket,
|
||||||
scheduler::SCHEDULER,
|
scheduler::SCHEDULER,
|
||||||
},
|
},
|
||||||
alloc::{
|
alloc::{
|
||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
vec,
|
vec,
|
||||||
},
|
},
|
||||||
core::sync::atomic::{AtomicU64, Ordering::*},
|
core::sync::atomic::{AtomicU64, Ordering::*},
|
||||||
lazy_static::lazy_static,
|
lazy_static::lazy_static,
|
||||||
log::*,
|
log::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref TICK: AtomicU64 = AtomicU64::new(0);
|
pub static ref TICK: AtomicU64 = AtomicU64::new(0);
|
||||||
pub static ref BOOT_CONF: BootConfig = boot_conf::BootConfig::new();
|
pub static ref BOOT_CONF: BootConfig = boot_conf::BootConfig::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The main entry point of the kernel
|
/// The main entry point of the kernel
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn kernel_main() -> ! {
|
pub fn kernel_main() -> ! {
|
||||||
init::init();
|
init::init();
|
||||||
log::set_max_level(BOOT_CONF.log_level());
|
log::set_max_level(BOOT_CONF.log_level());
|
||||||
|
|
||||||
use crate::scheduler::Priority;
|
use crate::scheduler::Priority;
|
||||||
let mut scheduler = SCHEDULER.lock();
|
let mut scheduler = SCHEDULER.lock();
|
||||||
|
|
||||||
use Priority::*;
|
use Priority::*;
|
||||||
|
|
||||||
let mut process_1 = scheduler.new_process(High);
|
let mut process_1 = scheduler.new_process(High);
|
||||||
process_1.capabilities.files = FileAccess::Some(vec![PathRep {
|
process_1.capabilities.set_file_access(vec![PathRep {
|
||||||
location: FileLocations::Home,
|
location: FileLocations::Home,
|
||||||
file_name: "test".to_string(),
|
file_name: "test".to_string(),
|
||||||
}]);
|
}]);
|
||||||
scheduler.add_process(process_1);
|
scheduler.add_process(process_1);
|
||||||
for ref_process in &scheduler.list {
|
for ref_process in &scheduler.list {
|
||||||
trace!("{:?}", ref_process);
|
trace!("{:?}", ref_process);
|
||||||
}
|
}
|
||||||
drop(scheduler);
|
drop(scheduler);
|
||||||
|
|
||||||
use crate::proto_filetable::contain::FILE_TABLE;
|
use crate::proto_filetable::contain::FILE_TABLE;
|
||||||
use crate::proto_filetable::file::FileLocations;
|
use crate::proto_filetable::file::FileLocations;
|
||||||
|
|
||||||
let mut file_table = FILE_TABLE.lock();
|
let mut file_table = FILE_TABLE.lock();
|
||||||
let mut new_file = File::new(FileLocations::Bin, "test".to_string(), "txt".to_string());
|
let mut new_file = File::new(FileLocations::Bin, "test".to_string(), "txt".to_string());
|
||||||
|
|
||||||
new_file.write_bytes(b"Hello, world!");
|
new_file.write_bytes(b"Hello, world!");
|
||||||
file_table.add_file("test", new_file);
|
file_table.add_file("test", new_file);
|
||||||
|
|
||||||
let file = file_table.get_file("test");
|
let file = file_table.get_file("test");
|
||||||
|
|
||||||
match file {
|
match file {
|
||||||
Some(file) => {
|
Some(file) => {
|
||||||
let file_bytes = &file.data_pointer;
|
let file_bytes = &file.data_pointer;
|
||||||
let file_string = String::from_utf8(file_bytes.to_vec()).unwrap();
|
let file_string = String::from_utf8(file_bytes.to_vec()).unwrap();
|
||||||
info!("{}", file_string);
|
info!("{}", file_string);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
info!("File not found");
|
info!("File not found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use crate::wasm::WasmProgram;
|
use crate::wasm::WasmProgram;
|
||||||
let ret = WasmProgram::new_from_bytes(&[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]);
|
let ret = WasmProgram::new_from_bytes(&[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]);
|
||||||
trace!("Binary Valid: {:?}", ret.validate_header());
|
trace!("Binary Valid: {:?}", ret.validate_header());
|
||||||
|
|
||||||
sloop()
|
sloop()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// called by arch specific timers to tick up all kernel related functions
|
/// called by arch specific timers to tick up all kernel related functions
|
||||||
pub fn tick() {
|
pub fn tick() {
|
||||||
let mut data = TICK.load(Relaxed);
|
let mut data = TICK.load(Relaxed);
|
||||||
data += 1;
|
data += 1;
|
||||||
|
|
||||||
crate::kernel_state::KERNEL_STATE.lock().update_state();
|
crate::kernel_state::KERNEL_STATE.lock().update_state();
|
||||||
|
|
||||||
// let mut scheduler = SCHEDULER.lock();
|
// let mut scheduler = SCHEDULER.lock();
|
||||||
// scheduler.bump_exec();
|
// scheduler.bump_exec();
|
||||||
|
|
||||||
TICK.store(data, Relaxed)
|
TICK.store(data, Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cpu_socket_startup() {
|
pub fn cpu_socket_startup() {
|
||||||
let mut cpu_info_socket = SimpleSock::new();
|
let mut cpu_info_socket = SimpleSock::new();
|
||||||
cpu_info_socket.register_protocol("CPU_INFO".to_string());
|
cpu_info_socket.register_protocol("CPU_INFO".to_string());
|
||||||
|
|
||||||
let x = master().unwrap();
|
let x = master().unwrap();
|
||||||
let _xyz = x.brand_string().unwrap();
|
let _xyz = x.brand_string().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,88 +1,129 @@
|
||||||
|
use core::ops::BitOr;
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
use crate::file::PathRep;
|
use crate::file::PathRep;
|
||||||
|
|
||||||
|
// TODO: Get Able to document this
|
||||||
|
///
|
||||||
pub type SoundCardID = u8;
|
pub type SoundCardID = u8;
|
||||||
|
// TODO: Get Able to document this
|
||||||
|
///
|
||||||
pub type DeviceID = u8;
|
pub type DeviceID = u8;
|
||||||
|
// TODO: Get Able to document this
|
||||||
|
///
|
||||||
pub type ControllerID = u8;
|
pub type ControllerID = u8;
|
||||||
|
|
||||||
|
#[repr(u8)]
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum FileAccess {
|
/// Enum that specifies which abilities a program can have.
|
||||||
All,
|
pub enum Ability {
|
||||||
Some(Vec<PathRep>),
|
// TODO: Get Able to document this
|
||||||
None,
|
///
|
||||||
|
AllControllers = 0x01,
|
||||||
|
// TODO: Get Able to document this
|
||||||
|
///
|
||||||
|
AllFiles = 0x02,
|
||||||
|
// TODO: Get Able to document this
|
||||||
|
///
|
||||||
|
AllSoundCards = 0x04,
|
||||||
|
// TODO: Get Able to document this
|
||||||
|
///
|
||||||
|
Keyboard = 0x08,
|
||||||
|
// TODO: Get Able to document this
|
||||||
|
///
|
||||||
|
Mouse = 0x10,
|
||||||
|
// TODO: Get Able to document this
|
||||||
|
///
|
||||||
|
Telecomms = 0x20,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, Default, PartialEq)]
|
||||||
pub enum ControllerAccess {
|
/// Wrapper for bit mask of Ability.
|
||||||
All,
|
pub struct Permissions(u8);
|
||||||
Some(Vec<ControllerID>),
|
|
||||||
None,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
/// The capabilities of a program. This must only be handled by kernel code.
|
||||||
pub enum SoundCardAccess {
|
/// Capabilities should never be set by user code, either directly or indirectly.
|
||||||
All,
|
#[derive(Clone, Debug, Default, PartialEq)]
|
||||||
Some(Vec<SoundCardID>),
|
|
||||||
None,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub enum MouseAccess {
|
|
||||||
Yes,
|
|
||||||
No,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub enum KeyboardAccess {
|
|
||||||
Yes,
|
|
||||||
No,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub enum NetworkAccess {
|
|
||||||
Yes,
|
|
||||||
No,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A set of capabilities that a process has
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub struct Capabilities {
|
pub struct Capabilities {
|
||||||
// TODO: Add more capabilities
|
perms: Permissions,
|
||||||
pub files: FileAccess,
|
files: Vec<PathRep>,
|
||||||
pub mouse: MouseAccess,
|
controllers: Vec<ControllerID>,
|
||||||
pub keyboard: KeyboardAccess,
|
soundcards: Vec<SoundCardID>,
|
||||||
pub controllers: ControllerAccess,
|
|
||||||
pub sound_cards: SoundCardAccess,
|
|
||||||
pub network_access: NetworkAccess,
|
|
||||||
}
|
}
|
||||||
impl Capabilities {
|
|
||||||
/// Generate a set of empty capabilities
|
|
||||||
pub fn empty() -> Self {
|
|
||||||
Self {
|
|
||||||
files: FileAccess::None,
|
|
||||||
mouse: MouseAccess::No,
|
|
||||||
keyboard: KeyboardAccess::No,
|
|
||||||
controllers: ControllerAccess::None,
|
|
||||||
sound_cards: SoundCardAccess::None,
|
|
||||||
network_access: NetworkAccess::No,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Generate a set of capabilities that allows all access
|
impl Capabilities {
|
||||||
/// to all devices
|
/// Generate a set of empty capabilities
|
||||||
///
|
pub fn empty() -> Self {
|
||||||
/// # Safety
|
Self::default()
|
||||||
/// This is a very dangerous function and should not be used
|
}
|
||||||
/// unless you know what you are doing
|
|
||||||
pub unsafe fn all() -> Self {
|
/// Generate a set of capabilities that allows all access
|
||||||
Self {
|
/// to all devices
|
||||||
files: FileAccess::All,
|
///
|
||||||
mouse: MouseAccess::Yes,
|
/// # Safety
|
||||||
keyboard: KeyboardAccess::Yes,
|
/// This is a very dangerous function and should not be used
|
||||||
controllers: ControllerAccess::All,
|
/// unless you know what you are doing
|
||||||
sound_cards: SoundCardAccess::All,
|
pub unsafe fn all() -> Self {
|
||||||
network_access: NetworkAccess::Yes,
|
Self {
|
||||||
}
|
perms: Permissions::all(),
|
||||||
}
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Checks if capabilities has this ability.
|
||||||
|
pub fn has_ability(&self, ability: Ability) -> bool {
|
||||||
|
self.perms.has_ability(ability)
|
||||||
|
}
|
||||||
|
/// Sets which individual files this capabilities grants access to.
|
||||||
|
pub fn set_file_access(&mut self, files: Vec<PathRep>) {
|
||||||
|
self.files = files;
|
||||||
|
}
|
||||||
|
/// Sets which individual controllers this capabilities grants access to.
|
||||||
|
pub fn set_controller_access(&mut self, controllers: Vec<ControllerID>) {
|
||||||
|
self.controllers = controllers;
|
||||||
|
}
|
||||||
|
/// Sets which individual soundcards this capabilities grants access to.
|
||||||
|
pub fn set_soundcard_access(&mut self, soundcards: Vec<SoundCardID>) {
|
||||||
|
self.soundcards = soundcards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ability {
|
||||||
|
/// Returns a bit mask with all abilities enabled.
|
||||||
|
pub fn all() -> u8 {
|
||||||
|
use Ability::*;
|
||||||
|
AllControllers | AllFiles | AllSoundCards | Keyboard | Mouse | Telecomms
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BitOr for Ability {
|
||||||
|
type Output = u8;
|
||||||
|
fn bitor(self, rhs: Self) -> u8 {
|
||||||
|
self as u8 | rhs as u8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BitOr<u8> for Ability {
|
||||||
|
type Output = u8;
|
||||||
|
fn bitor(self, rhs: u8) -> u8 {
|
||||||
|
self as u8 | rhs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BitOr<Ability> for u8 {
|
||||||
|
type Output = u8;
|
||||||
|
fn bitor(self, rhs: Ability) -> u8 {
|
||||||
|
self | rhs as u8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Permissions {
|
||||||
|
/// Returns self with all abilities enabled.
|
||||||
|
pub fn all() -> Self {
|
||||||
|
Self(Ability::all())
|
||||||
|
}
|
||||||
|
/// Checks if permissions has ability.
|
||||||
|
pub fn has_ability(&self, ability: Ability) -> bool {
|
||||||
|
self.0 & ability.clone() as u8 == ability as u8
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -19,7 +19,7 @@ mod tests;
|
||||||
|
|
||||||
use crate::file::PathRep;
|
use crate::file::PathRep;
|
||||||
|
|
||||||
use self::capabilities::Capabilities;
|
use capabilities::Capabilities;
|
||||||
|
|
||||||
lazy_static::lazy_static!(
|
lazy_static::lazy_static!(
|
||||||
/// The standard implementation for ableOS
|
/// The standard implementation for ableOS
|
||||||
|
@ -30,19 +30,19 @@ lazy_static::lazy_static!(
|
||||||
/// Scheduler priority model
|
/// Scheduler priority model
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum Priority {
|
pub enum Priority {
|
||||||
/// Exclusively Kernel space | 20 Timer Tick execution time
|
/// Exclusively Kernel space | 20 Timer Tick execution time
|
||||||
High,
|
High,
|
||||||
/// Kernel / User space | 15 Timer Tick execution time
|
/// Kernel / User space | 15 Timer Tick execution time
|
||||||
Medium,
|
Medium,
|
||||||
/// low priority userspace code | 10 Timer Tick execution time
|
/// low priority userspace code | 10 Timer Tick execution time
|
||||||
Low,
|
Low,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum FileAccessTypes {
|
pub enum FileAccessTypes {
|
||||||
All,
|
All,
|
||||||
Some(Vec<PathRep>),
|
Some(Vec<PathRep>),
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This structure handles the process scheduling and execution
|
/// This structure handles the process scheduling and execution
|
||||||
|
@ -59,139 +59,139 @@ pub enum FileAccessTypes {
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Scheduler {
|
pub struct Scheduler {
|
||||||
/// The highest free process ID
|
/// The highest free process ID
|
||||||
pub free_pid: PID,
|
pub free_pid: PID,
|
||||||
/// The execution time of the current process in ticks
|
/// The execution time of the current process in ticks
|
||||||
pub process_exec_time: u64,
|
pub process_exec_time: u64,
|
||||||
/// The list of processes
|
/// The list of processes
|
||||||
pub list: Vec<Process>,
|
pub list: Vec<Process>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scheduler {
|
impl Scheduler {
|
||||||
/// Create a new scheduler
|
/// Create a new scheduler
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
/// ```
|
/// ```
|
||||||
/// use ableos::scheduler::Priority;
|
/// use ableos::scheduler::Priority;
|
||||||
/// let mut scheduler = Scheduler::new();
|
/// let mut scheduler = Scheduler::new();
|
||||||
/// ```
|
/// ```
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
free_pid: PID(0),
|
free_pid: PID(0),
|
||||||
process_exec_time: 0,
|
process_exec_time: 0,
|
||||||
list: Vec::new(),
|
list: 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
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let mut scheduler = scheduler();
|
/// let mut scheduler = scheduler();
|
||||||
/// let mut process = scheduler.next_process();
|
/// let mut process = scheduler.next_process();
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if there are no processes in the list
|
/// 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.list[0].clone();
|
||||||
self.list.remove(0);
|
self.list.remove(0);
|
||||||
self.list.push(previous_task);
|
self.list.push(previous_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new process
|
/// Creates a new process
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `priority` - The priority of the process
|
/// * `priority` - The priority of the process
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let mut scheduler = scheduler();
|
/// let mut scheduler = scheduler();
|
||||||
/// let mut process = scheduler.new_process(Priority::Medium);
|
/// let mut process = scheduler.new_process(Priority::Medium);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn new_process(&mut self, priority: Priority) -> Process {
|
pub fn new_process(&mut self, priority: Priority) -> Process {
|
||||||
let process = Process {
|
let process = Process {
|
||||||
id: self.free_pid.clone(),
|
id: self.free_pid.clone(),
|
||||||
capabilities: Capabilities::empty(),
|
capabilities: Capabilities::empty(),
|
||||||
priority,
|
priority,
|
||||||
};
|
};
|
||||||
// self.free_pid.0 += 1;
|
// self.free_pid.0 += 1;
|
||||||
// self.list.push(process);
|
// self.list.push(process);
|
||||||
process
|
process
|
||||||
}
|
}
|
||||||
/// Add a created process to the scheduler
|
/// Add a created process to the scheduler
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `process` - The process to add
|
/// * `process` - The process to add
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let mut scheduler = Scheduler::new();
|
/// let mut scheduler = Scheduler::new();
|
||||||
/// let mut process = scheduler.new_process(Priority::Medium);
|
/// let mut process = scheduler.new_process(Priority::Medium);
|
||||||
/// scheduler.add_process(process);
|
/// scheduler.add_process(process);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn add_process(&mut self, process: Process) {
|
pub fn add_process(&mut self, process: Process) {
|
||||||
self.list.push(process);
|
self.list.push(process);
|
||||||
|
|
||||||
self.free_pid.0 += 1;
|
self.free_pid.0 += 1;
|
||||||
}
|
}
|
||||||
/// Terminate the process with the matching PID
|
/// Terminate the process with the matching PID
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `pid` - The PID of the process to terminate
|
/// * `pid` - The PID of the process to terminate
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let mut scheduler = scheduler();
|
/// let mut scheduler = scheduler();
|
||||||
/// let mut process = scheduler.new_process(Priority::Medium);
|
/// let mut process = scheduler.new_process(Priority::Medium);
|
||||||
/// scheduler.terminate_process(process.id);
|
/// scheduler.terminate_process(process.id);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn term_process(&mut self, pid: PID) {
|
pub fn term_process(&mut self, pid: PID) {
|
||||||
let mut process_index = 0;
|
let mut process_index = 0;
|
||||||
for x in &self.list {
|
for x in &self.list {
|
||||||
if x.id == pid {
|
if x.id == pid {
|
||||||
self.list.remove(process_index);
|
self.list.remove(process_index);
|
||||||
break;
|
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::*;
|
||||||
|
if self.list.len() > 0 {
|
||||||
|
match (self.process_exec_time, self.list[0].priority) {
|
||||||
|
(20, High) => {
|
||||||
|
self.next_process();
|
||||||
}
|
}
|
||||||
process_index += 1
|
(15, Medium) => {
|
||||||
}
|
self.next_process();
|
||||||
}
|
|
||||||
/// 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::*;
|
|
||||||
if self.list.len() > 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
(_, _) => {}
|
|
||||||
}
|
}
|
||||||
}
|
(10, Low) => {
|
||||||
}
|
self.next_process();
|
||||||
|
}
|
||||||
|
|
||||||
|
(_, _) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,49 +1,45 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use crate::scheduler::{
|
use crate::{scheduler::{proc::PID, Priority::*, Scheduler}, capabilities::Ability};
|
||||||
capabilities::{ControllerAccess, FileAccess, KeyboardAccess, MouseAccess, SoundCardAccess},
|
|
||||||
proc::PID,
|
|
||||||
Priority::*,
|
|
||||||
Scheduler,
|
|
||||||
};
|
|
||||||
|
|
||||||
// #[test]
|
// #[test]
|
||||||
fn test_new_process() {
|
fn test_new_process() {
|
||||||
let mut scheduler = Scheduler::new();
|
let mut scheduler = Scheduler::new();
|
||||||
scheduler.new_process(High);
|
scheduler.new_process(High);
|
||||||
assert_eq!(scheduler.list.len(), 1);
|
assert_eq!(scheduler.list.len(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
// #[test]
|
||||||
fn test_next_process() {
|
fn test_next_process() {
|
||||||
let mut scheduler = Scheduler::new();
|
let mut scheduler = Scheduler::new();
|
||||||
scheduler.new_process(High);
|
scheduler.new_process(High);
|
||||||
scheduler.next_process();
|
scheduler.next_process();
|
||||||
assert_eq!(scheduler.list.len(), 0);
|
assert_eq!(scheduler.list.len(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
// #[test]
|
||||||
fn test_term_process() {
|
fn test_term_process() {
|
||||||
let mut scheduler = Scheduler::new();
|
let mut scheduler = Scheduler::new();
|
||||||
scheduler.new_process(High);
|
scheduler.new_process(High);
|
||||||
scheduler.term_process(PID(1));
|
scheduler.term_process(PID(1));
|
||||||
assert_eq!(scheduler.list.len(), 0);
|
assert_eq!(scheduler.list.len(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
// #[test]
|
||||||
fn test_bump_exec() {
|
fn test_bump_exec() {
|
||||||
let mut scheduler = Scheduler::new();
|
let mut scheduler = Scheduler::new();
|
||||||
scheduler.new_process(High);
|
scheduler.new_process(High);
|
||||||
scheduler.bump_exec();
|
scheduler.bump_exec();
|
||||||
assert_eq!(scheduler.process_exec_time, 1);
|
assert_eq!(scheduler.process_exec_time, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
// #[test]
|
||||||
fn test_capabilities() {
|
fn test_capabilities() {
|
||||||
let caps = Capabilities::empty();
|
let caps = Capabilities::empty();
|
||||||
assert_eq!(caps.files, FileAccess::None);
|
assert!(!caps.has_ability(Ability::AllControllers));
|
||||||
assert_eq!(caps.mouse, MouseAccess::No);
|
assert!(!caps.has_ability(Ability::AllFiles));
|
||||||
assert_eq!(caps.keyboard, KeyboardAccess::No);
|
assert!(!caps.has_ability(Ability::AllSoundCards));
|
||||||
assert_eq!(caps.controllers, ControllerAccess::None);
|
assert!(!caps.has_ability(Ability::Keyboard));
|
||||||
assert_eq!(caps.sound_cards, SoundCardAccess::None);
|
assert!(!caps.has_ability(Ability::Mouse));
|
||||||
|
assert!(!caps.has_ability(Ability::Telecomms));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue