From 99fee86ef91b2162b4ee2b0bc83fb8955e739765 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Fri, 14 Oct 2016 20:12:21 -0600 Subject: [PATCH] Significant improvements for events - switch to event queue in orbital --- context/event.rs | 14 +++++++------- context/file.rs | 2 ++ scheme/irq.rs | 4 ++-- scheme/root.rs | 4 ++-- syscall/fs.rs | 37 ++++++++++++++++++++++++++++--------- syscall/process.rs | 10 ++++++++-- 6 files changed, 49 insertions(+), 22 deletions(-) diff --git a/context/event.rs b/context/event.rs index 19d119d3..a42ecef2 100644 --- a/context/event.rs +++ b/context/event.rs @@ -27,7 +27,7 @@ pub fn registry_mut() -> RwLockWriteGuard<'static, Registry> { REGISTRY.call_once(init_registry).write() } -pub fn register(fd: usize, scheme_id: usize, id: usize) -> bool { +pub fn register(fd: usize, scheme_id: usize, event_id: usize) -> bool { let (context_id, events) = { let contexts = context::contexts(); let context_lock = contexts.current().expect("event::register: No context"); @@ -36,7 +36,7 @@ pub fn register(fd: usize, scheme_id: usize, id: usize) -> bool { }; let mut registry = registry_mut(); - let entry = registry.entry((scheme_id, id)).or_insert_with(|| { + let entry = registry.entry((scheme_id, event_id)).or_insert_with(|| { BTreeMap::new() }); if entry.contains_key(&(context_id, fd)) { @@ -47,11 +47,11 @@ pub fn register(fd: usize, scheme_id: usize, id: usize) -> bool { } } -pub fn unregister(fd: usize, scheme_id: usize, id: usize) { +pub fn unregister(fd: usize, scheme_id: usize, event_id: usize) { let mut registry = registry_mut(); let mut remove = false; - if let Some(entry) = registry.get_mut(&(scheme_id, id)) { + if let Some(entry) = registry.get_mut(&(scheme_id, event_id)) { entry.remove(&(context::context_id(), fd)); if entry.is_empty() { @@ -60,13 +60,13 @@ pub fn unregister(fd: usize, scheme_id: usize, id: usize) { } if remove { - registry.remove(&(scheme_id, id)); + registry.remove(&(scheme_id, event_id)); } } -pub fn trigger(scheme_id: usize, id: usize, flags: usize, data: usize) { +pub fn trigger(scheme_id: usize, event_id: usize, flags: usize, data: usize) { let registry = registry(); - if let Some(event_lists) = registry.get(&(scheme_id, id)) { + if let Some(event_lists) = registry.get(&(scheme_id, event_id)) { for entry in event_lists.iter() { if let Some(event_list) = entry.1.upgrade() { event_list.send(Event { diff --git a/context/file.rs b/context/file.rs index 67a28eb8..d9238d69 100644 --- a/context/file.rs +++ b/context/file.rs @@ -8,4 +8,6 @@ pub struct File { pub scheme: usize, /// The number the scheme uses to refer to this file pub number: usize, + /// If events are on, this is the event ID + pub event: Option<usize>, } diff --git a/scheme/irq.rs b/scheme/irq.rs index 2ed891e0..ce99c423 100644 --- a/scheme/irq.rs +++ b/scheme/irq.rs @@ -93,8 +93,8 @@ impl Scheme for IrqScheme { } } - fn fevent(&self, _file: usize, _flags: usize) -> Result<usize> { - Ok(0) + fn fevent(&self, file: usize, _flags: usize) -> Result<usize> { + Ok(file) } fn fsync(&self, _file: usize) -> Result<usize> { diff --git a/scheme/root.rs b/scheme/root.rs index 1d4d4d04..57877bf8 100644 --- a/scheme/root.rs +++ b/scheme/root.rs @@ -89,8 +89,8 @@ impl Scheme for RootScheme { inner.write(buf) } - fn fevent(&self, _file: usize, _flags: usize) -> Result<usize> { - Ok(0) + fn fevent(&self, file: usize, _flags: usize) -> Result<usize> { + Ok(file) } fn fsync(&self, _file: usize) -> Result<usize> { diff --git a/syscall/fs.rs b/syscall/fs.rs index fb06884e..6c953e46 100644 --- a/syscall/fs.rs +++ b/syscall/fs.rs @@ -98,7 +98,8 @@ pub fn open(path: &[u8], flags: usize) -> Result<usize> { let context = context_lock.read(); context.add_file(::context::file::File { scheme: scheme_id, - number: file_id + number: file_id, + event: None, }).ok_or(Error::new(EMFILE)) } @@ -113,12 +114,14 @@ pub fn pipe2(fds: &mut [usize], flags: usize) -> Result<usize> { let read_fd = context.add_file(::context::file::File { scheme: scheme_id, - number: read_id + number: read_id, + event: None, }).ok_or(Error::new(EMFILE))?; let write_fd = context.add_file(::context::file::File { scheme: scheme_id, - number: write_id + number: write_id, + event: None, }).ok_or(Error::new(EMFILE))?; fds[0] = read_fd; @@ -206,7 +209,9 @@ pub fn close(fd: usize) -> Result<usize> { file }; - context::event::unregister(fd, file.scheme, file.number); + if let Some(event_id) = file.event { + context::event::unregister(fd, file.scheme, event_id); + } let scheme = { let schemes = scheme::schemes(); @@ -240,7 +245,8 @@ pub fn dup(fd: usize) -> Result<usize> { let context = context_lock.read(); context.add_file(::context::file::File { scheme: file.scheme, - number: new_id + number: new_id, + event: None, }).ok_or(Error::new(EMFILE)) } @@ -250,8 +256,13 @@ pub fn fevent(fd: usize, flags: usize) -> Result<usize> { 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 mut files = context.files.lock(); + let mut file = files.get_mut(fd).ok_or(Error::new(EBADF))?.ok_or(Error::new(EBADF))?; + if let Some(event_id) = file.event.take() { + println!("{}: {}:{}: events already registered: {}", fd, file.scheme, file.number, event_id); + context::event::unregister(fd, file.scheme, event_id); + } + file.clone() }; let scheme = { @@ -259,7 +270,15 @@ pub fn fevent(fd: usize, flags: usize) -> Result<usize> { let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?; scheme.clone() }; - scheme.fevent(file.number, flags)?; - context::event::register(fd, file.scheme, file.number); + let event_id = scheme.fevent(file.number, flags)?; + { + let contexts = context::contexts(); + let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; + let context = context_lock.read(); + let mut files = context.files.lock(); + let mut file = files.get_mut(fd).ok_or(Error::new(EBADF))?.ok_or(Error::new(EBADF))?; + file.event = Some(event_id); + } + context::event::register(fd, file.scheme, event_id); Ok(0) } diff --git a/syscall/process.rs b/syscall/process.rs index 5763c891..ddd2cec9 100644 --- a/syscall/process.rs +++ b/syscall/process.rs @@ -232,7 +232,11 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> { }; match result { Ok(new_number) => { - Some(context::file::File { scheme: file.scheme, number: new_number }) + Some(context::file::File { + scheme: file.scheme, + number: new_number, + event: None, + }) }, Err(err) => { println!("clone: failed to dup {}: {:?}", fd, err); @@ -616,7 +620,9 @@ pub fn exit(status: usize) -> ! { /// Files must be closed while context is valid so that messages can be passed for (fd, file_option) in close_files.drain(..).enumerate() { if let Some(file) = file_option { - context::event::unregister(fd, file.scheme, file.number); + if let Some(event_id) = file.event { + context::event::unregister(fd, file.scheme, event_id); + } let scheme_option = { let schemes = scheme::schemes(); -- GitLab