From 470d5692febd332803a31c02730de02389b992ce Mon Sep 17 00:00:00 2001 From: WangRunji Date: Thu, 19 Apr 2018 15:28:32 +0800 Subject: [PATCH] Pass test for FifoSwapManager. Change interface. --- crate/memory/src/swap/fifo.rs | 15 +++++++------ crate/memory/src/swap/mock_page_table.rs | 28 ++++++++++++++++-------- crate/memory/src/swap/mod.rs | 4 ++-- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/crate/memory/src/swap/fifo.rs b/crate/memory/src/swap/fifo.rs index 8a91f52..4a006ee 100644 --- a/crate/memory/src/swap/fifo.rs +++ b/crate/memory/src/swap/fifo.rs @@ -22,14 +22,14 @@ impl SwapManager for FifoSwapManager { self.deque.push_back(addr); } - fn pop(&mut self, addr: usize) { + fn remove(&mut self, addr: usize) { let id = self.deque.iter() .position(|&x| x == addr) .expect("address not found"); self.deque.remove(id); } - fn swap(&mut self) -> Option { + fn pop(&mut self) -> Option { self.deque.pop_front() } } @@ -52,19 +52,20 @@ mod test { static mut PAGE: *mut MockPageTable = 0 as *mut _; static mut FIFO: *mut FifoSwapManager = 0 as *mut _; - fn pgfault_handler(pt: &mut MockPageTable, addr: Addr) { + fn page_fault_handler(pt: &mut MockPageTable, addr: Addr) { unsafe{ PGFAULT_COUNT += 1; } let fifo = unsafe{ &mut *FIFO }; - if let Some(x) = fifo.swap() { - pt.unmap(x); + if !pt.map(addr) { // is full? + pt.unmap(fifo.pop().unwrap()); + pt.map(addr); } - pt.map(addr); + fifo.push(addr); } #[test] fn test() { use self::MemOp::{R, W}; - let mut pt = MockPageTable::new(pgfault_handler); + let mut pt = MockPageTable::new(4, page_fault_handler); let mut fifo = FifoSwapManager::::new( unsafe{ &*(&pt as *const _) }); unsafe { diff --git a/crate/memory/src/swap/mock_page_table.rs b/crate/memory/src/swap/mock_page_table.rs index ba5185f..b3f0088 100644 --- a/crate/memory/src/swap/mock_page_table.rs +++ b/crate/memory/src/swap/mock_page_table.rs @@ -5,10 +5,11 @@ pub struct MockPageTable { mapped_set: BTreeSet, accessed_set: BTreeSet, dirty_set: BTreeSet, - pgfault_handler: PgfaultHandler, + page_fault_handler: PageFaultHandler, + capacity: usize, } -type PgfaultHandler = fn(&mut MockPageTable, Addr); +type PageFaultHandler = fn(&mut MockPageTable, Addr); impl PageTable for MockPageTable { fn accessed(&self, addr: Addr) -> bool { @@ -20,18 +21,19 @@ impl PageTable for MockPageTable { } impl MockPageTable { - pub fn new(pgfault_handler: PgfaultHandler) -> Self { + pub fn new(capacity: usize, page_fault_handler: PageFaultHandler) -> Self { MockPageTable { mapped_set: BTreeSet::::new(), accessed_set: BTreeSet::::new(), dirty_set: BTreeSet::::new(), - pgfault_handler, + page_fault_handler, + capacity, } } /// Read memory, mark accessed, trigger page fault if not present pub fn read(&mut self, addr: Addr) { while !self.mapped_set.contains(&addr) { - (self.pgfault_handler)(self, addr); + (self.page_fault_handler)(self, addr); } self.accessed_set.insert(addr); @@ -39,14 +41,20 @@ impl MockPageTable { /// Write memory, mark accessed and dirty, trigger page fault if not present pub fn write(&mut self, addr: Addr) { while !self.mapped_set.contains(&addr) { - (self.pgfault_handler)(self, addr); + (self.page_fault_handler)(self, addr); } self.accessed_set.insert(addr); self.dirty_set.insert(addr); } - pub fn map(&mut self, addr: Addr) { + /// Map a page, return false if no more space + pub fn map(&mut self, addr: Addr) -> bool { + if self.mapped_set.len() == self.capacity { + return false; + } self.mapped_set.insert(addr); + true } + /// Unmap a page pub fn unmap(&mut self, addr: Addr) { self.mapped_set.remove(&addr); } @@ -64,11 +72,11 @@ mod test { #[test] fn test() { - fn pgfault_handler(pt: &mut MockPageTable, addr: Addr) { + fn page_fault_handler(pt: &mut MockPageTable, addr: Addr) { unsafe{ PGFAULT_COUNT += 1; } pt.map(addr); } - let mut pt = MockPageTable::new(pgfault_handler); + let mut pt = MockPageTable::new(2, page_fault_handler); pt.map(0); pt.read(0); @@ -81,6 +89,8 @@ mod test { assert!(pt.accessed(1)); assert!(pt.dirty(1)); + assert_eq!(pt.map(2), false); + pt.unmap(0); pt.read(0); assert_pgfault_eq(2); diff --git a/crate/memory/src/swap/mod.rs b/crate/memory/src/swap/mod.rs index badc394..80b1e5a 100644 --- a/crate/memory/src/swap/mod.rs +++ b/crate/memory/src/swap/mod.rs @@ -11,9 +11,9 @@ trait SwapManager { /// Called when map a swappable page into the memory fn push(&mut self, addr: Addr); /// Called to delete the addr entry from the swap manager - fn pop(&mut self, addr: Addr); + fn remove(&mut self, addr: Addr); /// Try to swap out a page, return then victim - fn swap(&mut self) -> Option; + fn pop(&mut self) -> Option; } trait PageTable {