diff --git a/context/switch.rs b/context/switch.rs index 2e16727..9065530 100644 --- a/context/switch.rs +++ b/context/switch.rs @@ -8,7 +8,7 @@ use super::{contexts, Context, Status, CONTEXT_ID}; /// # Safety /// /// Do not call this while holding locks! -pub unsafe fn switch() { +pub unsafe fn switch() -> bool { use core::ops::DerefMut; // Set the global lock to avoid the unsafe operations below from causing issues @@ -48,10 +48,9 @@ pub unsafe fn switch() { } if to_ptr as usize == 0 { - // TODO: Sleep, wait for interrupt // Unset global lock if no context found arch::context::CONTEXT_SWITCH_LOCK.store(false, Ordering::SeqCst); - return; + return false; } //println!("Switch {} to {}", (&*from_ptr).id, (&*to_ptr).id); @@ -64,4 +63,6 @@ pub unsafe fn switch() { CONTEXT_ID.store((&mut *to_ptr).id, Ordering::SeqCst); (&mut *from_ptr).arch.switch_to(&mut (&mut *to_ptr).arch); + + true } diff --git a/lib.rs b/lib.rs index d7a1fc8..91b0000 100644 --- a/lib.rs +++ b/lib.rs @@ -162,8 +162,11 @@ pub extern fn kmain() { loop { unsafe { interrupt::disable(); - context::switch(); - interrupt::enable_and_nop(); + if context::switch() { + interrupt::enable_and_nop(); + } else { + interrupt::enable_and_halt(); + } } } } diff --git a/scheme/debug.rs b/scheme/debug.rs index 70459e7..9b630b4 100644 --- a/scheme/debug.rs +++ b/scheme/debug.rs @@ -48,7 +48,7 @@ impl Scheme for DebugScheme { if i > 0 { return Ok(i); } else { - unsafe { context::switch(); } + unsafe { context::switch(); } //TODO: Block } } } diff --git a/scheme/event.rs b/scheme/event.rs new file mode 100644 index 0000000..7801d74 --- /dev/null +++ b/scheme/event.rs @@ -0,0 +1,33 @@ +use core::{mem, str}; + +use arch::interrupt::irq::{ACKS, COUNTS, acknowledge}; +use syscall::error::*; +use syscall::scheme::Scheme; + +pub struct EventScheme; + +impl Scheme for EventScheme { + fn open(&self, _path: &[u8], _flags: usize) -> Result { + Ok( + } + + fn dup(&self, file: usize) -> Result { + Ok(file) + } + + fn read(&self, file: usize, buffer: &mut [u8]) -> Result { + Ok(0) + } + + fn write(&self, file: usize, buffer: &[u8]) -> Result { + Ok(0) + } + + fn fsync(&self, _file: usize) -> Result { + Ok(0) + } + + fn close(&self, _file: usize) -> Result { + Ok(0) + } +} diff --git a/scheme/user.rs b/scheme/user.rs index ba8fd95..c355456 100644 --- a/scheme/user.rs +++ b/scheme/user.rs @@ -52,7 +52,7 @@ impl UserInner { } } - unsafe { context::switch(); } + unsafe { context::switch(); } //TODO: Block } } @@ -163,7 +163,7 @@ impl UserInner { if i > 0 { return Ok(i * packet_size); } else { - unsafe { context::switch(); } + unsafe { context::switch(); } //TODO: Block } } } else { @@ -230,7 +230,12 @@ impl Scheme for UserScheme { fn seek(&self, file: usize, position: usize, whence: usize) -> Result { let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; - inner.call(SYS_FSYNC, file, position, whence) + inner.call(SYS_LSEEK, file, position, whence) + } + + fn fevent(&self, file: usize, flags: usize) -> Result { + let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; + inner.call(SYS_FEVENT, file, flags, 0) } fn fstat(&self, file: usize, stat: &mut Stat) -> Result { diff --git a/syscall/fs.rs b/syscall/fs.rs index 2fef6f6..ca88b26 100644 --- a/syscall/fs.rs +++ b/syscall/fs.rs @@ -98,6 +98,24 @@ pub fn dup(fd: usize) -> Result { scheme.dup(file.number) } +/// Register events for file +pub fn fevent(fd: usize, flags: usize) -> Result { + let file = { + let contexts = context::contexts(); + let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; + let context = context_lock.read(); + let file = context.get_file(fd).ok_or(Error::new(EBADF))?; + file + }; + + let scheme = { + let schemes = scheme::schemes(); + let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?; + scheme.clone() + }; + scheme.fevent(file.number, flags) +} + /// Get the canonical path of the file pub fn fpath(fd: usize, buf: &mut [u8]) -> Result { let file = { diff --git a/syscall/mod.rs b/syscall/mod.rs index c4ed06b..1bb5a56 100644 --- a/syscall/mod.rs +++ b/syscall/mod.rs @@ -45,6 +45,7 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize SYS_CLONE => clone(b, stack), SYS_YIELD => sched_yield(), SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?), + SYS_FEVENT => fevent(b, c), SYS_FPATH => fpath(b, validate_slice_mut(c as *mut u8, d)?), SYS_PHYSMAP => physmap(b, c, d), SYS_PHYSUNMAP => physunmap(b), diff --git a/syscall/process.rs b/syscall/process.rs index 0da2d00..5150b95 100644 --- a/syscall/process.rs +++ b/syscall/process.rs @@ -618,7 +618,6 @@ pub fn sched_yield() -> Result { } pub fn waitpid(pid: usize, status_ptr: usize, flags: usize) -> Result { - //TODO: Implement status_ptr and options loop { { let mut exited = false; @@ -644,6 +643,6 @@ pub fn waitpid(pid: usize, status_ptr: usize, flags: usize) -> Result { } } - unsafe { context::switch(); } + unsafe { context::switch(); } //TODO: Block } }