Implement events on pipe

Add syscall name debugging
Update debugging code
This commit is contained in:
Jeremy Soller
2017-09-16 12:04:20 -06:00
parent 917d30c193
commit 6e8de21b7c
3 changed files with 155 additions and 15 deletions

View File

@@ -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();
}
}

66
src/syscall/debug.rs Normal file
View File

@@ -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",
_ => "?",
}
}

View File

@@ -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 result = inner(a, b, c, d, e, f, bp, stack);
/*
if let Err(ref err) = result {
let 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());
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}: {}", a, b, c, d, err);
println!("{} ({:X}), {:X}, {:X}, {:X}", debug::name(a), a, b, c, d);
}
*/
let result = inner(a, b, c, d, e, f, bp, stack);
/*
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());
}
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);
}
}
}
*/