Fix exceptions with semaphore
This commit is contained in:
parent
134e2bd2cc
commit
21f3a72a3d
@ -2,7 +2,7 @@ use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use crate::{simulator::{machine::{ExceptionType, Machine}, error::{MachineOk, MachineError}}};
|
||||
|
||||
use super::{system::System, thread::Thread, synch::Semaphore};
|
||||
use super::{system::System, thread::Thread};
|
||||
|
||||
type Error = String;
|
||||
|
||||
@ -200,21 +200,12 @@ fn syscall(machine: &mut Machine, system: &mut System) -> Result<MachineOk, Mach
|
||||
|
||||
fn sc_p(machine: &mut Machine, system: &mut System) -> Result<MachineOk, MachineError> {
|
||||
let id_sema = machine.int_reg.get_reg(10);
|
||||
match system.get_obj_addrs().search_semaphore(id_sema as i32) {
|
||||
Some(sema) => { sema.p(machine, system.get_thread_manager()); Ok(MachineOk::Ok) }
|
||||
None => Err(format!("Coudn't find semaphore {}", id_sema))?
|
||||
}
|
||||
system.get_thread_manager().sem_p(id_sema as i32, machine)
|
||||
}
|
||||
|
||||
fn sc_v(machine: &mut Machine, system: &mut System) -> Result<MachineOk, MachineError> {
|
||||
let id_sema = machine.int_reg.get_reg(10);
|
||||
match system.get_obj_addrs().search_semaphore(id_sema as i32) {
|
||||
Some(sema) => {
|
||||
sema.v(machine, system.get_thread_manager());
|
||||
Ok(MachineOk::Ok)
|
||||
},
|
||||
None => Err(format!("Couldn't find semaphore {}", id_sema))?
|
||||
}
|
||||
system.get_thread_manager().sem_v(id_sema as i32, machine)
|
||||
}
|
||||
|
||||
fn sc_sem_create(machine: &mut Machine) -> Result<MachineOk, MachineError> {
|
||||
|
@ -7,12 +7,13 @@ use std::rc::Rc;
|
||||
use super::thread_manager::ThreadManager;
|
||||
|
||||
/// Structure of a Semaphore used for synchronisation
|
||||
#[derive(PartialEq)]
|
||||
pub struct Semaphore {
|
||||
|
||||
/// Counter of simultanous Semaphore
|
||||
counter:i32,
|
||||
pub counter:i32,
|
||||
/// QUeue of Semaphore waiting to be exucated
|
||||
waiting_queue:List<Rc<RefCell<Thread>>>,
|
||||
pub waiting_queue:List<Rc<RefCell<Thread>>>,
|
||||
|
||||
}
|
||||
|
||||
@ -78,7 +79,8 @@ impl Semaphore {
|
||||
/// Lock used for synchronisation, can be interpreted has a Semaphore with a
|
||||
/// counter of 1
|
||||
/// It's used for critical parts
|
||||
pub struct Lock{
|
||||
#[derive(PartialEq)]
|
||||
pub struct Lock {
|
||||
|
||||
/// Thread owning the lock
|
||||
owner: Option<Rc<RefCell<Thread>>>,
|
||||
|
@ -3,7 +3,6 @@
|
||||
//! Module containing structs and methods pertaining to the state of the operating system
|
||||
|
||||
use super::{thread_manager::ThreadManager};
|
||||
use crate::utility::objaddr::ObjAddr;
|
||||
|
||||
/// # System
|
||||
///
|
||||
@ -16,8 +15,7 @@ use crate::utility::objaddr::ObjAddr;
|
||||
/// - The thread to be destroyed next
|
||||
/// - The scheduler which acts upon these threads
|
||||
pub struct System {
|
||||
thread_manager: ThreadManager,
|
||||
obj_addrs: ObjAddr
|
||||
thread_manager: ThreadManager
|
||||
}
|
||||
|
||||
impl System {
|
||||
@ -28,14 +26,12 @@ impl System {
|
||||
&mut self.thread_manager
|
||||
}
|
||||
|
||||
pub fn get_obj_addrs(&mut self) -> &mut ObjAddr { &mut self.obj_addrs }
|
||||
|
||||
}
|
||||
|
||||
impl Default for System {
|
||||
/// System constructor
|
||||
fn default() -> Self {
|
||||
Self { thread_manager: ThreadManager::new(), obj_addrs: ObjAddr::init() }
|
||||
Self { thread_manager: ThreadManager::new() }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
use std::{rc::Rc, cell::{RefCell, Ref}};
|
||||
|
||||
use crate::{utility::list::List, simulator::{machine::{NUM_INT_REGS, NUM_FP_REGS, Machine}, interrupt::InterruptStatus}};
|
||||
use crate::{utility::{list::List, objaddr::ObjAddr}, simulator::{machine::{NUM_INT_REGS, NUM_FP_REGS, Machine}, interrupt::InterruptStatus, error::{MachineOk, MachineError}}};
|
||||
|
||||
use super::{thread::Thread, process::Process};
|
||||
use super::{thread::Thread, process::Process, synch::Semaphore};
|
||||
|
||||
pub const SIMULATORSTACKSIZE: usize = 32 * 1024;
|
||||
|
||||
@ -19,6 +19,7 @@ pub struct ThreadManager {
|
||||
pub g_alive: List<Rc<RefCell<Thread>>>,
|
||||
/// Thread in ready state waiting to become active
|
||||
ready_list: List<Rc<RefCell<Thread>>>,
|
||||
obj_addrs: ObjAddr
|
||||
}
|
||||
|
||||
impl ThreadManager {
|
||||
@ -30,6 +31,7 @@ impl ThreadManager {
|
||||
g_thread_to_be_destroyed: Option::None,
|
||||
g_alive: List::default(),
|
||||
ready_list: List::default(),
|
||||
obj_addrs: ObjAddr::init(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,6 +173,49 @@ impl ThreadManager {
|
||||
machine.pc = t.thread_context.pc;
|
||||
}
|
||||
|
||||
pub fn sem_p(&mut self, id_sema: i32, machine: &mut Machine) -> Result<MachineOk, MachineError> {
|
||||
match self.get_g_current_thread() {
|
||||
Some(thread) => {
|
||||
let rc1_thread = Rc::clone(thread);
|
||||
let rc2_thread = Rc::clone(thread);
|
||||
let sema = self.get_obj_addrs().search_semaphore(id_sema as i32);
|
||||
if let Some(sema) = sema {
|
||||
let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff);
|
||||
sema.counter -= 1;
|
||||
if sema.counter < 0 {
|
||||
sema.waiting_queue.push(rc1_thread);
|
||||
self.thread_sleep(machine, rc2_thread);
|
||||
}
|
||||
machine.interrupt.set_status(old_status);
|
||||
Ok(MachineOk::Ok)
|
||||
} else {
|
||||
Err("Cannot find semaphore")?
|
||||
}
|
||||
},
|
||||
None => unreachable!("Current thread should not be None")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sem_v(&mut self, id_sema: i32, machine: &mut Machine) -> Result<MachineOk, MachineError> {
|
||||
let sema = self.get_obj_addrs().search_semaphore(id_sema as i32);
|
||||
match sema {
|
||||
Some(sema) => {
|
||||
let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff);
|
||||
sema.counter += 1;
|
||||
match sema.waiting_queue.pop() {
|
||||
Some(thread) => self.ready_to_run(thread),
|
||||
None => ()
|
||||
}
|
||||
machine.interrupt.set_status(old_status);
|
||||
Ok(MachineOk::Ok)
|
||||
},
|
||||
None => {
|
||||
Err("Cannot find semaphore")?
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Currently running thread
|
||||
pub fn get_g_current_thread(&mut self) -> &Option<Rc<RefCell<Thread>>> {
|
||||
&self.g_current_thread
|
||||
@ -198,6 +243,10 @@ impl ThreadManager {
|
||||
self.g_thread_to_be_destroyed = thread
|
||||
}
|
||||
|
||||
pub fn get_obj_addrs(&mut self) -> &mut ObjAddr {
|
||||
&mut self.obj_addrs
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -15,6 +15,7 @@ use crate::kernel::synch::{ Semaphore, Lock };
|
||||
/// A method allows to detect of an object corresponding to a given
|
||||
/// identifier exists; this is used to check the parameters of system
|
||||
/// calls.
|
||||
#[derive(PartialEq)]
|
||||
pub struct ObjAddr {
|
||||
last_id: i32,
|
||||
semaphores: HashMap<i32, Semaphore>,
|
||||
@ -47,12 +48,12 @@ impl ObjAddr {
|
||||
}
|
||||
|
||||
/// Searches for a semaphore of id **id** in self
|
||||
pub fn search_semaphore(&self, id: i32) -> Option<&mut Semaphore> {
|
||||
pub fn search_semaphore(&mut self, id: i32) -> Option<&mut Semaphore> {
|
||||
self.semaphores.get_mut(&id)
|
||||
}
|
||||
|
||||
/// Searches for a lock of id **id** in self
|
||||
pub fn search_lock(&self, id:i32) -> Option<&mut Lock> {
|
||||
pub fn search_lock(&mut self, id:i32) -> Option<&mut Lock> {
|
||||
self.locks.get_mut(&id)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user