From 9d19f0630bcdbf4260fa1976987b00562b02ee2c Mon Sep 17 00:00:00 2001 From: Samy Solhi Date: Wed, 22 Mar 2023 14:59:28 +0100 Subject: [PATCH] Fix Semaphore and Lock tests --- src/kernel/synch.rs | 243 ++++++++++++++++++++++---------------------- 1 file changed, 123 insertions(+), 120 deletions(-) diff --git a/src/kernel/synch.rs b/src/kernel/synch.rs index 6ce265b..96f2ff0 100644 --- a/src/kernel/synch.rs +++ b/src/kernel/synch.rs @@ -1,3 +1,4 @@ +use crate::kernel::thread_manager; use crate::utility::list::List; use crate::kernel::thread::Thread; use crate::simulator::interrupt::InterruptStatus::InterruptOff; @@ -66,13 +67,13 @@ impl Semaphore { /// ### Parameters /// - **machine** the machine where the threads are executed /// - **scheduler** the scheduler which determine which thread to execute - pub fn v(&mut self, system: &mut System){ - let old_status = system.get_machine().interrupt.set_status(InterruptOff); + pub fn v(&mut self, machine: &mut Machine, thread_manager: &mut ThreadManager){ + let old_status = machine.interrupt.set_status(InterruptOff); self.counter += 1; if self.waiting_queue.peek() != None { - system.get_thread_manager().ready_to_run(self.waiting_queue.pop().unwrap()); + thread_manager.ready_to_run(self.waiting_queue.pop().unwrap()); } - system.get_machine().interrupt.set_status(old_status); + machine.interrupt.set_status(old_status); } } @@ -145,16 +146,16 @@ impl Lock { /// ### Parameters /// - **machine** the machine where the code is executed /// - **scheduler** the scheduler which determine which thread to execute - pub fn release(&mut self, system: &mut System) { - let old_status = system.get_machine().interrupt.set_status(InterruptOff); + pub fn release(&mut self, machine: &mut Machine, thread_manager: &mut ThreadManager) { + let old_status = machine.interrupt.set_status(InterruptOff); - match system.get_thread_manager().get_g_current_thread() { + match thread_manager.get_g_current_thread() { Some(thread) => { - if self.held_by_current_thread(system) { + if self.held_by_current_thread(thread_manager) { if self.waiting_queue.peek() != None { self.owner = Some(self.waiting_queue.pop().unwrap()); match &self.owner { - Some(x) => system.get_thread_manager().ready_to_run(Rc::clone(&x)), + Some(x) => thread_manager.ready_to_run(Rc::clone(&x)), None => () } } else { @@ -166,13 +167,13 @@ impl Lock { None => () } - system.get_machine().interrupt.set_status(old_status); + machine.interrupt.set_status(old_status); } - pub fn held_by_current_thread(&mut self, system: &mut System) -> bool { + pub fn held_by_current_thread(&mut self, thread_manager: &mut ThreadManager) -> bool { match &self.owner { Some(x) => - match system.get_thread_manager().get_g_current_thread() { + match thread_manager.get_g_current_thread() { Some(thread) => Rc::ptr_eq(&x, &thread), None => false } @@ -255,132 +256,134 @@ impl Condition { } -// #[cfg(test)] -// mod test { -// use std::{rc::Rc, cell::RefCell}; +#[cfg(test)] +mod test { + use std::{rc::Rc, cell::RefCell}; -// use crate::{kernel::{thread::Thread, synch::{Semaphore, Lock}}, init_system, simulator::machine::Machine}; + use crate::{kernel::{thread::Thread, synch::{Semaphore, Lock}, thread_manager::ThreadManager}, init_system, simulator::machine::Machine}; -// #[test] -// fn test_semaphore_single() { -// // Init -// let system = init_system!(); -// let mut semaphore = Semaphore::new(1); -// let thread = Rc::new(RefCell::new(Thread::new("test_semaphore"))); -// // P -// semaphore.p(system, thread); -// assert_eq!(semaphore.counter, 0); -// assert!(semaphore.waiting_queue.is_empty()); -// // V -// semaphore.v(Rc::clone(&system)); -// assert_eq!(semaphore.counter, 1); -// assert!(semaphore.waiting_queue.is_empty()); -// } + #[test] + fn test_semaphore_single() { + // Init + let mut machine = Machine::init_machine(); + let mut thread_manager = ThreadManager::new(); + let mut semaphore = Semaphore::new(1); + let thread = Rc::new(RefCell::new(Thread::new("test_semaphore"))); + thread_manager.ready_to_run(Rc::clone(&thread)); + thread_manager.set_g_current_thread(Some(thread)); + // P + semaphore.p(&mut machine, &mut thread_manager); + assert_eq!(semaphore.counter, 0); + assert!(semaphore.waiting_queue.is_empty()); + // V + semaphore.v(&mut machine, &mut thread_manager); + assert_eq!(semaphore.counter, 1); + assert!(semaphore.waiting_queue.is_empty()); + } -// #[test] -// #[ignore] -// fn test_semaphore_multiple() { -// // Init -// let system = init_system!(); -// let tm = system.borrow_mut().get_thread_manager(); -// let mut semaphore = Semaphore::new(2, Rc::clone(&tm)); -// let thread1 = Rc::new(RefCell::new(Thread::new("test_semaphore_1"))); -// let thread2 = Rc::new(RefCell::new(Thread::new("test_semaphore_2"))); -// let thread3 = Rc::new(RefCell::new(Thread::new("test_semaphore_3"))); + #[test] + fn test_semaphore_multiple() { + // Init + let mut tm = ThreadManager::new(); + let mut machine = Machine::init_machine(); + let mut semaphore = Semaphore::new(2); + let thread1 = Rc::new(RefCell::new(Thread::new("test_semaphore_1"))); + let thread2 = Rc::new(RefCell::new(Thread::new("test_semaphore_2"))); + let thread3 = Rc::new(RefCell::new(Thread::new("test_semaphore_3"))); -// let mut borrow_tm = tm.borrow_mut(); -// let scheduler = &mut borrow_tm.g_scheduler; -// scheduler.ready_to_run(Rc::clone(&thread1)); -// scheduler.ready_to_run(Rc::clone(&thread2)); -// scheduler.ready_to_run(Rc::clone(&thread3)); -// // P -// borrow_tm.set_g_current_thread(Some(Rc::clone(&thread1))); -// semaphore.p(thread1, Rc::clone(&system)); -// assert_eq!(semaphore.counter, 1); -// assert!(semaphore.waiting_queue.is_empty()); + // let mut borrow_tm = tm.borrow_mut(); + // let scheduler = &mut tm.g_scheduler; + tm.ready_to_run(Rc::clone(&thread1)); + tm.ready_to_run(Rc::clone(&thread2)); + tm.ready_to_run(Rc::clone(&thread3)); + // P + tm.set_g_current_thread(Some(Rc::clone(&thread1))); + semaphore.p(&mut machine, &mut tm); + assert_eq!(semaphore.counter, 1); + assert!(semaphore.waiting_queue.is_empty()); -// borrow_tm.set_g_current_thread(Some(Rc::clone(&thread2))); -// semaphore.p(thread2, Rc::clone(&system)); -// assert_eq!(semaphore.counter, 0); -// assert!(semaphore.waiting_queue.is_empty()); + tm.set_g_current_thread(Some(Rc::clone(&thread2))); + semaphore.p(&mut machine, &mut tm); + assert_eq!(semaphore.counter, 0); + assert!(semaphore.waiting_queue.is_empty()); -// borrow_tm.set_g_current_thread(Some(Rc::clone(&thread3))); -// semaphore.p(thread3, Rc::clone(&system)); -// assert_eq!(semaphore.counter, -1); -// assert!(semaphore.waiting_queue.iter().count() == 1); + tm.set_g_current_thread(Some(Rc::clone(&thread3))); + semaphore.p(&mut machine, &mut tm); + assert_eq!(semaphore.counter, -1); + assert!(semaphore.waiting_queue.iter().count() == 1); -// // V -// semaphore.v(Rc::clone(&system)); -// assert_eq!(semaphore.counter, 0); -// assert!(semaphore.waiting_queue.is_empty()); + // V + semaphore.v(&mut machine, &mut tm); + assert_eq!(semaphore.counter, 0); + assert!(semaphore.waiting_queue.is_empty()); -// semaphore.v(Rc::clone(&system)); -// assert_eq!(semaphore.counter, 1); -// assert!(semaphore.waiting_queue.is_empty()); + semaphore.v(&mut machine, &mut tm); + assert_eq!(semaphore.counter, 1); + assert!(semaphore.waiting_queue.is_empty()); -// semaphore.v(Rc::clone(&system)); -// assert_eq!(semaphore.counter, 2); -// assert!(semaphore.waiting_queue.is_empty()); -// } + semaphore.v(&mut machine, &mut tm); + assert_eq!(semaphore.counter, 2); + assert!(semaphore.waiting_queue.is_empty()); + } -// #[test] -// #[ignore] -// fn test_lock_simple() { -// let system = init_system!(); -// let sys = system.borrow_mut(); -// let tm = sys.get_thread_manager(); -// let thread = Rc::new(RefCell::new(Thread::new("test_lock"))); -// tm.borrow_mut().set_g_current_thread(Some(Rc::clone(&thread))); -// let mut lock = Lock::new(Rc::clone(&tm)); + #[test] + fn test_lock_simple() { + let mut machine = Machine::init_machine(); + let mut tm = ThreadManager::new(); + let thread = Rc::new(RefCell::new(Thread::new("test_lock"))); + tm.ready_to_run(Rc::clone(&thread)); + tm.set_g_current_thread(Some(Rc::clone(&thread))); + let mut lock = Lock::new(); -// assert!(lock.free); -// lock.acquire(Some(Rc::clone(&thread)), Rc::clone(&system)); -// assert!(lock.held_by_current_thread(Rc::clone(&thread))); + assert!(lock.free); + lock.acquire(&mut machine, &mut tm); + assert!(lock.held_by_current_thread(&mut tm)); -// assert!(!lock.free); -// lock.release(Rc::clone(&system), Rc::clone(&thread)); -// assert!(!lock.held_by_current_thread(thread)); -// assert!(lock.free); -// } + assert!(!lock.free); + lock.release(&mut machine, &mut tm); + assert!(!lock.held_by_current_thread(&mut tm)); + assert!(lock.free); + } -// #[test] -// #[ignore] -// fn test_lock_multiple() { -// let system = init_system!(); -// let thread1 = Rc::new(RefCell::new(Thread::new("test_lock1"))); -// let thread2 = Rc::new(RefCell::new(Thread::new("test_lock2"))); -// let thread3 = Rc::new(RefCell::new(Thread::new("test_lock3"))); - -// let tm = system.borrow_mut().get_thread_manager(); -// tm.borrow_mut().set_g_current_thread(Some(Rc::clone(&thread1))); -// let mut lock = Lock::new(Rc::clone(&tm)); - -// assert!(lock.free); -// lock.acquire(Some(Rc::clone(&thread1)), Rc::clone(&system)); -// assert!(lock.held_by_current_thread(Rc::clone(&thread1))); -// assert!(!lock.free); - -// tm.borrow_mut().set_g_current_thread(Some(Rc::clone(&thread2))); -// lock.acquire(Some(Rc::clone(&thread2)), Rc::clone(&system)); -// tm.borrow_mut().set_g_current_thread(Some(Rc::clone(&thread1))); + #[test] + fn test_lock_multiple() { + let thread1 = Rc::new(RefCell::new(Thread::new("test_lock1"))); + let thread2 = Rc::new(RefCell::new(Thread::new("test_lock2"))); + let mut machine = Machine::init_machine(); + let mut tm = ThreadManager::new(); -// assert!(lock.held_by_current_thread(Rc::clone(&thread1))); -// assert!(lock.waiting_queue.iter().count() == 1); -// assert!(!lock.free); + tm.ready_to_run(Rc::clone(&thread1)); + tm.ready_to_run(Rc::clone(&thread2)); -// lock.release(Rc::clone(&system), Rc::clone(&thread1)); -// assert!(!lock.held_by_current_thread(thread1)); -// assert!(lock.held_by_current_thread(Rc::clone(&thread2))); -// assert!(!lock.free); + tm.set_g_current_thread(Some(Rc::clone(&thread1))); + let mut lock = Lock::new(); -// tm.borrow_mut().set_g_current_thread(Some(Rc::clone(&thread2))); + assert!(lock.free); + lock.acquire(&mut machine, &mut tm); + assert!(lock.held_by_current_thread(&mut tm)); + assert!(!lock.free); + tm.set_g_current_thread(Some(Rc::clone(&thread2))); + lock.acquire(&mut machine, &mut tm); + + + tm.set_g_current_thread(Some(Rc::clone(&thread1))); + assert!(lock.held_by_current_thread(&mut tm)); + assert!(lock.waiting_queue.iter().count() == 1); + assert!(!lock.free); -// lock.release(Rc::clone(&system), Rc::clone(&thread2)); -// assert!(!lock.held_by_current_thread(thread2)); -// assert!(lock.free); -// } -// } \ No newline at end of file + lock.release(&mut machine, &mut tm); + assert!(!lock.held_by_current_thread(&mut tm)); + + tm.set_g_current_thread(Some(Rc::clone(&thread2))); + assert!(lock.held_by_current_thread(&mut tm)); + assert!(!lock.free); + + lock.release(&mut machine, &mut tm); + assert!(!lock.held_by_current_thread(&mut tm)); + assert!(lock.free); + } +} \ No newline at end of file