Commit d789589f authored by Nifou's avatar Nifou

Fix an error with removed processes and current process

parent 65e58166
......@@ -78,7 +78,7 @@ impl Syscall {
crate::memory::switch_to_kernel_page_table();
// Get the current thread's process
let current_process = PROCESSOR.inner().scheduler.current().process;
let current_process = PROCESSOR.inner().scheduler.current().unwrap().process;
processes.get_mut(&current_process).unwrap().memory.map(0x300000, 0x300000 + len as u64, Flags::from(prot), Flags::PRESENT);
processes.get_mut(&current_process).unwrap().memory.switch_page_table();
......@@ -106,7 +106,7 @@ impl Syscall {
crate::memory::switch_to_kernel_page_table();
// Get the current thread's process
let current_process = PROCESSOR.inner().scheduler.current().process;
let current_process = PROCESSOR.inner().scheduler.current().unwrap().process;
processes.get_mut(&current_process).unwrap().memory.map(0x10000000, 0x10004000, Flags::PRESENT | Flags::WRITABLE, Flags::PRESENT);
processes.get_mut(&current_process).unwrap().memory.switch_page_table();
......
......@@ -66,7 +66,7 @@ impl Syscall {
// Use the kernel's page table
crate::memory::switch_to_kernel_page_table();
PROCESSOR.inner().scheduler.remove();
PROCESSOR.inner().scheduler.remove_current();
if let Some(thread) = PROCESSOR.inner().scheduler.choose() {
// Change the stack to use the new context
......@@ -108,7 +108,7 @@ impl Syscall {
// Use the kernel's page table
crate::memory::switch_to_kernel_page_table();
PROCESSOR.inner().scheduler.remove();
PROCESSOR.inner().scheduler.remove_current();
if let Some(thread) = PROCESSOR.inner().scheduler.choose() {
// Change the stack to use the new context
......
......@@ -15,7 +15,7 @@
* along with this program. If not, see https://www.gnu.org/licenses.
*/
//! A trait which make the addition of other scheduler algorithms easier
use super::thread::Thread;
use super::thread::{Thread, Tid};
/// A trait which defines the common functions used in a scheduler algorithm
pub trait SchedulerAlgo {
......@@ -23,14 +23,23 @@ pub trait SchedulerAlgo {
fn add(&mut self, thread: Thread);
/// Remove the current thread in the list of threads
fn remove(&mut self);
fn remove_current(&mut self);
/// Remove the thread with tid `tid` in the list of threads
fn remove(&mut self, tid: Tid);
/// Choose the next thread which will be executed
fn choose(&mut self) -> Option<Thread>;
/// Get the current thread
fn current(&self) -> Thread;
fn current(&self) -> Option<&Thread>;
/// Get the current mutable thread
fn current_mut(&mut self) -> &mut Thread;
fn current_mut(&mut self) -> Option<&mut Thread>;
/// Get the thread with the TID `tid`
fn get(&self, tid: Tid) -> Option<&Thread>;
/// Get the mutable thread with the TID `tid`
fn get_mut(&mut self, tid: Tid) -> Option<&mut Thread>;
}
......@@ -37,7 +37,7 @@ static NEXT_PID: AtomicUsize = AtomicUsize::new(0);
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
/// A process ID
pub struct Pid(usize);
pub struct Pid(pub usize);
#[derive(PartialEq, Debug, Clone, Copy)]
/// The state of the process (killed or alive)
......
......@@ -19,11 +19,12 @@ use alloc::collections::vec_deque::VecDeque;
use crate::tasking::{
algo::SchedulerAlgo,
thread::Thread,
thread::{Thread, Tid},
};
/// A [Round Robin](https://en.wikipedia.org/wiki/Round-robin_scheduling) sheduler
pub struct RoundRobinScheduler {
current: Tid,
threads: VecDeque<Thread>,
}
......@@ -31,6 +32,7 @@ impl RoundRobinScheduler {
/// Create a new Round Robin scheduler
pub fn new() -> Self {
Self {
current: Tid(0),
threads: VecDeque::new(),
}
}
......@@ -47,6 +49,7 @@ impl SchedulerAlgo for RoundRobinScheduler {
// Add the thread at the end of the queue
if let Some(thread) = thread.clone() {
self.current = thread.tid;
self.threads.push_back(thread);
}
......@@ -54,18 +57,38 @@ impl SchedulerAlgo for RoundRobinScheduler {
thread
}
fn remove(&mut self) {
// The last process is the current process
self.threads.pop_back();
fn remove_current(&mut self) {
self.remove(self.current);
}
fn remove(&mut self, tid: Tid) {
assert!(!self.threads.is_empty());
let mut index = 0;
for (i, thread) in self.threads.iter_mut().enumerate() {
if thread.tid == tid {
index = i;
break;
}
}
self.threads.remove(index);
}
fn current(&self) -> Thread {
fn current(&self) -> Option<&Thread> {
// The last process is the current process
self.threads.back().expect("There is zero thread").clone()
self.get(self.current)
}
fn current_mut(&mut self) -> &mut Thread {
fn current_mut(&mut self) -> Option<&mut Thread> {
// The last process is the current process
self.threads.back_mut().expect("There is zero thread")
self.get_mut(self.current)
}
fn get(&self, tid: Tid) -> Option<&Thread> {
self.threads.iter().find(|thread| thread.tid == tid)
}
fn get_mut(&mut self, tid: Tid) -> Option<&mut Thread> {
self.threads.iter_mut().find(|thread| thread.tid == tid)
}
}
......@@ -51,7 +51,7 @@ const KSTACK_SIZE: usize = 4096;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
/// A thread ID
pub struct Tid(usize);
pub struct Tid(pub usize);
#[derive(Debug, Clone)]
/// A thread which is chosen by the scheduler
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment