* WIP: Time syscalls

* Count time from PIT using low tickrate

* Implement realtime

* Implement nanosleep with a tight loop
This commit is contained in:
Jeremy Soller 2016-10-06 20:50:14 -06:00 committed by GitHub
parent 798f7c8808
commit 64cc730eac
11 changed files with 199 additions and 7 deletions

View file

@ -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),

View file

@ -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))?;

50
kernel/syscall/time.rs Normal file
View file

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