From 7841f3617aac684dbe8464c9ffd5f85f67b502a0 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Thu, 6 Oct 2016 20:50:14 -0600 Subject: [PATCH] Time (#11) * WIP: Time syscalls * Count time from PIT using low tickrate * Implement realtime * Implement nanosleep with a tight loop --- scheme/pipe.rs | 1 - syscall/mod.rs | 7 +++++++ syscall/process.rs | 5 ----- syscall/time.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 syscall/time.rs diff --git a/scheme/pipe.rs b/scheme/pipe.rs index eee3d4fe..f9e680d6 100644 --- a/scheme/pipe.rs +++ b/scheme/pipe.rs @@ -3,7 +3,6 @@ use collections::{BTreeMap, VecDeque}; use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; use spin::{Mutex, Once, RwLock, RwLockReadGuard, RwLockWriteGuard}; -use context; use syscall::error::{Error, Result, EBADF, EPIPE}; use syscall::scheme::Scheme; diff --git a/syscall/mod.rs b/syscall/mod.rs index 9599a443..9de8b929 100644 --- a/syscall/mod.rs +++ b/syscall/mod.rs @@ -6,8 +6,10 @@ pub use self::syscall::{data, error, flag, number, scheme}; pub use self::fs::*; pub use self::process::*; +pub use self::time::*; pub use self::validate::*; +use self::data::TimeSpec; use self::error::{Error, Result, ENOSYS}; use self::number::*; @@ -17,6 +19,9 @@ pub mod fs; /// Process syscalls pub mod process; +/// Time syscalls +pub mod time; + /// Validate input pub mod validate; @@ -52,6 +57,7 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize SYS_IOPL => iopl(b), SYS_CLONE => clone(b, stack), SYS_YIELD => sched_yield(), + SYS_NANOSLEEP => nanosleep(validate_slice(b as *const TimeSpec, 1).map(|req| &req[0])?, validate_slice_mut(c as *mut TimeSpec, 1).ok().map(|rem| &mut rem[0])), SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?), SYS_GETUID => getuid(), SYS_GETGID => getgid(), @@ -59,6 +65,7 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize SYS_GETEGID => getegid(), SYS_SETUID => setuid(b as u32), SYS_SETGID => setgid(b as u32), + SYS_CLOCK_GETTIME => clock_gettime(b, validate_slice_mut(c as *mut TimeSpec, 1).map(|time| &mut time[0])?), SYS_PIPE2 => pipe2(validate_slice_mut(b as *mut usize, 2)?, c), SYS_PHYSALLOC => physalloc(b), SYS_PHYSFREE => physfree(b, c), diff --git a/syscall/process.rs b/syscall/process.rs index 61d0b03e..cdd768f4 100644 --- a/syscall/process.rs +++ b/syscall/process.rs @@ -770,11 +770,6 @@ pub fn physunmap(virtual_address: usize) -> Result<usize> { } } -pub fn sched_yield() -> Result<usize> { - unsafe { context::switch(); } - Ok(0) -} - pub fn setgid(gid: u32) -> Result<usize> { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; diff --git a/syscall/time.rs b/syscall/time.rs new file mode 100644 index 00000000..ca057738 --- /dev/null +++ b/syscall/time.rs @@ -0,0 +1,50 @@ +use arch; +use context; +use syscall::data::TimeSpec; +use syscall::error::*; +use syscall::flag::{CLOCK_REALTIME, CLOCK_MONOTONIC}; + +pub fn clock_gettime(clock: usize, time: &mut TimeSpec) -> Result<usize> { + match clock { + CLOCK_REALTIME => { + let arch_time = arch::time::realtime(); + time.tv_sec = arch_time.0 as i64; + time.tv_nsec = arch_time.1 as i32; + Ok(0) + }, + CLOCK_MONOTONIC => { + let arch_time = arch::time::monotonic(); + time.tv_sec = arch_time.0 as i64; + time.tv_nsec = arch_time.1 as i32; + Ok(0) + }, + _ => Err(Error::new(EINVAL)) + } +} + +pub fn nanosleep(req: &TimeSpec, rem_opt: Option<&mut TimeSpec>) -> Result<usize> { + let start = arch::time::monotonic(); + let sum = start.1 + req.tv_nsec as u64; + let end = (start.0 + req.tv_sec as u64 + sum / 1000000000, sum % 1000000000); + + loop { + unsafe { context::switch(); } + + let current = arch::time::monotonic(); + if current.0 > end.0 || (current.0 == end.0 && current.1 >= end.1) { + break; + } + } + + if let Some(mut rem) = rem_opt { + rem.tv_sec = 0; + rem.tv_nsec = 0; + } + + Ok(0) +} + +pub fn sched_yield() -> Result<usize> { + unsafe { context::switch(); } + Ok(0) +} -- GitLab