From 4341a2d7259d13f2182e36ff1c0b7b5bc5dac264 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 13 Sep 2016 11:20:55 -0600 Subject: [PATCH] Use flush_all instead of flush for performance --- kernel/context/memory.rs | 50 +++++++++++++++++++++++++++++++++++---- kernel/syscall/process.rs | 2 +- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/kernel/context/memory.rs b/kernel/context/memory.rs index c0b885b..9cd57f2 100644 --- a/kernel/context/memory.rs +++ b/kernel/context/memory.rs @@ -39,14 +39,22 @@ impl Memory { pub fn map(&mut self, flush: bool, clear: bool) { let mut active_table = unsafe { ActivePageTable::new() }; + let mut flush_all = false; + //TODO: Clear pages? for page in self.pages() { active_table.map(page, self.flags); + if flush { - active_table.flush(page); + //active_table.flush(page); + flush_all = true; } } + if flush_all { + active_table.flush_all(); + } + if clear { assert!(flush); unsafe { memset(self.start_address().get() as *mut u8, 0, self.size); } @@ -56,24 +64,40 @@ impl Memory { pub fn unmap(&mut self, flush: bool) { let mut active_table = unsafe { ActivePageTable::new() }; + let mut flush_all = false; + for page in self.pages() { active_table.unmap(page); + if flush { - active_table.flush(page); + //active_table.flush(page); + flush_all = true; } } + + if flush_all { + active_table.flush_all(); + } } pub fn remap(&mut self, new_flags: EntryFlags, flush: bool) { let mut active_table = unsafe { ActivePageTable::new() }; + let mut flush_all = false; + for page in self.pages() { active_table.remap(page, new_flags); + if flush { - active_table.flush(page); + //active_table.flush(page); + flush_all = true; } } + if flush_all { + active_table.flush_all(); + } + self.flags = new_flags; } @@ -82,32 +106,48 @@ impl Memory { //TODO: Calculate page changes to minimize operations if new_size > self.size { + let mut flush_all = false; + let start_page = Page::containing_address(VirtualAddress::new(self.start.get() + self.size)); let end_page = Page::containing_address(VirtualAddress::new(self.start.get() + new_size - 1)); for page in Page::range_inclusive(start_page, end_page) { if active_table.translate_page(page).is_none() { active_table.map(page, self.flags); + if flush { - active_table.flush(page); + //active_table.flush(page); + flush_all = true; } } } + if flush_all { + active_table.flush_all(); + } + if clear { assert!(flush); unsafe { memset((self.start.get() + self.size) as *mut u8, 0, new_size - self.size); } } } else if new_size < self.size { + let mut flush_all = false; + let start_page = Page::containing_address(VirtualAddress::new(self.start.get() + new_size)); let end_page = Page::containing_address(VirtualAddress::new(self.start.get() + self.size - 1)); for page in Page::range_inclusive(start_page, end_page) { if active_table.translate_page(page).is_some() { active_table.unmap(page); + if flush { - active_table.flush(page); + //active_table.flush(page); + flush_all = true; } } } + + if flush_all { + active_table.flush_all(); + } } self.size = new_size; diff --git a/kernel/syscall/process.rs b/kernel/syscall/process.rs index 78e0bc6..ad1d107 100644 --- a/kernel/syscall/process.rs +++ b/kernel/syscall/process.rs @@ -49,7 +49,7 @@ pub fn clone(flags: usize) -> Result { pub fn exit(status: usize) -> ! { println!("Exit {}", status); - + { let contexts = context::contexts(); let context_lock = contexts.current().expect("tried to exit without context");