add syscall time

This commit is contained in:
Jianfeng Jiang 2023-03-09 16:55:57 +08:00 committed by Tate, Hongliang Tian
parent 1e83996d09
commit 72e0725a0e
6 changed files with 132 additions and 0 deletions

17
src/Cargo.lock generated
View File

@ -310,6 +310,7 @@ dependencies = [
"pod",
"ringbuffer",
"spin 0.9.4",
"time",
"typeflags",
"typeflags-util",
"virtio-input-decoder",
@ -559,6 +560,22 @@ dependencies = [
"syn",
]
[[package]]
name = "time"
version = "0.3.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890"
dependencies = [
"serde",
"time-core",
]
[[package]]
name = "time-core"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
[[package]]
name = "toml"
version = "0.7.2"

View File

@ -19,6 +19,7 @@ cpio-decoder = {path="../cpio-decoder"}
virtio-input-decoder = "0.1.4"
ascii = { version = "1.1", default-features = false, features = ["alloc"] }
intrusive-collections = "0.9.5"
time = { version = "0.3", default-features = false, features = ["alloc"] }
# parse elf file
xmas-elf = "0.8.0"

View File

@ -207,6 +207,7 @@ define_syscall_nums!(
SYS_PRCTL = 157,
SYS_ARCH_PRCTL = 158,
SYS_GETTID = 186,
SYS_TIME = 201,
SYS_FUTEX = 202,
SYS_SET_TID_ADDRESS = 218,
SYS_CLOCK_NANOSLEEP = 230,
@ -335,6 +336,7 @@ pub fn syscall_dispatch(
SYS_PRCTL => syscall_handler!(5, sys_prctl, args),
SYS_ARCH_PRCTL => syscall_handler!(2, sys_arch_prctl, args, context),
SYS_GETTID => syscall_handler!(0, sys_gettid),
SYS_TIME => syscall_handler!(1, sys_time, args),
SYS_FUTEX => syscall_handler!(6, sys_futex, args),
SYS_SET_TID_ADDRESS => syscall_handler!(1, sys_set_tid_address, args),
SYS_CLOCK_NANOSLEEP => syscall_handler!(4, sys_clock_nanosleep, args),

View File

@ -0,0 +1,16 @@
use crate::log_syscall_entry;
use crate::prelude::*;
use crate::time::SystemTime;
use crate::util::write_val_to_user;
use super::SyscallReturn;
use super::SYS_TIME;
pub fn sys_time(tloc: Vaddr) -> Result<SyscallReturn> {
log_syscall_entry!(SYS_TIME);
debug!("tloc = 0x{tloc:x}");
let now = SystemTime::now();
let now_as_secs = now.duration_since(&SystemTime::UNIX_EPOCH)?.as_secs();
write_val_to_user(tloc, &now_as_secs)?;
Ok(SyscallReturn::Return(0))
}

View File

@ -3,6 +3,9 @@ use core::time::Duration;
use crate::prelude::*;
mod system_time;
pub use system_time::SystemTime;
pub type clockid_t = i32;
pub type time_t = i64;
pub type suseconds_t = i64;

View File

@ -0,0 +1,93 @@
use core::time::Duration;
use crate::prelude::*;
use jinux_frame::time::get_real_time;
use time::{Date, Month, PrimitiveDateTime, Time};
/// This struct corresponds to `SystemTime` in Rust std.
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct SystemTime(PrimitiveDateTime);
impl SystemTime {
/// The unix epoch, which represents 1970-01-01 00:00:00
pub const UNIX_EPOCH: SystemTime = SystemTime::unix_epoch();
const fn unix_epoch() -> Self {
// 1970-01-01 00:00:00
let date = Date::__from_ordinal_date_unchecked(1970, 1);
let time = Time::__from_hms_nanos_unchecked(0, 0, 0, 0);
SystemTime(PrimitiveDateTime::new(date, time))
}
/// Returns the current system time
pub fn now() -> Self {
let system_time = get_real_time();
// The get real time result should always be valid
convert_system_time(system_time).unwrap()
}
/// Add a duration to self. If the result does not exceed inner bounds return Some(t), else return None.
pub fn checked_add(&self, duration: Duration) -> Option<Self> {
let duration = convert_to_time_duration(duration);
self.0.checked_add(duration).map(|inner| SystemTime(inner))
}
/// Substract a duration from self. If the result does not exceed inner bounds return Some(t), else return None.
pub fn checked_sub(&self, duration: Duration) -> Option<Self> {
let duration = convert_to_time_duration(duration);
self.0.checked_sub(duration).map(|inner| SystemTime(inner))
}
/// Returns the duration since an earlier time. Return error if `earlier` is later than self.
pub fn duration_since(&self, earlier: &SystemTime) -> Result<Duration> {
if self.0 < earlier.0 {
return_errno_with_message!(
Errno::EINVAL,
"duration_since can only accept an earlier time"
);
}
let duration = self.0 - earlier.0;
Ok(convert_to_core_duration(duration))
}
/// Return the difference between current time and the time when self was created.
/// Return Error if current time is earlier than creating time.
/// The error can happen if self was created by checked_add.
pub fn elapsed(&self) -> Result<Duration> {
let now = SystemTime::now();
now.duration_since(self)
}
}
/// convert jinux_frame::time::Time to System time
fn convert_system_time(system_time: jinux_frame::time::Time) -> Result<SystemTime> {
let month = match Month::try_from(system_time.month) {
Ok(month) => month,
Err(_) => return_errno_with_message!(Errno::EINVAL, "unknown month in system time"),
};
let date = match Date::from_calendar_date(system_time.year as _, month, system_time.day) {
Ok(date) => date,
Err(_) => return_errno_with_message!(Errno::EINVAL, "Invalid system date"),
};
let time_ = match Time::from_hms(system_time.hour, system_time.minute, system_time.second) {
Ok(time_) => time_,
Err(_) => return_errno_with_message!(Errno::EINVAL, "Invalid system time"),
};
Ok(SystemTime(PrimitiveDateTime::new(date, time_)))
}
/// FIXME: need to further check precision loss
/// convert core::time::Duration to time::Duration
const fn convert_to_time_duration(duration: Duration) -> time::Duration {
let seconds = duration.as_secs() as i64;
let nanoseconds = duration.subsec_nanos() as i32;
time::Duration::new(seconds, nanoseconds)
}
/// FIXME: need to further check precision loss
/// convert time::Duration to core::time::Duration
const fn convert_to_core_duration(duration: time::Duration) -> Duration {
let seconds = duration.whole_seconds() as u64;
let nanoseconds = duration.subsec_nanoseconds() as u32;
Duration::new(seconds, nanoseconds)
}