mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-29 04:13:24 +00:00
Refactor project structure
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
bd878dd1c9
commit
e3c227ae06
130
kernel/aster-nix/src/time/mod.rs
Normal file
130
kernel/aster-nix/src/time/mod.rs
Normal file
@ -0,0 +1,130 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
#![allow(non_camel_case_types)]
|
||||
use core::time::Duration;
|
||||
|
||||
use aster_time::read_monotonic_time;
|
||||
|
||||
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;
|
||||
pub type clock_t = i64;
|
||||
|
||||
#[derive(Debug, Copy, Clone, TryFromInt, PartialEq)]
|
||||
#[repr(i32)]
|
||||
pub enum ClockID {
|
||||
CLOCK_REALTIME = 0,
|
||||
CLOCK_MONOTONIC = 1,
|
||||
CLOCK_PROCESS_CPUTIME_ID = 2,
|
||||
CLOCK_THREAD_CPUTIME_ID = 3,
|
||||
CLOCK_MONOTONIC_RAW = 4,
|
||||
CLOCK_REALTIME_COARSE = 5,
|
||||
CLOCK_MONOTONIC_COARSE = 6,
|
||||
CLOCK_BOOTTIME = 7,
|
||||
}
|
||||
|
||||
/// A list of all supported clock IDs for time-related functions.
|
||||
pub const ALL_SUPPORTED_CLOCK_IDS: [ClockID; 6] = [
|
||||
ClockID::CLOCK_REALTIME,
|
||||
ClockID::CLOCK_REALTIME_COARSE,
|
||||
ClockID::CLOCK_MONOTONIC,
|
||||
ClockID::CLOCK_MONOTONIC_COARSE,
|
||||
ClockID::CLOCK_MONOTONIC_RAW,
|
||||
ClockID::CLOCK_BOOTTIME,
|
||||
];
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Default, Copy, Clone, Pod)]
|
||||
pub struct timespec_t {
|
||||
pub sec: time_t,
|
||||
pub nsec: i64,
|
||||
}
|
||||
|
||||
impl From<Duration> for timespec_t {
|
||||
fn from(duration: Duration) -> timespec_t {
|
||||
let sec = duration.as_secs() as time_t;
|
||||
let nsec = duration.subsec_nanos() as i64;
|
||||
debug_assert!(sec >= 0); // nsec >= 0 always holds
|
||||
timespec_t { sec, nsec }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<timespec_t> for Duration {
|
||||
fn from(timespec: timespec_t) -> Self {
|
||||
Duration::new(timespec.sec as u64, timespec.nsec as u32)
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Default, Copy, Clone, Pod)]
|
||||
pub struct timeval_t {
|
||||
pub sec: time_t,
|
||||
pub usec: suseconds_t,
|
||||
}
|
||||
|
||||
impl From<Duration> for timeval_t {
|
||||
fn from(duration: Duration) -> timeval_t {
|
||||
let sec = duration.as_secs() as time_t;
|
||||
let usec = duration.subsec_micros() as suseconds_t;
|
||||
debug_assert!(sec >= 0); // usec >= 0 always holds
|
||||
timeval_t { sec, usec }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<timeval_t> for Duration {
|
||||
fn from(timeval: timeval_t) -> Self {
|
||||
Duration::new(timeval.sec as u64, (timeval.usec * 1000) as u32)
|
||||
}
|
||||
}
|
||||
|
||||
/// The various flags for setting POSIX.1b interval timers:
|
||||
pub const TIMER_ABSTIME: i32 = 0x01;
|
||||
|
||||
pub fn now_as_duration(clock_id: &ClockID) -> Result<Duration> {
|
||||
match clock_id {
|
||||
ClockID::CLOCK_MONOTONIC
|
||||
| ClockID::CLOCK_MONOTONIC_COARSE
|
||||
| ClockID::CLOCK_MONOTONIC_RAW
|
||||
| ClockID::CLOCK_BOOTTIME => Ok(read_monotonic_time()),
|
||||
ClockID::CLOCK_REALTIME | ClockID::CLOCK_REALTIME_COARSE => {
|
||||
let now = SystemTime::now();
|
||||
now.duration_since(&SystemTime::UNIX_EPOCH)
|
||||
}
|
||||
_ => {
|
||||
warn!(
|
||||
"unsupported clock_id: {:?}, treat it as CLOCK_REALTIME",
|
||||
clock_id
|
||||
);
|
||||
let now = SystemTime::now();
|
||||
now.duration_since(&SystemTime::UNIX_EPOCH)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Unix time measures time by the number of seconds that have elapsed since
|
||||
/// the Unix epoch, without adjustments made due to leap seconds.
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Default, Copy, Clone, Pod)]
|
||||
pub struct UnixTime {
|
||||
sec: u32,
|
||||
}
|
||||
|
||||
impl From<Duration> for UnixTime {
|
||||
fn from(duration: Duration) -> Self {
|
||||
Self {
|
||||
sec: duration.as_secs() as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<UnixTime> for Duration {
|
||||
fn from(time: UnixTime) -> Self {
|
||||
Duration::from_secs(time.sec as _)
|
||||
}
|
||||
}
|
110
kernel/aster-nix/src/time/system_time.rs
Normal file
110
kernel/aster-nix/src/time/system_time.rs
Normal file
@ -0,0 +1,110 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use core::time::Duration;
|
||||
|
||||
use aster_time::{read_monotonic_time, read_start_time};
|
||||
use time::{Date, Month, PrimitiveDateTime, Time};
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
/// 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 Ok(date) = Date::from_ordinal_date(1970, 1) else {
|
||||
unreachable!()
|
||||
};
|
||||
let Ok(time) = Time::from_hms_nano(0, 0, 0, 0) else {
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
SystemTime(PrimitiveDateTime::new(date, time))
|
||||
}
|
||||
|
||||
/// Returns the current system time
|
||||
pub fn now() -> Self {
|
||||
let start = read_start_time();
|
||||
|
||||
// The get real time result should always be valid
|
||||
convert_system_time(start)
|
||||
.unwrap()
|
||||
.checked_add(read_monotonic_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(SystemTime)
|
||||
}
|
||||
|
||||
/// 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(SystemTime)
|
||||
}
|
||||
|
||||
/// 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 aster_frame::time::Time to System time
|
||||
fn convert_system_time(system_time: aster_time::SystemTime) -> 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_nano(
|
||||
system_time.hour,
|
||||
system_time.minute,
|
||||
system_time.second,
|
||||
system_time.nanos.try_into().unwrap(),
|
||||
) {
|
||||
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)
|
||||
}
|
Reference in New Issue
Block a user