mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-23 00:16:17 +04:00
New page_table mod. Addr -> VirtAddr.
This commit is contained in:
parent
8d304da4b4
commit
e5e27db4ec
@ -4,4 +4,7 @@
|
||||
extern crate alloc;
|
||||
|
||||
pub mod memory_set;
|
||||
pub mod swap;
|
||||
pub mod swap;
|
||||
pub mod page_table;
|
||||
|
||||
type VirtAddr = usize;
|
@ -2,36 +2,47 @@ use alloc::btree_set::BTreeSet;
|
||||
use super::*;
|
||||
|
||||
pub struct MockPageTable {
|
||||
mapped_set: BTreeSet<Addr>,
|
||||
accessed_set: BTreeSet<Addr>,
|
||||
dirty_set: BTreeSet<Addr>,
|
||||
mapped_set: BTreeSet<VirtAddr>,
|
||||
accessed_set: BTreeSet<VirtAddr>,
|
||||
dirty_set: BTreeSet<VirtAddr>,
|
||||
page_fault_handler: PageFaultHandler,
|
||||
capacity: usize,
|
||||
}
|
||||
|
||||
type PageFaultHandler = fn(&mut MockPageTable, Addr);
|
||||
type PageFaultHandler = fn(&mut MockPageTable, VirtAddr);
|
||||
|
||||
impl PageTable for MockPageTable {
|
||||
fn accessed(&self, addr: Addr) -> bool {
|
||||
fn accessed(&self, addr: VirtAddr) -> bool {
|
||||
self.accessed_set.contains(&addr)
|
||||
}
|
||||
fn dirty(&self, addr: Addr) -> bool {
|
||||
fn dirty(&self, addr: VirtAddr) -> bool {
|
||||
self.dirty_set.contains(&addr)
|
||||
}
|
||||
/// Map a page, return false if no more space
|
||||
fn map(&mut self, addr: VirtAddr) -> bool {
|
||||
if self.mapped_set.len() == self.capacity {
|
||||
return false;
|
||||
}
|
||||
self.mapped_set.insert(addr);
|
||||
true
|
||||
}
|
||||
fn unmap(&mut self, addr: VirtAddr) {
|
||||
self.mapped_set.remove(&addr);
|
||||
}
|
||||
}
|
||||
|
||||
impl MockPageTable {
|
||||
pub fn new(capacity: usize, page_fault_handler: PageFaultHandler) -> Self {
|
||||
MockPageTable {
|
||||
mapped_set: BTreeSet::<Addr>::new(),
|
||||
accessed_set: BTreeSet::<Addr>::new(),
|
||||
dirty_set: BTreeSet::<Addr>::new(),
|
||||
mapped_set: BTreeSet::<VirtAddr>::new(),
|
||||
accessed_set: BTreeSet::<VirtAddr>::new(),
|
||||
dirty_set: BTreeSet::<VirtAddr>::new(),
|
||||
page_fault_handler,
|
||||
capacity,
|
||||
}
|
||||
}
|
||||
/// Read memory, mark accessed, trigger page fault if not present
|
||||
pub fn read(&mut self, addr: Addr) {
|
||||
pub fn read(&mut self, addr: VirtAddr) {
|
||||
while !self.mapped_set.contains(&addr) {
|
||||
(self.page_fault_handler)(self, addr);
|
||||
}
|
||||
@ -39,25 +50,13 @@ impl MockPageTable {
|
||||
|
||||
}
|
||||
/// Write memory, mark accessed and dirty, trigger page fault if not present
|
||||
pub fn write(&mut self, addr: Addr) {
|
||||
pub fn write(&mut self, addr: VirtAddr) {
|
||||
while !self.mapped_set.contains(&addr) {
|
||||
(self.page_fault_handler)(self, addr);
|
||||
}
|
||||
self.accessed_set.insert(addr);
|
||||
self.dirty_set.insert(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);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -72,7 +71,7 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
fn page_fault_handler(pt: &mut MockPageTable, addr: Addr) {
|
||||
fn page_fault_handler(pt: &mut MockPageTable, addr: VirtAddr) {
|
||||
unsafe{ PGFAULT_COUNT += 1; }
|
||||
pt.map(addr);
|
||||
}
|
10
crate/memory/src/page_table/mod.rs
Normal file
10
crate/memory/src/page_table/mod.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use super::*;
|
||||
|
||||
pub mod mock_page_table;
|
||||
|
||||
pub trait PageTable {
|
||||
fn accessed(&self, addr: VirtAddr) -> bool;
|
||||
fn dirty(&self, addr: VirtAddr) -> bool;
|
||||
fn map(&mut self, addr: VirtAddr) -> bool;
|
||||
fn unmap(&mut self, addr: VirtAddr);
|
||||
}
|
@ -3,14 +3,14 @@ use super::*;
|
||||
|
||||
struct FifoSwapManager<T: 'static + PageTable> {
|
||||
page_table: &'static T,
|
||||
deque: VecDeque<Addr>,
|
||||
deque: VecDeque<VirtAddr>,
|
||||
}
|
||||
|
||||
impl<T: 'static + PageTable> SwapManager<T> for FifoSwapManager<T> {
|
||||
fn new(page_table: &'static T) -> Self {
|
||||
FifoSwapManager {
|
||||
page_table,
|
||||
deque: VecDeque::<Addr>::new()
|
||||
deque: VecDeque::<VirtAddr>::new()
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ impl<T: 'static + PageTable> SwapManager<T> for FifoSwapManager<T> {
|
||||
self.deque.remove(id);
|
||||
}
|
||||
|
||||
fn pop(&mut self) -> Option<Addr> {
|
||||
fn pop(&mut self) -> Option<VirtAddr> {
|
||||
self.deque.pop_front()
|
||||
}
|
||||
}
|
||||
@ -37,7 +37,7 @@ impl<T: 'static + PageTable> SwapManager<T> for FifoSwapManager<T> {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use super::mock_page_table::MockPageTable;
|
||||
use page_table::mock_page_table::MockPageTable;
|
||||
|
||||
enum MemOp {
|
||||
R(usize), W(usize)
|
||||
@ -52,7 +52,7 @@ mod test {
|
||||
static mut PAGE: *mut MockPageTable = 0 as *mut _;
|
||||
static mut FIFO: *mut FifoSwapManager<MockPageTable> = 0 as *mut _;
|
||||
|
||||
fn page_fault_handler(pt: &mut MockPageTable, addr: Addr) {
|
||||
fn page_fault_handler(pt: &mut MockPageTable, addr: VirtAddr) {
|
||||
unsafe{ PGFAULT_COUNT += 1; }
|
||||
let fifo = unsafe{ &mut *FIFO };
|
||||
if !pt.map(addr) { // is full?
|
||||
|
@ -1,8 +1,8 @@
|
||||
pub mod fifo;
|
||||
mod mock_page_table;
|
||||
mod mock_swapper;
|
||||
use super::*;
|
||||
use super::page_table::PageTable;
|
||||
|
||||
type Addr = usize;
|
||||
pub mod fifo;
|
||||
mod mock_swapper;
|
||||
|
||||
trait SwapManager<T: PageTable> {
|
||||
/// Create and initialize for the swap manager
|
||||
@ -10,16 +10,11 @@ trait SwapManager<T: PageTable> {
|
||||
/// Called when tick interrupt occured
|
||||
fn tick(&mut self);
|
||||
/// Called when map a swappable page into the memory
|
||||
fn push(&mut self, addr: Addr);
|
||||
fn push(&mut self, addr: VirtAddr);
|
||||
/// Called to delete the addr entry from the swap manager
|
||||
fn remove(&mut self, addr: Addr);
|
||||
fn remove(&mut self, addr: VirtAddr);
|
||||
/// Try to swap out a page, return then victim
|
||||
fn pop(&mut self) -> Option<Addr>;
|
||||
}
|
||||
|
||||
trait PageTable {
|
||||
fn accessed(&self, addr: Addr) -> bool;
|
||||
fn dirty(&self, addr: Addr) -> bool;
|
||||
fn pop(&mut self) -> Option<VirtAddr>;
|
||||
}
|
||||
|
||||
trait Swapper {
|
||||
|
Loading…
Reference in New Issue
Block a user