Add thread save and restore processor context

This commit is contained in:
Quentin Legot
2023-03-09 12:08:33 +01:00
committed by François Autin
parent 0c3af96b78
commit 26b75ffe8d
5 changed files with 87 additions and 55 deletions

View File

@ -1,10 +1,10 @@
use std::{rc::Rc, cell::Cell};
use std::{rc::Rc, cell::{Cell, RefCell, RefMut, Ref}};
use crate::utility::list::List;
use crate::{utility::list::List, simulator::machine::{NUM_INT_REGS, NUM_FP_REGS}};
use super::{scheduler::Scheduler, thread::Thread, system::System, mgerror::ErrorCode, process::Process};
const SIMULATORSTACKSIZE: usize = 32 * 1024;
pub const SIMULATORSTACKSIZE: usize = 32 * 1024;
#[derive(PartialEq)]
pub struct ThreadManager<'a> {
@ -44,17 +44,54 @@ impl<'a> ThreadManager<'a> {
/// Wait for another thread to finish its execution
pub fn thread_join(&mut self, id_thread: Rc<Thread>) {
while self.get_g_alive().contains(&Rc::clone(&id_thread)) {
self.thread_yield();
self.thread_yield(Rc::clone(&id_thread));
}
}
/// Relinquish the CPU if any other thread is runnable.
///
/// Cannot use yield as a function name -> reserved name in rust
pub fn thread_yield(&mut self) {
pub fn thread_yield(&mut self, thread: Rc<Thread>) {
todo!();
}
/// Put the thread to sleep and relinquish the processor
pub fn thread_sleep(&mut self, thread: Rc<Thread>) {
todo!();
}
/// Finish the execution of the thread and prepare its deallocation
pub fn thread_finish(&self, thread: Rc<Thread>) {
todo!();
}
pub fn thread_save_processor_state(&mut self, thread: Rc<RefCell<Thread>>) {
if let Some(system) = self.system.get() {
let mut t: RefMut<_> = thread.borrow_mut();
for i in 0..NUM_INT_REGS {
t.thread_context.int_registers[i] = system.get_g_machine().borrow().read_int_register(i);
}
for i in 0..NUM_FP_REGS {
t.thread_context.float_registers[i] = system.get_g_machine().borrow().read_fp_register(i);
}
} else {
unreachable!("System is None")
}
}
pub fn thread_restore_processor_state(&self, thread: Rc<RefCell<Thread>>) {
if let Some(system) = self.system.get() {
let t: Ref<_> = thread.borrow();
for i in 0..NUM_INT_REGS {
let machine = system.get_g_machine();
let mut machine = machine.borrow_mut();
machine.write_int_register(i, t.thread_context.int_registers[i]);
}
} else {
unreachable!("System is None")
}
}
/// Currently running thread
pub fn get_g_current_thread(&mut self) -> &mut Option<Thread> {
&mut self.g_current_thread