Minimize locking in schemes. Reenable pcid and ion launch in init. WIP: Userspace schemes

This commit is contained in:
Jeremy Soller 2016-09-19 18:29:28 -06:00
parent 94ad63de11
commit abdbadfea3
9 changed files with 367 additions and 113 deletions

View file

@ -11,7 +11,7 @@ use alloc::boxed::Box;
use collections::BTreeMap;
use spin::{Once, Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard};
use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
use syscall::{Error, Result};
@ -32,12 +32,15 @@ pub mod initfs;
/// IRQ handling
pub mod irq;
/// Userspace schemes
//pub mod user;
/// Limit on number of schemes
pub const SCHEME_MAX_SCHEMES: usize = 65536;
/// Scheme list type
pub struct SchemeList {
map: BTreeMap<usize, Arc<Mutex<Box<Scheme + Send>>>>,
map: BTreeMap<usize, Arc<Box<Scheme + Send + Sync>>>,
names: BTreeMap<Box<[u8]>, usize>,
next_id: usize
}
@ -53,11 +56,11 @@ impl SchemeList {
}
/// Get the nth scheme.
pub fn get(&self, id: usize) -> Option<&Arc<Mutex<Box<Scheme + Send>>>> {
pub fn get(&self, id: usize) -> Option<&Arc<Box<Scheme + Send + Sync>>> {
self.map.get(&id)
}
pub fn get_name(&self, name: &[u8]) -> Option<(usize, &Arc<Mutex<Box<Scheme + Send>>>)> {
pub fn get_name(&self, name: &[u8]) -> Option<(usize, &Arc<Box<Scheme + Send + Sync>>)> {
if let Some(&id) = self.names.get(name) {
self.get(id).map(|scheme| (id, scheme))
} else {
@ -66,7 +69,7 @@ impl SchemeList {
}
/// Create a new scheme.
pub fn insert(&mut self, name: Box<[u8]>, scheme: Arc<Mutex<Box<Scheme + Send>>>) -> Result<&Arc<Mutex<Box<Scheme + Send>>>> {
pub fn insert(&mut self, name: Box<[u8]>, scheme: Arc<Box<Scheme + Send + Sync>>) -> Result<&Arc<Box<Scheme + Send + Sync>>> {
if self.names.contains_key(&name) {
return Err(Error::FileExists);
}
@ -99,10 +102,10 @@ static SCHEMES: Once<RwLock<SchemeList>> = Once::new();
/// Initialize schemes, called if needed
fn init_schemes() -> RwLock<SchemeList> {
let mut list: SchemeList = SchemeList::new();
list.insert(Box::new(*b"debug"), Arc::new(Mutex::new(Box::new(DebugScheme)))).expect("failed to insert debug: scheme");
list.insert(Box::new(*b"env"), Arc::new(Mutex::new(Box::new(EnvScheme::new())))).expect("failed to insert env: scheme");
list.insert(Box::new(*b"initfs"), Arc::new(Mutex::new(Box::new(InitFsScheme::new())))).expect("failed to insert initfs: scheme");
list.insert(Box::new(*b"irq"), Arc::new(Mutex::new(Box::new(IrqScheme)))).expect("failed to insert irq: scheme");
list.insert(Box::new(*b"debug"), Arc::new(Box::new(DebugScheme))).expect("failed to insert debug: scheme");
list.insert(Box::new(*b"env"), Arc::new(Box::new(EnvScheme::new()))).expect("failed to insert env: scheme");
list.insert(Box::new(*b"initfs"), Arc::new(Box::new(InitFsScheme::new()))).expect("failed to insert initfs: scheme");
list.insert(Box::new(*b"irq"), Arc::new(Box::new(IrqScheme))).expect("failed to insert irq: scheme");
RwLock::new(list)
}
@ -121,26 +124,26 @@ pub trait Scheme {
/// Open the file at `path` with `flags`.
///
/// Returns a file descriptor or an error
fn open(&mut self, path: &[u8], flags: usize) -> Result<usize>;
fn open(&self, path: &[u8], flags: usize) -> Result<usize>;
/// Duplicate an open file descriptor
///
/// Returns a file descriptor or an error
fn dup(&mut self, file: usize) -> Result<usize>;
fn dup(&self, file: usize) -> Result<usize>;
/// Read from some file descriptor into the `buffer`
///
/// Returns the number of bytes read
fn read(&mut self, file: usize, buffer: &mut [u8]) -> Result<usize>;
fn read(&self, file: usize, buffer: &mut [u8]) -> Result<usize>;
/// Write the `buffer` to the file descriptor
///
/// Returns the number of bytes written
fn write(&mut self, file: usize, buffer: &[u8]) -> Result<usize>;
fn write(&self, file: usize, buffer: &[u8]) -> Result<usize>;
/// Sync the file descriptor
fn fsync(&mut self, file: usize) -> Result<()>;
fn fsync(&self, file: usize) -> Result<()>;
/// Close the file descriptor
fn close(&mut self, file: usize) -> Result<()>;
fn close(&self, file: usize) -> Result<()>;
}