diff --git a/src/scheme/pipe.rs b/src/scheme/pipe.rs index 330b869510ecaee0d43ec0d1962a611ba05be713..9bd5f6790c948b11f585213298c65146fe9cfd86 100644 --- a/src/scheme/pipe.rs +++ b/src/scheme/pipe.rs @@ -2,11 +2,12 @@ use alloc::arc::{Arc, Weak}; use collections::{BTreeMap, VecDeque}; use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; use spin::{Mutex, Once, RwLock, RwLockReadGuard, RwLockWriteGuard}; -use scheme::{AtomicSchemeId, ATOMIC_SCHEMEID_INIT, SchemeId}; +use context; +use scheme::{AtomicSchemeId, ATOMIC_SCHEMEID_INIT, SchemeId}; use sync::WaitCondition; use syscall::error::{Error, Result, EAGAIN, EBADF, EINVAL, EPIPE, ESPIPE}; -use syscall::flag::{F_GETFL, F_SETFL, O_ACCMODE, O_NONBLOCK, MODE_FIFO}; +use syscall::flag::{EVENT_READ, F_GETFL, F_SETFL, O_ACCMODE, O_NONBLOCK, MODE_FIFO}; use syscall::scheme::Scheme; use syscall::data::Stat; @@ -32,10 +33,11 @@ fn pipes_mut() -> RwLockWriteGuard<'static, (BTreeMap<usize, Arc<PipeRead>>, BTr pub fn pipe(flags: usize) -> (usize, usize) { let mut pipes = pipes_mut(); + let scheme_id = PIPE_SCHEME_ID.load(Ordering::SeqCst); let read_id = PIPE_NEXT_ID.fetch_add(1, Ordering::SeqCst); let write_id = PIPE_NEXT_ID.fetch_add(1, Ordering::SeqCst); - let read = PipeRead::new(flags); - let write = PipeWrite::new(flags, &read); + let read = PipeRead::new(scheme_id, read_id, flags); + let write = PipeWrite::new(&read, flags); pipes.0.insert(read_id, Arc::new(read)); pipes.1.insert(write_id, Arc::new(write)); (read_id, write_id) @@ -117,6 +119,16 @@ impl Scheme for PipeScheme { Err(Error::new(EBADF)) } + fn fevent(&self, id: usize, flags: usize) -> Result<usize> { + let pipes = pipes(); + + if let Some(pipe) = pipes.0.get(&id) { + return pipe.fevent(flags); + } + + Err(Error::new(EBADF)) + } + fn fpath(&self, _id: usize, buf: &mut [u8]) -> Result<usize> { let mut i = 0; let scheme_path = b"pipe:"; @@ -156,14 +168,18 @@ impl Scheme for PipeScheme { /// Read side of a pipe pub struct PipeRead { + scheme_id: SchemeId, + event_id: usize, flags: AtomicUsize, condition: Arc<WaitCondition>, vec: Arc<Mutex<VecDeque<u8>>> } impl PipeRead { - pub fn new(flags: usize) -> Self { + pub fn new(scheme_id: SchemeId, event_id: usize, flags: usize) -> Self { PipeRead { + scheme_id: scheme_id, + event_id: event_id, flags: AtomicUsize::new(flags), condition: Arc::new(WaitCondition::new()), vec: Arc::new(Mutex::new(VecDeque::new())), @@ -172,6 +188,8 @@ impl PipeRead { fn dup(&self) -> Result<Self> { Ok(PipeRead { + scheme_id: self.scheme_id, + event_id: self.event_id, flags: AtomicUsize::new(self.flags.load(Ordering::SeqCst)), condition: self.condition.clone(), vec: self.vec.clone() @@ -189,6 +207,10 @@ impl PipeRead { } } + fn fevent(&self, _flags: usize) -> Result<usize> { + Ok(self.event_id) + } + fn read(&self, buf: &mut [u8]) -> Result<usize> { loop { { @@ -222,14 +244,18 @@ impl PipeRead { /// Read side of a pipe pub struct PipeWrite { + scheme_id: SchemeId, + event_id: usize, flags: AtomicUsize, condition: Arc<WaitCondition>, vec: Option<Weak<Mutex<VecDeque<u8>>>> } impl PipeWrite { - pub fn new(flags: usize, read: &PipeRead) -> Self { + pub fn new(read: &PipeRead, flags: usize) -> Self { PipeWrite { + scheme_id: read.scheme_id, + event_id: read.event_id, flags: AtomicUsize::new(flags), condition: read.condition.clone(), vec: Some(Arc::downgrade(&read.vec)), @@ -238,6 +264,8 @@ impl PipeWrite { fn dup(&self) -> Result<Self> { Ok(PipeWrite { + scheme_id: self.scheme_id, + event_id: self.event_id, flags: AtomicUsize::new(self.flags.load(Ordering::SeqCst)), condition: self.condition.clone(), vec: self.vec.clone() @@ -258,12 +286,17 @@ impl PipeWrite { fn write(&self, buf: &[u8]) -> Result<usize> { if let Some(ref vec_weak) = self.vec { if let Some(vec_lock) = vec_weak.upgrade() { - let mut vec = vec_lock.lock(); + let len = { + let mut vec = vec_lock.lock(); - for &b in buf.iter() { - vec.push_back(b); - } + for &b in buf.iter() { + vec.push_back(b); + } + + vec.len() + }; + context::event::trigger(self.scheme_id, self.event_id, EVENT_READ, len); self.condition.notify(); Ok(buf.len()) @@ -279,6 +312,7 @@ impl PipeWrite { impl Drop for PipeWrite { fn drop(&mut self) { drop(self.vec.take()); + context::event::trigger(self.scheme_id, self.event_id, EVENT_READ, 0); self.condition.notify(); } } diff --git a/src/syscall/debug.rs b/src/syscall/debug.rs new file mode 100644 index 0000000000000000000000000000000000000000..fee98c06d604808f8fdd808ca85ba1503b2fb8f3 --- /dev/null +++ b/src/syscall/debug.rs @@ -0,0 +1,66 @@ +use super::number::*; + +pub fn name(call: usize) -> &'static str { + match call { + SYS_LINK => "LINK", + SYS_OPEN => "OPEN", + SYS_CHMOD => "CHMOD", + SYS_RMDIR => "RMDIR", + SYS_UNLINK => "UNLINK", + + SYS_CLOSE => "CLOSE", + SYS_DUP => "DUP", + SYS_DUP2 => "DUP2", + SYS_READ => "READ", + SYS_WRITE => "WRITE", + SYS_LSEEK => "LSEEK", + SYS_FCNTL => "FCNTL", + SYS_FEVENT => "FEVENT", + SYS_FMAP => "FMAP", + SYS_FUNMAP => "FUNMAP", + SYS_FPATH => "FPATH", + SYS_FSTAT => "FSTAT", + SYS_FSTATVFS => "FSTATVFS", + SYS_FSYNC => "FSYNC", + SYS_FTRUNCATE => "FTRUNCATE", + SYS_FUTIMENS => "FUTIMENS", + + SYS_BRK => "BRK", + SYS_CHDIR => "CHDIR", + SYS_CLOCK_GETTIME => "CLOCK_GETTIME", + SYS_CLONE => "CLONE", + SYS_EXECVE => "EXECVE", + SYS_EXIT => "EXIT", + SYS_FUTEX => "FUTEX", + SYS_GETCWD => "GETCWD", + SYS_GETEGID => "GETEGID", + SYS_GETENS => "GETENS", + SYS_GETEUID => "GETEUID", + SYS_GETGID => "GETGID", + SYS_GETNS => "GETNS", + SYS_GETPID => "GETPID", + SYS_GETPGID => "GETPGID", + SYS_GETPPID => "GETPPID", + SYS_GETUID => "GETUID", + SYS_IOPL => "IOPL", + SYS_KILL => "KILL", + SYS_MKNS => "MKNS", + SYS_NANOSLEEP => "NANOSLEEP", + SYS_PHYSALLOC => "PHYSALLOC", + SYS_PHYSFREE => "PHYSFREE", + SYS_PHYSMAP => "PHYSMAP", + SYS_PHYSUNMAP => "PHYSUNMAP", + SYS_VIRTTOPHYS => "VIRTTOPHYS", + SYS_PIPE2 => "PIPE2", + SYS_SETPGID => "SETPGID", + SYS_SETREGID => "SETREGID", + SYS_SETRENS => "SETRENS", + SYS_SETREUID => "SETREUID", + SYS_SIGACTION => "SIGACTION", + SYS_SIGRETURN => "SIGRETURN", + SYS_WAITPID => "WAITPID", + SYS_YIELD => "YIELD", + + _ => "?", + } +} diff --git a/src/syscall/mod.rs b/src/syscall/mod.rs index a443d72063e1a426a6899e56b9f932e73274f779..f3181b147a70e42c4a1d364a0d6ce843d9700607 100644 --- a/src/syscall/mod.rs +++ b/src/syscall/mod.rs @@ -20,6 +20,9 @@ use context::ContextId; use interrupt::syscall::SyscallStack; use scheme::{FileHandle, SchemeNamespace}; +/// Debug +pub mod debug; + /// Driver syscalls pub mod driver; @@ -130,17 +133,54 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize } } + /* + let debug = { + let contexts = ::context::contexts(); + if let Some(context_lock) = contexts.current() { + let context = context_lock.read(); + if unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) } == "file:/bin/acid" { + if (a == SYS_WRITE || a == SYS_FSYNC) && (b == 1 || b == 2) { + false + } else { + true + } + } else { + false + } + } else { + false + } + }; + + if debug { + let contexts = ::context::contexts(); + if let Some(context_lock) = contexts.current() { + let context = context_lock.read(); + print!("{} ({}): ", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) }, context.id.into()); + } + + println!("{} ({:X}), {:X}, {:X}, {:X}", debug::name(a), a, b, c, d); + } + */ + let result = inner(a, b, c, d, e, f, bp, stack); /* - if let Err(ref err) = result { + if debug { let contexts = ::context::contexts(); if let Some(context_lock) = contexts.current() { let context = context_lock.read(); - print!("{}: {}: ", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) }, context.id.into()); + print!("{} ({}): ", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) }, context.id.into()); } - println!("{:X}, {:X}, {:X}, {:X}: {}", a, b, c, d, err); + match result { + Ok(ref ok) => { + println!("{} ({:X}), {:X}, {:X}, {:X}: Ok({:X})", debug::name(a), a, b, c, d, ok); + }, + Err(ref err) => { + println!("{} ({:X}), {:X}, {:X}, {:X}: Err({} ({:X}))", debug::name(a), a, b, c, d, err, err.errno); + } + } } */