From c0d83ef75bda2e5a9a41c384d9b8bfc8da6904cd Mon Sep 17 00:00:00 2001 From: WangRunji Date: Wed, 25 Apr 2018 13:50:31 +0800 Subject: [PATCH] Make tests safe, by using Arc & RefCell. --- .../memory/src/page_table/mock_page_table.rs | 38 ++++++----- crate/memory/src/swap/fifo.rs | 67 +++++++++---------- crate/memory/src/swap/mod.rs | 4 +- 3 files changed, 51 insertions(+), 58 deletions(-) diff --git a/crate/memory/src/page_table/mock_page_table.rs b/crate/memory/src/page_table/mock_page_table.rs index b26e6c0..bf5f50d 100644 --- a/crate/memory/src/page_table/mock_page_table.rs +++ b/crate/memory/src/page_table/mock_page_table.rs @@ -1,4 +1,4 @@ -use alloc::btree_set::BTreeSet; +use alloc::{boxed::Box, btree_set::BTreeSet}; use super::*; pub struct MockPageTable { @@ -9,7 +9,7 @@ pub struct MockPageTable { capacity: usize, } -type PageFaultHandler = fn(&mut MockPageTable, VirtAddr); +type PageFaultHandler = Box; impl PageTable for MockPageTable { fn accessed(&self, addr: VirtAddr) -> bool { @@ -44,7 +44,8 @@ impl MockPageTable { /// Read memory, mark accessed, trigger page fault if not present pub fn read(&mut self, addr: VirtAddr) { while !self.mapped_set.contains(&addr) { - (self.page_fault_handler)(self, addr); + let self_mut = unsafe{ &mut *(self as *mut Self) }; + (self.page_fault_handler)(self_mut, addr); } self.accessed_set.insert(addr); @@ -52,7 +53,8 @@ impl MockPageTable { /// Write memory, mark accessed and dirty, trigger page fault if not present pub fn write(&mut self, addr: VirtAddr) { while !self.mapped_set.contains(&addr) { - (self.page_fault_handler)(self, addr); + let self_mut = unsafe{ &mut *(self as *mut Self) }; + (self.page_fault_handler)(self_mut, addr); } self.accessed_set.insert(addr); self.dirty_set.insert(addr); @@ -62,29 +64,29 @@ impl MockPageTable { #[cfg(test)] mod test { use super::*; - - static mut PGFAULT_COUNT: usize = 0; - - fn assert_pgfault_eq(x: usize) { - assert_eq!(unsafe{ PGFAULT_COUNT }, x); - } + use alloc::arc::Arc; + use core::cell::RefCell; #[test] fn test() { - fn page_fault_handler(pt: &mut MockPageTable, addr: VirtAddr) { - unsafe{ PGFAULT_COUNT += 1; } - pt.map(addr); - } - let mut pt = MockPageTable::new(2, page_fault_handler); + let page_fault_count = Arc::new(RefCell::new(0usize)); + + let mut pt = MockPageTable::new(2, Box::new({ + let page_fault_count1 = page_fault_count.clone(); + move |pt: &mut MockPageTable, addr: VirtAddr| { + *page_fault_count1.borrow_mut() += 1; + pt.map(addr); + } + })); pt.map(0); pt.read(0); - assert_pgfault_eq(0); + assert_eq!(*page_fault_count.borrow(), 0); assert!(pt.accessed(0)); assert!(!pt.dirty(0)); pt.write(1); - assert_pgfault_eq(1); + assert_eq!(*page_fault_count.borrow(), 1); assert!(pt.accessed(1)); assert!(pt.dirty(1)); @@ -92,6 +94,6 @@ mod test { pt.unmap(0); pt.read(0); - assert_pgfault_eq(2); + assert_eq!(*page_fault_count.borrow(), 2); } } \ No newline at end of file diff --git a/crate/memory/src/swap/fifo.rs b/crate/memory/src/swap/fifo.rs index fd7c912..daa796f 100644 --- a/crate/memory/src/swap/fifo.rs +++ b/crate/memory/src/swap/fifo.rs @@ -1,19 +1,11 @@ use alloc::vec_deque::VecDeque; use super::*; -struct FifoSwapManager { - page_table: &'static T, +struct FifoSwapManager { deque: VecDeque, } -impl SwapManager for FifoSwapManager { - fn new(page_table: &'static T) -> Self { - FifoSwapManager { - page_table, - deque: VecDeque::::new() - } - } - +impl SwapManager for FifoSwapManager { fn tick(&mut self) { } @@ -34,44 +26,45 @@ impl SwapManager for FifoSwapManager { } } +impl FifoSwapManager { + fn new() -> Self { + FifoSwapManager { + deque: VecDeque::::new() + } + } +} + #[cfg(test)] mod test { use super::*; + use alloc::{arc::Arc, boxed::Box}; + use core::cell::RefCell; use page_table::mock_page_table::MockPageTable; enum MemOp { R(usize), W(usize) } - fn assert_pgfault_eq(x: usize) { - assert_eq!(unsafe{ PGFAULT_COUNT }, x); - } - - // For pgfault_handler: - static mut PGFAULT_COUNT: usize = 0; - static mut PAGE: *mut MockPageTable = 0 as *mut _; - static mut FIFO: *mut FifoSwapManager = 0 as *mut _; - - fn page_fault_handler(pt: &mut MockPageTable, addr: VirtAddr) { - unsafe{ PGFAULT_COUNT += 1; } - let fifo = unsafe{ &mut *FIFO }; - if !pt.map(addr) { // is full? - pt.unmap(fifo.pop().unwrap()); - pt.map(addr); - } - fifo.push(addr); - } - #[test] fn test() { use self::MemOp::{R, W}; - let mut pt = MockPageTable::new(4, page_fault_handler); - let mut fifo = FifoSwapManager::::new( - unsafe{ &*(&pt as *const _) }); - unsafe { - PAGE = &mut pt as *mut _; - FIFO = &mut fifo as *mut _; - } + let page_fault_count = Arc::new(RefCell::new(0usize)); + + let mut pt = MockPageTable::new(4, Box::new({ + let page_fault_count1 = page_fault_count.clone(); + let mut fifo = FifoSwapManager::new(); + + move |pt: &mut MockPageTable, addr: VirtAddr| { + *page_fault_count1.borrow_mut() += 1; + + if !pt.map(addr) { // is full? + pt.unmap(fifo.pop().unwrap()); + pt.map(addr); + } + fifo.push(addr); + } + })); + let op_seq = [ R(1), R(2), R(3), R(4), W(3), W(1), W(4), W(2), W(5), @@ -87,7 +80,7 @@ mod test { R(addr) => pt.read(*addr), W(addr) => pt.write(*addr), } - assert_pgfault_eq(count); + assert_eq!(*(*page_fault_count).borrow(), count); } } } \ No newline at end of file diff --git a/crate/memory/src/swap/mod.rs b/crate/memory/src/swap/mod.rs index 6d1c350..6adaa6b 100644 --- a/crate/memory/src/swap/mod.rs +++ b/crate/memory/src/swap/mod.rs @@ -4,9 +4,7 @@ use super::page_table::PageTable; pub mod fifo; mod mock_swapper; -trait SwapManager { - /// Create and initialize for the swap manager - fn new(page_table: &'static T) -> Self; +trait SwapManager { /// Called when tick interrupt occured fn tick(&mut self); /// Called when map a swappable page into the memory