diff --git a/src/kernel/synch.rs b/src/kernel/synch.rs index 0baa892..807793f 100644 --- a/src/kernel/synch.rs +++ b/src/kernel/synch.rs @@ -34,6 +34,7 @@ impl Semaphore { /// counter of 1 /// It's used for critical parts #[derive(PartialEq)] +#[derive(Clone)] pub struct Lock { /// Thread owning the lock diff --git a/src/kernel/thread_manager.rs b/src/kernel/thread_manager.rs index 26911b8..0f98417 100644 --- a/src/kernel/thread_manager.rs +++ b/src/kernel/thread_manager.rs @@ -282,8 +282,47 @@ impl ThreadManager { } } - pub fn lock_release(&mut self, id: i32, machine: &mut Machine) -> Result{ - todo!() + /// Wake up a waiter if necessary, or release it if no thread is waiting. + pub fn lock_release(&mut self, id: i32, machine: &mut Machine) -> Result { + let current_thread = self.get_g_current_thread(); + match current_thread { + Some(thread) => { + let current_thread = Rc::clone(&thread); + + let mut lock_option = self.get_obj_addrs().search_lock(id).cloned(); + match lock_option { + Some(mut lock) => { + let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff); + + match &lock.owner { + Some(lock_owner) => { + if Rc::ptr_eq(¤t_thread, lock_owner) { + match lock.waiting_queue.pop() { + Some(thread) => { + lock.owner = Some(thread); + match &lock.owner { + Some(x) => self.ready_to_run(Rc::clone(x)), + None => () + } + }, + None => { + lock.free = true; + lock.owner = None; + } + } + } + }, + None => () + } + machine.interrupt.set_status(old_status); + Ok(MachineOk::Ok) + }, + None => Err("Cannot find lock")? + } + }, + None => unreachable!("Current thread should not be None") + } + } /// Currently running thread diff --git a/src/utility/list.rs b/src/utility/list.rs index adc08fa..7a90d0a 100644 --- a/src/utility/list.rs +++ b/src/utility/list.rs @@ -10,6 +10,7 @@ use std::ptr; /// but everything has been tested with miri to assure there's no Undefined Behaviour (use-after-free, double free, etc.) /// or memory leak #[derive(PartialEq)] +#[derive(Clone)] pub struct List { head: Link, tail: *mut Node,