Implemented constructors for synch structs
This commit is contained in:
parent
df1b7a59e4
commit
287a608adf
@ -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(¤t_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.
|
||||||
///
|
///
|
||||||
|
Loading…
Reference in New Issue
Block a user