mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-08 21:06:48 +00:00
add syscall time
This commit is contained in:
parent
1e83996d09
commit
72e0725a0e
17
src/Cargo.lock
generated
17
src/Cargo.lock
generated
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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),
|
||||
|
16
src/services/libs/jinux-std/src/syscall/time.rs
Normal file
16
src/services/libs/jinux-std/src/syscall/time.rs
Normal 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))
|
||||
}
|
@ -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;
|
||||
|
93
src/services/libs/jinux-std/src/time/system_time.rs
Normal file
93
src/services/libs/jinux-std/src/time/system_time.rs
Normal 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)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user