diff --git a/scheme/debug.rs b/scheme/debug.rs index 8f63bf654f6f832206032332014f2a14f09db3fa..0dc67267ac9a17831497c37e8b40085b914440b1 100644 --- a/scheme/debug.rs +++ b/scheme/debug.rs @@ -1,6 +1,6 @@ use collections::VecDeque; use core::str; -use spin::{Mutex, MutexGuard, Once}; +use spin::{Mutex, Once}; use context; use syscall::Result; diff --git a/scheme/irq.rs b/scheme/irq.rs new file mode 100644 index 0000000000000000000000000000000000000000..9d7d42dae7353c3fbef37c8add16139941ff6c2c --- /dev/null +++ b/scheme/irq.rs @@ -0,0 +1,57 @@ +use core::{mem, str}; + +use arch::interrupt::irq::COUNTS; +use context; +use syscall::{Error, Result}; +use super::Scheme; + +pub struct IrqScheme; + +impl Scheme for IrqScheme { + fn open(&mut self, path: &[u8], _flags: usize) -> Result<usize> { + let path_str = str::from_utf8(path).or(Err(Error::NoEntry))?; + let id = path_str.parse::<usize>().or(Err(Error::NoEntry))?; + if id < COUNTS.lock().len() { + Ok(id) + } else { + Err(Error::NoEntry) + } + } + + fn dup(&mut self, file: usize) -> Result<usize> { + Ok(file) + } + + fn read(&mut self, file: usize, buffer: &mut [u8]) -> Result<usize> { + // Ensures that the length of the buffer is larger than the size of a usize + if buffer.len() >= mem::size_of::<usize>() { + let current = COUNTS.lock()[file]; + loop { + let next = COUNTS.lock()[file]; + if next != current { + // Safe if the length of the buffer is larger than the size of a usize + assert!(buffer.len() >= mem::size_of::<usize>()); + unsafe { *(buffer.as_mut_ptr() as *mut usize) = next }; + return Ok(mem::size_of::<usize>()); + } else { + // Safe if all locks have been dropped + unsafe { context::switch(); } + } + } + } else { + Err(Error::InvalidValue) + } + } + + fn write(&mut self, _file: usize, _buffer: &[u8]) -> Result<usize> { + Err(Error::NotPermitted) + } + + fn fsync(&mut self, file: usize) -> Result<()> { + Ok(()) + } + + fn close(&mut self, file: usize) -> Result<()> { + Ok(()) + } +} diff --git a/scheme/mod.rs b/scheme/mod.rs index af9f0a9a71e8c04fc25c3e078f1760aff71c71a0..6ca5c1357999b2e19baceb954448883f0445255b 100644 --- a/scheme/mod.rs +++ b/scheme/mod.rs @@ -18,6 +18,7 @@ use syscall::{Error, Result}; use self::debug::DebugScheme; use self::env::EnvScheme; use self::initfs::InitFsScheme; +use self::irq::IrqScheme; /// Debug scheme pub mod debug; @@ -28,6 +29,9 @@ pub mod env; /// InitFS scheme pub mod initfs; +/// IRQ handling +pub mod irq; + /// Limit on number of schemes pub const SCHEME_MAX_SCHEMES: usize = 65536; @@ -98,6 +102,7 @@ fn init_schemes() -> RwLock<SchemeList> { 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"); RwLock::new(list) }