Implemented constructors for synch structs

This commit is contained in:
Rémi Rativel 2023-03-14 16:34:44 +01:00
parent df1b7a59e4
commit 287a608adf

View File

@ -1,3 +1,4 @@
use core::panicking::panic;
use crate::utility::list::List; use crate::utility::list::List;
use crate::kernel::thread::Thread; use crate::kernel::thread::Thread;
use crate::simulator::interrupt::InterruptStatus::InterruptOff; use crate::simulator::interrupt::InterruptStatus::InterruptOff;
@ -23,6 +24,10 @@ pub struct Semaphore {
impl Semaphore { impl Semaphore {
pub fn new(counter: i32, thread_manager: Rc<RefCell<ThreadManager>>) -> Semaphore{
Semaphore { counter, waiting_queue: List::new(), thread_manager}
}
/// Decrement the value, and wait if it becomes < 0. Checking the /// Decrement the value, and wait if it becomes < 0. Checking the
/// value and decrementing must be done atomically, so we /// value and decrementing must be done atomically, so we
/// need to disable interrupts before checking the value. /// need to disable interrupts before checking the value.
@ -69,7 +74,7 @@ impl Semaphore {
pub struct Lock{ pub struct Lock{
/// Thread owning the lock /// Thread owning the lock
owner: Rc<RefCell<Thread>>, owner: Option<Rc<RefCell<Thread>>>,
/// The queue of threads waiting for execution /// The queue of threads waiting for execution
waiting_queue:List<Rc<RefCell<Thread>>>, waiting_queue:List<Rc<RefCell<Thread>>>,
/// Thread manager which managing threads /// Thread manager which managing threads
@ -81,6 +86,15 @@ pub struct Lock{
impl Lock { impl Lock {
/// Initialize a Lock, so that it can be used for synchronization.
/// The lock is initialy free
///
/// ### Parameters
/// - **thread_manager** Thread manager which managing threads
pub fn new(thread_manager: Rc<RefCell<ThreadManager>>) -> Lock {
Lock { owner: None, waiting_queue: List::new(), thread_manager, free: true }
}
/// Wait until the lock become free. Checking the /// Wait until the lock become free. Checking the
/// state of the lock (free or busy) and modify it must be done /// state of the lock (free or busy) and modify it must be done
/// atomically, so we need to disable interrupts before checking /// atomically, so we need to disable interrupts before checking
@ -92,15 +106,20 @@ impl Lock {
/// ### Parameters /// ### Parameters
/// - **current_thread** the current thread /// - **current_thread** the current thread
/// - **machine** the machine where the threads are executed /// - **machine** the machine where the threads are executed
pub fn acquire(&mut self, current_thread: Rc<RefCell<Thread>>, machine: &mut Machine) { pub fn acquire(&mut self, current_thread: Option<Rc<RefCell<Thread>>>, machine: &mut Machine) {
let old_status = machine.interrupt.set_status(InterruptOff); let old_status = machine.interrupt.set_status(InterruptOff);
if self.free { if self.free {
self.free = false; self.free = false;
self.owner = current_thread; self.owner = current_thread;
} else { } else {
self.waiting_queue.push(Rc::clone(&current_thread)); match current_thread {
self.thread_manager.borrow_mut().thread_sleep(current_thread); Some(x) => {
self.waiting_queue.push(Rc::clone(&x));
self.thread_manager.borrow_mut().thread_sleep(x)
},
None => ()
}
} }
machine.interrupt.set_status(old_status); machine.interrupt.set_status(old_status);
@ -120,8 +139,11 @@ impl Lock {
if self.held_by_current_thread(current_thread) { if self.held_by_current_thread(current_thread) {
if self.waiting_queue.peek() != None { if self.waiting_queue.peek() != None {
self.owner = self.waiting_queue.pop().unwrap(); self.owner = Some(self.waiting_queue.pop().unwrap());
scheduler.ready_to_run(Rc::clone(&self.owner)); match &self.owner {
Some(x) => scheduler.ready_to_run(Rc::clone(&x)),
None => ()
}
} else { } else {
self.free = true; self.free = true;
} }
@ -147,6 +169,14 @@ pub struct Condition{
impl Condition { impl Condition {
/// Initializes a Condition, so that it can be used for synchronization.
///
/// ### Parameters
/// - *thread_manager* Thread manager which managing threads
pub fn new(thread_manager: Rc<RefCell<ThreadManager>>) -> Condition {
Condition{ waiting_queue: List::new(), thread_manager }
}
/// Block the calling thread (put it in the wait queue). /// Block the calling thread (put it in the wait queue).
/// This operation must be atomic, so we need to disable interrupts. /// This operation must be atomic, so we need to disable interrupts.
/// ///