Implemente finish (not finished yet), fix ucontext for windows

This commit is contained in:
Quentin Legot 2023-03-08 13:21:08 +01:00
parent 6ca0b564c5
commit 8c6ef4e131
5 changed files with 45 additions and 15 deletions

View File

@ -2,11 +2,12 @@ use std::{sync::{RwLock, Arc}};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use crate::{kernel::{thread::Thread, scheduler::Scheduler}, utility::list::List}; use crate::{kernel::{thread::Thread, scheduler::Scheduler}, utility::list::List, simulator::machine::Machine};
extern crate lazy_static; extern crate lazy_static;
lazy_static! { lazy_static! {
pub static ref G_MACHINE: RwLock<Machine> = RwLock::new(Machine::_init_machine());
pub static ref G_CURRENT_THREAD: RwLock<Option<Thread>> = RwLock::new(Option::None); pub static ref G_CURRENT_THREAD: RwLock<Option<Thread>> = RwLock::new(Option::None);
pub static ref G_THREAD_TO_BE_DESTROYED: RwLock<Option<Thread>> = RwLock::new(Option::None); pub static ref G_THREAD_TO_BE_DESTROYED: RwLock<Option<Thread>> = RwLock::new(Option::None);
pub static ref G_ALIVE: RwLock<List<Arc<Thread>>> = RwLock::new(List::new()); pub static ref G_ALIVE: RwLock<List<Arc<Thread>>> = RwLock::new(List::new());

View File

@ -1,7 +1,7 @@
use std::{sync::Arc}; use std::{sync::Arc};
use super::{process::Process, mgerror::ErrorCode, system::{ObjectType, G_ALIVE, G_SCHEDULER}, ucontext::UContextT}; use super::{process::Process, mgerror::ErrorCode, system::{ObjectType, G_ALIVE, G_SCHEDULER}, ucontext::UContextT};
use crate::{simulator::machine::{NUM_INT_REGS, NUM_FP_REGS, STACK_REG}}; use crate::{simulator::machine::{NUM_INT_REGS, NUM_FP_REGS, STACK_REG}, kernel::system::{G_MACHINE, G_THREAD_TO_BE_DESTROYED}};
const SIMULATORSTACKSIZE: usize = 32 * 1024; const SIMULATORSTACKSIZE: usize = 32 * 1024;
const STACK_FENCEPOST: u32 = 0xdeadbeef; const STACK_FENCEPOST: u32 = 0xdeadbeef;
@ -116,7 +116,34 @@ impl Thread {
} }
/// Finish the execution of the thread and prepare its deallocation /// Finish the execution of the thread and prepare its deallocation
pub fn finish(&self) { pub fn finish(mut self) {
match G_MACHINE.write() {
Ok(mut machine) => {
let old_status = machine.interrupt.set_status(crate::simulator::interrupt::InterruptStatus::InterruptOff);
match G_ALIVE.write() {
Ok(alive) => {
// todo alive.remove(T) à implémenter dans List
},
Err(err) => {
panic!("RwLock is poisoned: {}", err);
}
}
match G_THREAD_TO_BE_DESTROYED.write() {
Ok(mut thread_to_be_destroyed) => {
thread_to_be_destroyed.replace(self);
},
Err(err) => {
panic!("RwLock is poisoned: {}", err);
}
}
// self.sleep();
machine.interrupt.set_status(old_status);
},
Err(err) => {
panic!("RwLock is poisoned: {}", err);
}
}
todo!(); todo!();
} }

View File

@ -1,8 +1,6 @@
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
use libc::{ucontext_t, getcontext, setcontext, makecontext};
/// Safe wrapper for ucontext_t struct of linux-gnu libc /// Safe wrapper for ucontext_t struct of linux-gnu libc
/// ///
/// setcontext and getcontext are unsafe function, this wrap unsafe libc functions /// setcontext and getcontext are unsafe function, this wrap unsafe libc functions
@ -13,7 +11,7 @@ use libc::{ucontext_t, getcontext, setcontext, makecontext};
#[derive(PartialEq)] #[derive(PartialEq)]
pub struct UContextT { pub struct UContextT {
#[cfg(not(target_os = "windows"))] // struct non disponible sur la libc sur windows #[cfg(not(target_os = "windows"))] // struct non disponible sur la libc sur windows
pub buf: ucontext_t, pub buf: lib::ucontext_t,
pub stackBottom: Vec<i8> pub stackBottom: Vec<i8>
} }
@ -22,7 +20,7 @@ impl UContextT {
pub fn new() -> Self { pub fn new() -> Self {
let mut context = MaybeUninit::<ucontext_t>::uninit(); let mut context = MaybeUninit::<ucontext_t>::uninit();
unsafe { getcontext(context.as_mut_ptr()) }; unsafe { lib::getcontext(context.as_mut_ptr()) };
Self { Self {
buf: unsafe { context.assume_init() }, buf: unsafe { context.assume_init() },
stackBottom: Vec::default(), stackBottom: Vec::default(),
@ -34,7 +32,7 @@ impl UContextT {
/// Use `man getcontext` for more informations /// Use `man getcontext` for more informations
pub fn get_context(&mut self) -> i32 { pub fn get_context(&mut self) -> i32 {
unsafe { unsafe {
getcontext(&mut self.buf) lib::getcontext(&mut self.buf)
} }
} }
@ -43,13 +41,13 @@ impl UContextT {
/// Use `man setcontext` for more informations /// Use `man setcontext` for more informations
pub fn set_context(&mut self) -> i32 { pub fn set_context(&mut self) -> i32 {
unsafe { unsafe {
setcontext(&self.buf) lib::setcontext(&self.buf)
} }
} }
pub fn make_context(&mut self, func: extern "C" fn(), args: i32) { pub fn make_context(&mut self, func: extern "C" fn(), args: i32) {
unsafe { unsafe {
makecontext(&mut self.buf, func, args) lib::makecontext(&mut self.buf, func, args)
} }
} }
@ -59,7 +57,9 @@ impl UContextT {
impl UContextT { impl UContextT {
pub fn new() -> Self { pub fn new() -> Self {
Self {} Self {
stackBottom: Vec::default()
}
} }
pub fn get_context(&mut self) { pub fn get_context(&mut self) {

View File

@ -1,6 +1,6 @@
struct Interrupt { pub struct Interrupt {
level: InterruptStatus level: InterruptStatus
} }

View File

@ -1,6 +1,6 @@
use std::{ops::{Add, Sub}, io::Write}; use std::{ops::{Add, Sub}, io::Write};
use super::{decode::{Instruction, decode}}; use super::{decode::{Instruction, decode}, interrupt::Interrupt};
use super::global::*; use super::global::*;
use std::fs::File; use std::fs::File;
@ -71,7 +71,8 @@ pub struct Machine {
pub int_reg : Register<i64>, pub int_reg : Register<i64>,
pub fp_reg : Register<f32>, pub fp_reg : Register<f32>,
pub main_memory : [u8 ; MEM_SIZE], pub main_memory : [u8 ; MEM_SIZE],
pub shiftmask : [u64 ; 64] pub shiftmask : [u64 ; 64],
pub interrupt: Interrupt,
// futur taille à calculer int memSize = g_cfg->NumPhysPages * g_cfg->PageSize; // futur taille à calculer int memSize = g_cfg->NumPhysPages * g_cfg->PageSize;
//creer une struct cfg(configuration) qui s'initialise avec valeur dans un fichier cfg //creer une struct cfg(configuration) qui s'initialise avec valeur dans un fichier cfg
} }
@ -95,7 +96,8 @@ impl Machine {
int_reg : Register::<i64>::init(), int_reg : Register::<i64>::init(),
fp_reg : Register::<f32>::init(), fp_reg : Register::<f32>::init(),
main_memory : [0 ; MEM_SIZE], main_memory : [0 ; MEM_SIZE],
shiftmask shiftmask,
interrupt: Interrupt::new()
} }
} }