Make grants be a BTreeSet
This commit is contained in:
+17
-13
@@ -93,20 +93,20 @@ pub fn inner_physmap(physical_address: usize, size: usize, flags: PhysmapFlags)
|
||||
entry_flags |= EntryFlags::NO_CACHE;
|
||||
}
|
||||
|
||||
let mut i = 0;
|
||||
while i < grants.len() {
|
||||
let start = grants[i].start_address().get();
|
||||
// TODO: Make this faster than Sonic himself by using le superpowers of BTreeSet
|
||||
|
||||
for grant in grants.iter() {
|
||||
let start = grant.start_address().get();
|
||||
if to_address + full_size < start {
|
||||
break;
|
||||
}
|
||||
|
||||
let pages = (grants[i].size() + 4095) / 4096;
|
||||
let pages = (grant.size() + 4095) / 4096;
|
||||
let end = start + pages * 4096;
|
||||
to_address = end;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
grants.insert(i, Grant::physmap(
|
||||
grants.insert(Grant::physmap(
|
||||
PhysicalAddress::new(from_address),
|
||||
VirtualAddress::new(to_address),
|
||||
full_size,
|
||||
@@ -131,14 +131,18 @@ pub fn inner_physunmap(virtual_address: usize) -> Result<usize> {
|
||||
|
||||
let mut grants = context.grants.lock();
|
||||
|
||||
for i in 0 .. grants.len() {
|
||||
let start = grants[i].start_address().get();
|
||||
let end = start + grants[i].size();
|
||||
if virtual_address >= start && virtual_address < end {
|
||||
grants.remove(i).unmap();
|
||||
// TODO Implementation can now use the powers of BTreeSet
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
let grant = grants.iter().map(|grant| grant.region()).find(|grant| {
|
||||
let start = grant.start_address().get();
|
||||
let end = start + grant.size();
|
||||
|
||||
virtual_address >= start && virtual_address < end
|
||||
});
|
||||
|
||||
if let Some(grant) = grant {
|
||||
grants.take(&grant).unwrap().unmap();
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
Err(Error::new(EFAULT))
|
||||
|
||||
+16
-9
@@ -453,15 +453,22 @@ pub fn funmap(virtual_address: usize) -> Result<usize> {
|
||||
|
||||
let mut grants = context.grants.lock();
|
||||
|
||||
for i in 0 .. grants.len() {
|
||||
let start = grants[i].start_address().get();
|
||||
let end = start + grants[i].size();
|
||||
if virtual_address >= start && virtual_address < end {
|
||||
let mut grant = grants.remove(i);
|
||||
desc_opt = grant.desc_opt.take();
|
||||
grant.unmap();
|
||||
break;
|
||||
}
|
||||
// TODO: Make BTreeSet roll around at the speed of sound,
|
||||
// I mean, its got places to go, gotta follow its rainbow.
|
||||
// Can't keep around, gotta moving on.
|
||||
// Guess what lies ahead, only one way to find oooouuuut.
|
||||
|
||||
let grant = grants.iter().map(|grant| grant.region()).find(|grant| {
|
||||
let start = grant.start_address().get();
|
||||
let end = start + grant.size();
|
||||
|
||||
virtual_address >= start && virtual_address < end
|
||||
});
|
||||
|
||||
if let Some(grant) = grant {
|
||||
let mut grant = grants.take(&grant).unwrap();
|
||||
desc_opt = grant.desc_opt.take();
|
||||
grant.unmap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+32
-18
@@ -1,13 +1,15 @@
|
||||
use alloc::sync::Arc;
|
||||
use alloc::boxed::Box;
|
||||
use alloc::collections::BTreeSet;
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec::Vec;
|
||||
use core::alloc::{GlobalAlloc, Layout};
|
||||
use core::{intrinsics, mem};
|
||||
use core::ops::DerefMut;
|
||||
use core::{intrinsics, mem};
|
||||
use spin::Mutex;
|
||||
|
||||
use crate::context::file::FileDescriptor;
|
||||
use crate::context::{ContextId, WaitpidKey};
|
||||
use crate::context::memory::UserGrants;
|
||||
use crate::context;
|
||||
#[cfg(not(feature="doc"))]
|
||||
use crate::elf::{self, program_header};
|
||||
@@ -280,12 +282,12 @@ pub fn clone(flags: CloneFlags, stack_base: usize) -> Result<ContextId> {
|
||||
if flags.contains(CLONE_VM) {
|
||||
grants = Arc::clone(&context.grants);
|
||||
} else {
|
||||
let mut grants_vec = Vec::new();
|
||||
let mut grants_set = UserGrants::default();
|
||||
for grant in context.grants.lock().iter() {
|
||||
let start = VirtualAddress::new(grant.start_address().get() + crate::USER_TMP_GRANT_OFFSET - crate::USER_GRANT_OFFSET);
|
||||
grants_vec.push(grant.secret_clone(start));
|
||||
grants_set.insert(grant.secret_clone(start));
|
||||
}
|
||||
grants = Arc::new(Mutex::new(grants_vec));
|
||||
grants = Arc::new(Mutex::new(grants_set));
|
||||
}
|
||||
|
||||
if flags.contains(CLONE_VM) {
|
||||
@@ -332,20 +334,25 @@ pub fn clone(flags: CloneFlags, stack_base: usize) -> Result<ContextId> {
|
||||
|
||||
// If not cloning virtual memory, use fmap to re-obtain every grant where possible
|
||||
if !flags.contains(CLONE_VM) {
|
||||
let mut i = 0;
|
||||
while i < grants.lock().len() {
|
||||
let mut grants = grants.lock();
|
||||
|
||||
let mut to_remove = BTreeSet::new();
|
||||
|
||||
// TODO: Use drain_filter if possible
|
||||
|
||||
for grant in grants.iter() {
|
||||
let remove = false;
|
||||
if let Some(grant) = grants.lock().get(i) {
|
||||
if let Some(ref _desc) = grant.desc_opt {
|
||||
println!("todo: clone grant {} using fmap: {:?}", i, grant);
|
||||
}
|
||||
if let Some(ref _desc) = grant.desc_opt {
|
||||
println!("todo: clone grant using fmap: {:?}", grant);
|
||||
}
|
||||
if remove {
|
||||
grants.lock().remove(i);
|
||||
} else {
|
||||
i += 1;
|
||||
to_remove.insert(grant.region());
|
||||
}
|
||||
}
|
||||
|
||||
for region in to_remove {
|
||||
grants.remove(®ion);
|
||||
}
|
||||
}
|
||||
|
||||
// If vfork, block the current process
|
||||
@@ -510,9 +517,15 @@ pub fn clone(flags: CloneFlags, stack_base: usize) -> Result<ContextId> {
|
||||
}
|
||||
|
||||
// Move grants
|
||||
for grant in grants.lock().iter_mut() {
|
||||
let start = VirtualAddress::new(grant.start_address().get() + crate::USER_GRANT_OFFSET - crate::USER_TMP_GRANT_OFFSET);
|
||||
grant.move_to(start, &mut new_table, &mut temporary_page);
|
||||
{
|
||||
let mut grants = grants.lock();
|
||||
let old_grants = mem::replace(&mut *grants, UserGrants::default());
|
||||
|
||||
for mut grant in old_grants.inner.into_iter() {
|
||||
let start = VirtualAddress::new(grant.start_address().get() + crate::USER_GRANT_OFFSET - crate::USER_TMP_GRANT_OFFSET);
|
||||
grant.move_to(start, &mut new_table, &mut temporary_page);
|
||||
grants.insert(grant);
|
||||
}
|
||||
}
|
||||
context.grants = grants;
|
||||
}
|
||||
@@ -626,7 +639,8 @@ fn empty(context: &mut context::Context, reaping: bool) {
|
||||
|
||||
let mut grants = context.grants.lock();
|
||||
if Arc::strong_count(&context.grants) == 1 {
|
||||
for grant in grants.drain(..) {
|
||||
let grants = mem::replace(&mut *grants, UserGrants::default());
|
||||
for grant in grants.inner.into_iter() {
|
||||
if reaping {
|
||||
println!("{}: {}: Grant should not exist: {:?}", context.id.into(), unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) }, grant);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user