WIP: itimer and sigprocmask
This commit is contained in:
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -178,7 +178,7 @@ dependencies = [
|
||||
"goblin 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"linked_list_allocator 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"raw-cpuid 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.45",
|
||||
"redox_syscall 0.1.49",
|
||||
"slab_allocator 0.3.1",
|
||||
"spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"x86 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -279,7 +279,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.45"
|
||||
version = "0.1.49"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
|
||||
110
src/scheme/itimer.rs
Normal file
110
src/scheme/itimer.rs
Normal file
@@ -0,0 +1,110 @@
|
||||
use alloc::collections::BTreeMap;
|
||||
use core::{mem, slice, str};
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
use spin::RwLock;
|
||||
|
||||
use syscall::data::ITimerSpec;
|
||||
use syscall::error::*;
|
||||
use syscall::flag::{CLOCK_REALTIME, CLOCK_MONOTONIC};
|
||||
use syscall::scheme::Scheme;
|
||||
|
||||
pub struct ITimerScheme {
|
||||
next_id: AtomicUsize,
|
||||
handles: RwLock<BTreeMap<usize, usize>>
|
||||
}
|
||||
|
||||
impl ITimerScheme {
|
||||
pub fn new() -> ITimerScheme {
|
||||
ITimerScheme {
|
||||
next_id: AtomicUsize::new(0),
|
||||
handles: RwLock::new(BTreeMap::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Scheme for ITimerScheme {
|
||||
fn open(&self, path: &[u8], _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
|
||||
let path_str = str::from_utf8(path).or(Err(Error::new(ENOENT)))?;
|
||||
|
||||
let clock = path_str.parse::<usize>().or(Err(Error::new(ENOENT)))?;
|
||||
|
||||
match clock {
|
||||
CLOCK_REALTIME => (),
|
||||
CLOCK_MONOTONIC => (),
|
||||
_ => return Err(Error::new(ENOENT))
|
||||
}
|
||||
|
||||
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
|
||||
self.handles.write().insert(id, clock);
|
||||
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
fn read(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
let clock = {
|
||||
let handles = self.handles.read();
|
||||
*handles.get(&id).ok_or(Error::new(EBADF))?
|
||||
};
|
||||
|
||||
let time_buf = unsafe { slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut ITimerSpec, buf.len()/mem::size_of::<ITimerSpec>()) };
|
||||
|
||||
let mut i = 0;
|
||||
while i < time_buf.len() {
|
||||
time_buf[i] = ITimerSpec::default();
|
||||
i += 1;
|
||||
}
|
||||
|
||||
Ok(i * mem::size_of::<ITimerSpec>())
|
||||
}
|
||||
|
||||
fn write(&self, id: usize, buf: &[u8]) -> Result<usize> {
|
||||
let clock = {
|
||||
let handles = self.handles.read();
|
||||
*handles.get(&id).ok_or(Error::new(EBADF))?
|
||||
};
|
||||
|
||||
let time_buf = unsafe { slice::from_raw_parts(buf.as_ptr() as *const ITimerSpec, buf.len()/mem::size_of::<ITimerSpec>()) };
|
||||
|
||||
let mut i = 0;
|
||||
while i < time_buf.len() {
|
||||
let time = time_buf[i];
|
||||
println!("{}: {:?}", i, time);
|
||||
i += 1;
|
||||
}
|
||||
|
||||
Ok(i * mem::size_of::<ITimerSpec>())
|
||||
}
|
||||
|
||||
fn fcntl(&self, _id: usize, _cmd: usize, _arg: usize) -> Result<usize> {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn fevent(&self, id: usize, _flags: usize) -> Result<usize> {
|
||||
let handles = self.handles.read();
|
||||
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(id))
|
||||
}
|
||||
|
||||
fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
let clock = {
|
||||
let handles = self.handles.read();
|
||||
*handles.get(&id).ok_or(Error::new(EBADF))?
|
||||
};
|
||||
|
||||
let mut i = 0;
|
||||
let scheme_path = format!("time:{}", clock).into_bytes();
|
||||
while i < buf.len() && i < scheme_path.len() {
|
||||
buf[i] = scheme_path[i];
|
||||
i += 1;
|
||||
}
|
||||
Ok(i)
|
||||
}
|
||||
|
||||
fn fsync(&self, id: usize) -> Result<usize> {
|
||||
let handles = self.handles.read();
|
||||
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(0))
|
||||
}
|
||||
|
||||
fn close(&self, id: usize) -> Result<usize> {
|
||||
self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(0))
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ use self::debug::DebugScheme;
|
||||
use self::event::EventScheme;
|
||||
use self::initfs::InitFsScheme;
|
||||
use self::irq::IrqScheme;
|
||||
use self::itimer::ITimerScheme;
|
||||
use self::memory::MemoryScheme;
|
||||
use self::pipe::PipeScheme;
|
||||
use self::root::RootScheme;
|
||||
@@ -37,6 +38,9 @@ pub mod initfs;
|
||||
/// `irq:` - allows userspace handling of IRQs
|
||||
pub mod irq;
|
||||
|
||||
/// `itimer:` - support for getitimer and setitimer
|
||||
pub mod itimer;
|
||||
|
||||
/// When compiled with "live" feature - `disk:` - embedded filesystem for live disk
|
||||
#[cfg(feature="live")]
|
||||
pub mod live;
|
||||
@@ -115,6 +119,7 @@ impl SchemeList {
|
||||
|
||||
self.insert(ns, Box::new(*b""), |scheme_id| Arc::new(Box::new(RootScheme::new(ns, scheme_id)))).unwrap();
|
||||
self.insert(ns, Box::new(*b"event"), |_| Arc::new(Box::new(EventScheme))).unwrap();
|
||||
self.insert(ns, Box::new(*b"itimer"), |_| Arc::new(Box::new(ITimerScheme::new()))).unwrap();
|
||||
self.insert(ns, Box::new(*b"memory"), |_| Arc::new(Box::new(MemoryScheme::new()))).unwrap();
|
||||
self.insert(ns, Box::new(*b"sys"), |_| Arc::new(Box::new(SysScheme::new()))).unwrap();
|
||||
self.insert(ns, Box::new(*b"time"), |scheme_id| Arc::new(Box::new(TimeScheme::new(scheme_id)))).unwrap();
|
||||
|
||||
@@ -254,6 +254,12 @@ pub fn format_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -
|
||||
d,
|
||||
e
|
||||
),
|
||||
SYS_SIGPROCMASK => format!(
|
||||
"sigprocmask({}, {:?}, {:?})",
|
||||
b,
|
||||
validate_slice(c as *const [u64; 2], 1),
|
||||
validate_slice(d as *const [u64; 2], 1)
|
||||
),
|
||||
SYS_MKNS => format!(
|
||||
"mkns({:?})",
|
||||
validate_slice(b as *const [usize; 2], c)
|
||||
|
||||
@@ -125,6 +125,19 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: u
|
||||
},
|
||||
e
|
||||
),
|
||||
SYS_SIGPROCMASK => sigprocmask(
|
||||
b,
|
||||
if c == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(validate_slice(c as *const [u64; 2], 1).map(|s| &s[0])?)
|
||||
},
|
||||
if d == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(validate_slice_mut(d as *mut [u64; 2], 1).map(|s| &mut s[0])?)
|
||||
}
|
||||
),
|
||||
SYS_SIGRETURN => sigreturn(),
|
||||
SYS_PIPE2 => pipe2(validate_slice_mut(b as *mut usize, 2)?, c),
|
||||
SYS_PHYSALLOC => physalloc(b),
|
||||
|
||||
@@ -1176,6 +1176,11 @@ pub fn sigaction(sig: usize, act_opt: Option<&SigAction>, oldact_opt: Option<&mu
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sigprocmask(how: usize, mask_opt: Option<&[u64; 2]>, oldmask_opt: Option<&mut [u64; 2]>) -> Result<usize> {
|
||||
println!("sigprocmask {}, {:?}, {:?}", how, mask_opt, oldmask_opt);
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub fn sigreturn() -> Result<usize> {
|
||||
{
|
||||
let contexts = context::contexts();
|
||||
|
||||
2
syscall
2
syscall
Submodule syscall updated: 31b7ae8eef...6909fb1c32
Reference in New Issue
Block a user