1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-27 10:13:28 +04:00
rCore/kernel/src/syscall/time.rs

144 lines
3.2 KiB
Rust
Raw Normal View History

2019-02-22 10:10:24 +04:00
//! Syscalls for time
use super::*;
2019-03-12 07:49:17 +04:00
use crate::consts::USEC_PER_TICK;
2019-03-09 10:08:56 +04:00
use core::time::Duration;
2019-03-09 21:20:50 +04:00
use lazy_static::lazy_static;
2019-02-22 10:10:24 +04:00
2019-03-10 04:53:29 +04:00
/// should be initialized together
lazy_static! {
2019-03-12 07:49:17 +04:00
pub static ref EPOCH_BASE: u64 = crate::arch::timer::read_epoch();
pub static ref TICK_BASE: u64 = unsafe { crate::trap::TICK as u64 };
}
2019-03-10 04:53:29 +04:00
// 1ms msec
// 1us usec
// 1ns nsec
const USEC_PER_SEC: u64 = 1_000_000;
const MSEC_PER_SEC: u64 = 1_000;
const USEC_PER_MSEC: u64 = 1_000;
const NSEC_PER_USEC: u64 = 1_000;
/// Get time since epoch in usec
fn get_epoch_usec() -> u64 {
let tick_base = *TICK_BASE;
let epoch_base = *EPOCH_BASE;
let tick = unsafe { crate::trap::TICK as u64 };
(tick - tick_base) * USEC_PER_TICK as u64 + epoch_base * USEC_PER_SEC
}
#[repr(C)]
2019-03-09 10:08:56 +04:00
#[derive(Debug, Copy, Clone)]
pub struct TimeVal {
sec: u64,
usec: u64,
}
2019-03-07 05:47:36 +04:00
impl TimeVal {
pub fn to_msec(&self) -> u64 {
2019-03-10 04:53:29 +04:00
self.sec * MSEC_PER_SEC + self.usec / USEC_PER_MSEC
2019-03-07 05:47:36 +04:00
}
2019-03-10 04:53:29 +04:00
pub fn get_epoch() -> Self {
let usec = get_epoch_usec();
TimeVal {
sec: usec / USEC_PER_SEC,
usec: usec % USEC_PER_SEC,
}
2019-03-07 05:47:36 +04:00
}
}
2019-03-08 11:35:18 +04:00
#[repr(C)]
2019-03-09 10:08:56 +04:00
#[derive(Debug, Copy, Clone)]
2019-03-08 11:35:18 +04:00
pub struct TimeSpec {
sec: u64,
nsec: u64,
}
impl TimeSpec {
2019-03-09 10:08:56 +04:00
pub fn to_duration(&self) -> Duration {
Duration::new(self.sec, self.nsec as u32)
2019-03-08 11:35:18 +04:00
}
2019-03-10 04:53:29 +04:00
pub fn get_epoch() -> Self {
let usec = get_epoch_usec();
TimeSpec {
sec: usec / USEC_PER_SEC,
nsec: usec % USEC_PER_SEC * NSEC_PER_USEC,
}
}
2019-03-08 11:35:18 +04:00
}
pub fn sys_gettimeofday(tv: *mut TimeVal, tz: *const u8) -> SysResult {
2019-03-08 11:35:18 +04:00
info!("gettimeofday: tv: {:?}, tz: {:?}", tv, tz);
2019-03-04 12:25:57 +04:00
if tz as usize != 0 {
return Err(SysError::EINVAL);
}
let proc = process();
2019-03-22 19:45:57 +04:00
proc.vm.check_write_ptr(tv)?;
2019-03-04 12:25:57 +04:00
2019-03-10 04:53:29 +04:00
let timeval = TimeVal::get_epoch();
unsafe {
*tv = timeval;
}
2019-03-04 12:25:57 +04:00
Ok(0)
}
2019-03-08 11:35:18 +04:00
pub fn sys_clock_gettime(clock: usize, ts: *mut TimeSpec) -> SysResult {
info!("clock_gettime: clock: {:?}, ts: {:?}", clock, ts);
let proc = process();
2019-03-22 19:45:57 +04:00
proc.vm.check_write_ptr(ts)?;
2019-03-08 11:35:18 +04:00
2019-03-10 04:53:29 +04:00
let timespec = TimeSpec::get_epoch();
2019-03-08 11:35:18 +04:00
unsafe {
*ts = timespec;
}
Ok(0)
}
pub fn sys_time(time: *mut u64) -> SysResult {
2019-03-10 04:53:29 +04:00
let sec = get_epoch_usec() / USEC_PER_SEC;
if time as usize != 0 {
let proc = process();
2019-03-22 19:45:57 +04:00
proc.vm.check_write_ptr(time)?;
unsafe {
time.write(sec as u64);
}
}
2019-03-08 15:04:39 +04:00
Ok(sec as usize)
}
// ignore other fields for now
#[repr(C)]
pub struct RUsage {
utime: TimeVal,
2019-03-27 14:35:08 +04:00
stime: TimeVal,
}
pub fn sys_getrusage(who: usize, rusage: *mut RUsage) -> SysResult {
info!("getrusage: who: {}, rusage: {:?}", who, rusage);
let proc = process();
2019-03-22 19:45:57 +04:00
proc.vm.check_write_ptr(rusage)?;
let tick_base = *TICK_BASE;
let tick = unsafe { crate::trap::TICK as u64 };
let usec = (tick - tick_base) * USEC_PER_TICK as u64;
let new_rusage = RUsage {
utime: TimeVal {
sec: usec / USEC_PER_SEC,
usec: usec % USEC_PER_SEC,
},
stime: TimeVal {
sec: usec / USEC_PER_SEC,
usec: usec % USEC_PER_SEC,
2019-03-27 14:35:08 +04:00
},
};
2019-03-27 14:35:08 +04:00
unsafe { *rusage = new_rusage };
Ok(0)
}