From 8fd25ee3180dab85ff2f431ac53702b4bb3a02cc Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 20 Oct 2016 12:31:39 -0600 Subject: [PATCH] Add nonblocking root scheme --- kernel/scheme/debug.rs | 2 +- kernel/scheme/event.rs | 2 +- kernel/scheme/root.rs | 4 ++-- kernel/scheme/user.rs | 8 +++++--- kernel/sync/wait_queue.rs | 35 +++++++++++------------------------ 5 files changed, 20 insertions(+), 31 deletions(-) diff --git a/kernel/scheme/debug.rs b/kernel/scheme/debug.rs index e082ac6..27ab626 100644 --- a/kernel/scheme/debug.rs +++ b/kernel/scheme/debug.rs @@ -41,7 +41,7 @@ impl Scheme for DebugScheme { /// /// Returns the number of bytes read fn read(&self, _file: usize, buf: &mut [u8]) -> Result { - Ok(INPUT.call_once(init_input).receive_into(buf)) + Ok(INPUT.call_once(init_input).receive_into(buf, true)) } /// Write the `buffer` to the `file` diff --git a/kernel/scheme/event.rs b/kernel/scheme/event.rs index 1634e1b..cca7420 100644 --- a/kernel/scheme/event.rs +++ b/kernel/scheme/event.rs @@ -59,7 +59,7 @@ impl Scheme for EventScheme { }; let event_buf = unsafe { slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut Event, buf.len()/mem::size_of::()) }; - Ok(handle.receive_into(event_buf) * mem::size_of::()) + Ok(handle.receive_into(event_buf, true) * mem::size_of::()) } fn fsync(&self, id: usize) -> Result { diff --git a/kernel/scheme/root.rs b/kernel/scheme/root.rs index 57877bf..a253132 100644 --- a/kernel/scheme/root.rs +++ b/kernel/scheme/root.rs @@ -27,7 +27,7 @@ impl RootScheme { } impl Scheme for RootScheme { - fn open(&self, path: &[u8], _flags: usize, uid: u32, _gid: u32) -> Result { + fn open(&self, path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result { if uid == 0 { let context = { let contexts = context::contexts(); @@ -42,7 +42,7 @@ impl Scheme for RootScheme { if schemes.get_name(path).is_some() { return Err(Error::new(EEXIST)); } - let inner = Arc::new(UserInner::new(id, context)); + let inner = Arc::new(UserInner::new(id, flags, context)); let scheme_id = schemes.insert(path.to_vec().into_boxed_slice(), Arc::new(Box::new(UserScheme::new(Arc::downgrade(&inner))))).expect("failed to insert user scheme"); inner.scheme_id.store(scheme_id, Ordering::SeqCst); inner diff --git a/kernel/scheme/user.rs b/kernel/scheme/user.rs index c2d8650..8f1c95a 100644 --- a/kernel/scheme/user.rs +++ b/kernel/scheme/user.rs @@ -12,12 +12,13 @@ use scheme::root::ROOT_SCHEME_ID; use sync::{WaitQueue, WaitMap}; use syscall::data::{Packet, Stat}; use syscall::error::*; -use syscall::flag::EVENT_READ; +use syscall::flag::{EVENT_READ, O_NONBLOCK}; use syscall::number::*; use syscall::scheme::Scheme; pub struct UserInner { handle_id: usize, + flags: usize, pub scheme_id: AtomicUsize, next_id: AtomicU64, context: Weak>, @@ -26,9 +27,10 @@ pub struct UserInner { } impl UserInner { - pub fn new(handle_id: usize, context: Weak>) -> UserInner { + pub fn new(handle_id: usize, flags: usize, context: Weak>) -> UserInner { UserInner { handle_id: handle_id, + flags: flags, scheme_id: AtomicUsize::new(0), next_id: AtomicU64::new(1), context: context, @@ -158,7 +160,7 @@ impl UserInner { pub fn read(&self, buf: &mut [u8]) -> Result { let packet_buf = unsafe { slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut Packet, buf.len()/mem::size_of::()) }; - Ok(self.todo.receive_into(packet_buf) * mem::size_of::()) + Ok(self.todo.receive_into(packet_buf, self.flags & O_NONBLOCK != O_NONBLOCK) * mem::size_of::()) } pub fn write(&self, buf: &[u8]) -> Result { diff --git a/kernel/sync/wait_queue.rs b/kernel/sync/wait_queue.rs index 445164c..fdf81b5 100644 --- a/kernel/sync/wait_queue.rs +++ b/kernel/sync/wait_queue.rs @@ -1,6 +1,4 @@ use collections::vec_deque::VecDeque; -use core::mem; -use core::ops::DerefMut; use spin::Mutex; use sync::WaitCondition; @@ -39,40 +37,29 @@ impl WaitQueue { } } - pub fn receive_into(&self, buf: &mut [T]) -> usize { + pub fn receive_into(&self, buf: &mut [T], block: bool) -> usize { let mut i = 0; - if i < buf.len() { + if i < buf.len() && block { buf[i] = self.receive(); i += 1; } - while i < buf.len() { - if let Some(value) = self.inner.lock().pop_front() { - buf[i] = value; - i += 1; - } else { - break; + { + let mut inner = self.inner.lock(); + while i < buf.len() { + if let Some(value) = inner.pop_front() { + buf[i] = value; + i += 1; + } else { + break; + } } } i } - pub fn receive_all(&self) -> VecDeque { - loop { - { - let mut inner = self.inner.lock(); - if ! inner.is_empty() { - let mut swap_inner = VecDeque::new(); - mem::swap(inner.deref_mut(), &mut swap_inner); - return swap_inner; - } - } - self.condition.wait(); - } - } - pub fn send(&self, value: T) -> usize { let len = { let mut inner = self.inner.lock();