From 616dfbc0555c8ed62938dfbceba3220fa919d89f Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 23 Sep 2016 15:47:53 -0600 Subject: [PATCH] WIP: Kevent --- drivers/vesad/src/main.rs | 5 +++++ initfs/etc/init.rc | 4 ++-- kernel/context/switch.rs | 7 ++++--- kernel/lib.rs | 7 +++++-- kernel/scheme/debug.rs | 2 +- kernel/scheme/event.rs | 33 +++++++++++++++++++++++++++++++++ kernel/scheme/user.rs | 11 ++++++++--- kernel/syscall/fs.rs | 18 ++++++++++++++++++ kernel/syscall/mod.rs | 1 + kernel/syscall/process.rs | 3 +-- schemes/example/src/main.rs | 15 +++++++++++++++ syscall/src/data.rs | 24 ++++++++++++++++++++++++ syscall/src/flag.rs | 4 ++++ syscall/src/lib.rs | 4 ++++ syscall/src/number.rs | 1 + syscall/src/scheme.rs | 5 +++++ 16 files changed, 131 insertions(+), 13 deletions(-) create mode 100644 kernel/scheme/event.rs diff --git a/drivers/vesad/src/main.rs b/drivers/vesad/src/main.rs index f022a74..41c01ba 100644 --- a/drivers/vesad/src/main.rs +++ b/drivers/vesad/src/main.rs @@ -42,6 +42,11 @@ impl Scheme for DisplayScheme { Ok(id) } + fn fevent(&self, _id: usize, flags: usize) -> Result { + println!("fevent {:X}", flags); + Ok(0) + } + fn fsync(&self, _id: usize) -> Result { Ok(0) } diff --git a/initfs/etc/init.rc b/initfs/etc/init.rc index 374b4ab..27af7d0 100644 --- a/initfs/etc/init.rc +++ b/initfs/etc/init.rc @@ -1,5 +1,5 @@ initfs:bin/vesad initfs:bin/ps2d #initfs:bin/pcid -#initfs:bin/example -initfs:bin/login display: initfs:bin/ion +initfs:bin/example +#initfs:bin/login display: initfs:bin/ion diff --git a/kernel/context/switch.rs b/kernel/context/switch.rs index 2e16727..9065530 100644 --- a/kernel/context/switch.rs +++ b/kernel/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/kernel/lib.rs b/kernel/lib.rs index d7a1fc8..91b0000 100644 --- a/kernel/lib.rs +++ b/kernel/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/kernel/scheme/debug.rs b/kernel/scheme/debug.rs index 70459e7..9b630b4 100644 --- a/kernel/scheme/debug.rs +++ b/kernel/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/kernel/scheme/event.rs b/kernel/scheme/event.rs new file mode 100644 index 0000000..7801d74 --- /dev/null +++ b/kernel/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/kernel/scheme/user.rs b/kernel/scheme/user.rs index ba8fd95..c355456 100644 --- a/kernel/scheme/user.rs +++ b/kernel/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/kernel/syscall/fs.rs b/kernel/syscall/fs.rs index 2fef6f6..ca88b26 100644 --- a/kernel/syscall/fs.rs +++ b/kernel/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/kernel/syscall/mod.rs b/kernel/syscall/mod.rs index c4ed06b..1bb5a56 100644 --- a/kernel/syscall/mod.rs +++ b/kernel/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/kernel/syscall/process.rs b/kernel/syscall/process.rs index 0da2d00..5150b95 100644 --- a/kernel/syscall/process.rs +++ b/kernel/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 } } diff --git a/schemes/example/src/main.rs b/schemes/example/src/main.rs index 84fb345..3dd9c70 100644 --- a/schemes/example/src/main.rs +++ b/schemes/example/src/main.rs @@ -25,6 +25,21 @@ impl Scheme for ExampleScheme { } fn main(){ + { + let events = syscall::open("event:", 0).unwrap(); + + let a = syscall::open("display:", 0).unwrap(); + syscall::fevent(a, syscall::EVENT_READ).unwrap(); + + loop { + let mut event = syscall::Event::default(); + syscall::read(events, &mut event).unwrap(); + println!("{:?}", event); + } + + let _ = syscall::close(events); + } + thread::spawn(move || { let mut socket = File::create(":example").expect("example: failed to create example scheme"); let scheme = ExampleScheme; diff --git a/syscall/src/data.rs b/syscall/src/data.rs index 399950b..5ed4cd4 100644 --- a/syscall/src/data.rs +++ b/syscall/src/data.rs @@ -1,6 +1,30 @@ use core::ops::{Deref, DerefMut}; use core::{mem, slice}; +#[derive(Copy, Clone, Debug, Default)] +pub struct Event { + pub id: usize, + pub flags: usize, + pub data: usize +} + +impl Deref for Event { + type Target = [u8]; + fn deref(&self) -> &[u8] { + unsafe { + slice::from_raw_parts(self as *const Event as *const u8, mem::size_of::()) as &[u8] + } + } +} + +impl DerefMut for Event { + fn deref_mut(&mut self) -> &mut [u8] { + unsafe { + slice::from_raw_parts_mut(self as *mut Event as *mut u8, mem::size_of::()) as &mut [u8] + } + } +} + #[derive(Copy, Clone, Debug, Default)] #[repr(packed)] pub struct Packet { diff --git a/syscall/src/flag.rs b/syscall/src/flag.rs index 52db74c..73b4dd8 100644 --- a/syscall/src/flag.rs +++ b/syscall/src/flag.rs @@ -14,6 +14,10 @@ pub const CLONE_SUPERVISE: usize = 0x400000; pub const CLOCK_REALTIME: usize = 1; pub const CLOCK_MONOTONIC: usize = 4; +pub const EVENT_NONE: usize = 0; +pub const EVENT_READ: usize = 1; +pub const EVENT_WRITE: usize = 2; + pub const FUTEX_WAIT: usize = 0; pub const FUTEX_WAKE: usize = 1; pub const FUTEX_REQUEUE: usize = 2; diff --git a/syscall/src/lib.rs b/syscall/src/lib.rs index 3acc70a..2f4ea89 100644 --- a/syscall/src/lib.rs +++ b/syscall/src/lib.rs @@ -58,6 +58,10 @@ pub fn exit(status: usize) -> Result { unsafe { syscall1(SYS_EXIT, status) } } +pub fn fevent(fd: usize, flags: usize) -> Result { + unsafe { syscall2(SYS_FEVENT, fd, flags) } +} + pub fn fpath(fd: usize, buf: &mut [u8]) -> Result { unsafe { syscall3(SYS_FPATH, fd, buf.as_mut_ptr() as usize, buf.len()) } } diff --git a/syscall/src/number.rs b/syscall/src/number.rs index 80e7065..c0f341c 100644 --- a/syscall/src/number.rs +++ b/syscall/src/number.rs @@ -6,6 +6,7 @@ pub const SYS_CLOCK_GETTIME: usize = 265; pub const SYS_DUP: usize = 41; pub const SYS_EXECVE: usize = 11; pub const SYS_EXIT: usize = 1; +pub const SYS_FEVENT: usize = 927; pub const SYS_FPATH: usize = 928; pub const SYS_FSTAT: usize = 28; pub const SYS_FSYNC: usize = 118; diff --git a/syscall/src/scheme.rs b/syscall/src/scheme.rs index 6a857d1..5c6099d 100644 --- a/syscall/src/scheme.rs +++ b/syscall/src/scheme.rs @@ -67,6 +67,11 @@ pub trait Scheme { Err(Error::new(EBADF)) } + #[allow(unused_variables)] + fn fevent(&self, id: usize, flags: usize) -> Result { + Err(Error::new(EBADF)) + } + #[allow(unused_variables)] fn fpath(&self, id: usize, buf: &mut [u8]) -> Result { Err(Error::new(EBADF))