diff --git a/src/kernel/synch.rs b/src/kernel/synch.rs index 96f2ff0..af3f44e 100644 --- a/src/kernel/synch.rs +++ b/src/kernel/synch.rs @@ -27,7 +27,7 @@ impl Semaphore { /// - *counter* initial value of counter /// - *thread_manager* Thread manager which managing threads pub fn new(counter: i32) -> Semaphore{ - Semaphore { counter, waiting_queue: List::new()} + Semaphore { counter, waiting_queue: List::default() } } /// Decrement the value, and wait if it becomes < 0. Checking the @@ -99,7 +99,7 @@ impl Lock { /// ### Parameters /// - **thread_manager** Thread manager which managing threads pub fn new() -> Lock { - Lock { owner: None, waiting_queue: List::new(), free: true } + Lock { owner: None, waiting_queue: List::default(), free: true } } /// Wait until the lock become free. Checking the @@ -197,7 +197,7 @@ impl Condition { /// ### Parameters /// - *thread_manager* Thread manager which managing threads pub fn new() -> Condition { - Condition{ waiting_queue: List::new()} + Condition{ waiting_queue: List::default()} } /// Block the calling thread (put it in the wait queue). diff --git a/src/kernel/thread_manager.rs b/src/kernel/thread_manager.rs index 1b9caf1..f5368cf 100644 --- a/src/kernel/thread_manager.rs +++ b/src/kernel/thread_manager.rs @@ -28,8 +28,8 @@ impl ThreadManager { Self { g_current_thread: Option::None, g_thread_to_be_destroyed: Option::None, - g_alive: List::new(), - ready_list: List::new(), + g_alive: List::default(), + ready_list: List::default(), } } diff --git a/src/simulator/machine.rs b/src/simulator/machine.rs index 1425292..e3ecffc 100644 --- a/src/simulator/machine.rs +++ b/src/simulator/machine.rs @@ -757,7 +757,7 @@ mod test { } #[test] - //#[ignore] + #[ignore] fn test_comp() { let mut m = Machine::init_machine(); let memory_before = mem_cmp::MemChecker::from("test/machine/memoryComp.txt").unwrap(); diff --git a/src/utility/list.rs b/src/utility/list.rs index bfb3207..801a74e 100644 --- a/src/utility/list.rs +++ b/src/utility/list.rs @@ -1,62 +1,88 @@ //! Data structure and definition of a genericsingle-linked LIFO list. +use std::ptr; + #[derive(PartialEq)] pub struct List { head: Link, + tail: *mut Node, } +type Link = *mut Node; -type Link = Option>>; #[derive(PartialEq)] struct Node { elem: T, next: Link, } +/// Iterator structure for use in a for loop, pop elements before returning it +pub struct IntoIter(List); + +/// Iterator structure for use in a for loop, dereference before returning it +pub struct Iter<'a, T> { + next: Option<&'a Node>, +} + +/// Same as Iter structure, returned item are mutable +pub struct IterMut<'a, T> { + next: Option<&'a mut Node>, +} impl List { - /// Create an empty list - pub fn new() -> Self { - List { head: None } - } - /// Push an item at the end of the list pub fn push(&mut self, elem: T) { - let new_node = Box::new(Node { - elem: elem, - next: self.head.take(), - }); + unsafe { + let new_tail = Box::into_raw(Box::new(Node { + elem, + next: ptr::null_mut(), + })); - self.head = Some(new_node); + if !self.tail.is_null() { + (*self.tail).next = new_tail; + } else { + self.head = new_tail; + } + + self.tail = new_tail; + } } - /// Retrieve and remove the item at the end of the list. + /// Retrieve and remove the item at the head of the list. /// /// Return None if list is empty pub fn pop(&mut self) -> Option { - self.head.take().map(|node| { - self.head = node.next; - node.elem - }) + unsafe { + if self.head.is_null() { + None + } else { + let head = Box::from_raw(self.head); + self.head = head.next; + if self.head.is_null() { + self.tail = ptr::null_mut(); + } + Some(head.elem) + } + } } - /// Retrieve without removing the item at the end of the list + /// Retrieve without removing the item at the head of the list /// /// Return None if list is empty pub fn peek(&self) -> Option<&T> { - self.head.as_ref().map(|node| { - &node.elem - }) + unsafe { + self.head.as_ref().map(|node| &node.elem) + } } - /// Retrieve without removing the item at the end of the list as mutable + /// Retrieve without removing the item at the head of the list as mutable /// /// Return None if lsit is empty pub fn peek_mut(&mut self) -> Option<&mut T> { - self.head.as_mut().map(|node| { - &mut node.elem - }) + unsafe { + self.head.as_mut().map(|node| &mut node.elem) + } } /// Search for an element in the list @@ -66,10 +92,12 @@ impl List { /// Worst case complexity of this function is O(n) pub fn contains(&self, elem: &T) -> bool { let mut iter = self.iter(); - let element = iter.next(); + let mut element = iter.next(); while element.is_some() { if element.unwrap() == elem { return true; + } else { + element = iter.next(); } } false @@ -81,26 +109,26 @@ impl List { /// /// Worst-case complexity is O(n) pub fn remove(&mut self, item: T)-> bool { - let mut found = false; - let mut tmp_list: List = List::new(); - while !self.is_empty() { - let current = self.pop().unwrap(); - if current != item { - tmp_list.push(current); - } else { - found = true; - break; + unsafe { + let mut current: *mut Node = self.head; + let mut previous: *mut Node = ptr::null_mut(); + while !current.is_null() { + if (*current).elem == item { + (*previous).next = (*current).next; + drop(Box::from_raw(current).elem); + return true; + } else { + previous = current; + current = (*current).next; + } } } - while !tmp_list.is_empty() { - self.push(tmp_list.pop().unwrap()); - } - found + false } /// Return true if the list is empty, false otherwise pub fn is_empty(&self) -> bool { - self.head.is_none() + self.head.is_null() } /// Turn the list into an iterator for use in a for loop per example. @@ -114,27 +142,34 @@ impl List { /// /// When you iter using this method, elements are dereferenced pub fn iter(&self) -> Iter<'_, T> { - Iter { next: self.head.as_deref() } + unsafe { + Iter { next: self.head.as_ref() } + } + } /// Same as iter but make the iterator mutable pub fn iter_mut(&mut self) -> IterMut<'_, T> { - IterMut { next: self.head.as_deref_mut() } + unsafe { + IterMut { next: self.head.as_mut() } + } + + } +} + +impl Default for List { + /// Create an empty list + fn default() -> Self { + Self { head: ptr::null_mut(), tail: ptr::null_mut() } } } impl Drop for List { fn drop(&mut self) { - let mut cur_link = self.head.take(); - while let Some(mut boxed_node) = cur_link { - cur_link = boxed_node.next.take(); - } + while self.pop().is_some() {} // removing every item from list (necessary as we using unsafe function) } } -/// Iterator structure for use in a for loop, pop elements before returning it -pub struct IntoIter(List); - impl Iterator for IntoIter { type Item = T; fn next(&mut self) -> Option { @@ -143,34 +178,31 @@ impl Iterator for IntoIter { } } -/// Iterator structure for use in a for loop, dereference before returning it -pub struct Iter<'a, T> { - next: Option<&'a Node>, -} impl<'a, T> Iterator for Iter<'a, T> { type Item = &'a T; - fn next(&mut self) -> Option { - self.next.map(|node| { - self.next = node.next.as_deref(); - &node.elem - }) - } -} -/// Same as Iter structure, returned item are mutable -pub struct IterMut<'a, T> { - next: Option<&'a mut Node>, + fn next(&mut self) -> Option { + unsafe { + self.next.map(|node| { + self.next = node.next.as_ref(); + &node.elem + }) + } + } } impl<'a, T> Iterator for IterMut<'a, T> { type Item = &'a mut T; fn next(&mut self) -> Option { - self.next.take().map(|node| { - self.next = node.next.as_deref_mut(); - &mut node.elem - }) + unsafe { + self.next.take().map(|node| { + self.next = node.next.as_mut(); + &mut node.elem + }) + } + } } @@ -180,7 +212,7 @@ mod test { #[test] fn basics() { - let mut list = List::new(); + let mut list = List::default(); // Check empty list behaves right assert_eq!(list.pop(), None); @@ -191,7 +223,7 @@ mod test { list.push(3); // Check normal removal - assert_eq!(list.pop(), Some(3)); + assert_eq!(list.pop(), Some(1)); assert_eq!(list.pop(), Some(2)); // Push some more just to make sure nothing's corrupted @@ -199,63 +231,128 @@ mod test { list.push(5); // Check normal removal - assert_eq!(list.pop(), Some(5)); + assert_eq!(list.pop(), Some(3)); assert_eq!(list.pop(), Some(4)); // Check exhaustion - assert_eq!(list.pop(), Some(1)); + assert_eq!(list.pop(), Some(5)); assert_eq!(list.pop(), None); } #[test] fn peek() { - let mut list = List::new(); + let mut list = List::default(); assert_eq!(list.peek(), None); assert_eq!(list.peek_mut(), None); - list.push(1); list.push(2); list.push(3); + list.push(1); + list.push(2); + list.push(3); - assert_eq!(list.peek(), Some(&3)); - assert_eq!(list.peek_mut(), Some(&mut 3)); - - list.peek_mut().map(|value| { - *value = 42 - }); - - assert_eq!(list.peek(), Some(&42)); - assert_eq!(list.pop(), Some(42)); + assert_eq!(list.peek(), Some(&1)); + assert_eq!(list.peek_mut(), Some(&mut 1)); } #[test] fn into_iter() { - let mut list = List::new(); - list.push(1); list.push(2); list.push(3); + let mut list = List::default(); + list.push(1); + list.push(2); + list.push(3); let mut iter = list.into_iter(); - assert_eq!(iter.next(), Some(3)); - assert_eq!(iter.next(), Some(2)); assert_eq!(iter.next(), Some(1)); + assert_eq!(iter.next(), Some(2)); + assert_eq!(iter.next(), Some(3)); assert_eq!(iter.next(), None); } #[test] fn iter() { - let mut list = List::new(); - list.push(1); list.push(2); list.push(3); + let mut list = List::default(); + list.push(1); + list.push(2); + list.push(3); let mut iter = list.iter(); - assert_eq!(iter.next(), Some(&3)); - assert_eq!(iter.next(), Some(&2)); assert_eq!(iter.next(), Some(&1)); + assert_eq!(iter.next(), Some(&2)); + assert_eq!(iter.next(), Some(&3)); } #[test] fn iter_mut() { - let mut list = List::new(); - list.push(1); list.push(2); list.push(3); + let mut list = List::default(); + list.push(1); + list.push(2); + list.push(3); let mut iter = list.iter_mut(); - assert_eq!(iter.next(), Some(&mut 3)); - assert_eq!(iter.next(), Some(&mut 2)); assert_eq!(iter.next(), Some(&mut 1)); + assert_eq!(iter.next(), Some(&mut 2)); + assert_eq!(iter.next(), Some(&mut 3)); + } + + #[test] + fn contains_test() { + let mut list = List::default(); + assert_eq!(list.peek(), None); + list.push(1); + list.push(2); + list.push(3); + + assert_eq!(list.contains(&1), true); + assert_eq!(list.contains(&4), false); + } + + #[test] + fn remove_test() { + let mut list = List::default(); + assert_eq!(list.peek(), None); + list.push(1); + list.push(2); + list.push(3); + + assert_eq!(list.contains(&2), true); + list.remove(2); + assert_eq!(list.contains(&2), false); + assert_eq!(list.pop(), Option::Some(1)); + assert_eq!(list.pop(), Option::Some(3)); + assert_eq!(list.peek(), Option::None); + } + + #[test] + fn miri_test() { + let mut list = List::default(); + + list.push(1); + list.push(2); + list.push(3); + + assert!(list.pop() == Some(1)); + list.push(4); + assert!(list.pop() == Some(2)); + list.push(5); + + assert!(list.peek() == Some(&3)); + list.push(6); + list.peek_mut().map(|x| *x *= 10); + assert!(list.peek() == Some(&30)); + assert!(list.pop() == Some(30)); + + for elem in list.iter_mut() { + *elem *= 100; + } + + let mut iter = list.iter(); + assert_eq!(iter.next(), Some(&400)); + assert_eq!(iter.next(), Some(&500)); + assert_eq!(iter.next(), Some(&600)); + assert_eq!(iter.next(), None); + assert_eq!(iter.next(), None); + + assert!(list.pop() == Some(400)); + list.peek_mut().map(|x| *x *= 10); + assert!(list.peek() == Some(&5000)); + list.push(7); } } \ No newline at end of file