mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-21 08:26:30 +00:00
95 lines
2.1 KiB
Rust
95 lines
2.1 KiB
Rust
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
//! The system time of Asterinas.
|
|
#![feature(let_chains)]
|
|
#![no_std]
|
|
#![deny(unsafe_code)]
|
|
|
|
extern crate alloc;
|
|
|
|
use alloc::sync::Arc;
|
|
use core::time::Duration;
|
|
|
|
use clocksource::ClockSource;
|
|
pub use clocksource::Instant;
|
|
use component::{init_component, ComponentInitError};
|
|
use ostd::sync::Mutex;
|
|
use rtc::Driver;
|
|
use spin::Once;
|
|
|
|
mod clocksource;
|
|
mod rtc;
|
|
mod tsc;
|
|
|
|
pub const NANOS_PER_SECOND: u32 = 1_000_000_000;
|
|
pub static VDSO_DATA_HIGH_RES_UPDATE_FN: Once<Arc<dyn Fn(Instant, u64) + Sync + Send>> =
|
|
Once::new();
|
|
static RTC_DRIVER: Once<Arc<dyn Driver + Send + Sync>> = Once::new();
|
|
|
|
#[init_component]
|
|
fn time_init() -> Result<(), ComponentInitError> {
|
|
let rtc = rtc::init_rtc_driver().ok_or(ComponentInitError::Unknown)?;
|
|
RTC_DRIVER.call_once(|| rtc);
|
|
tsc::init();
|
|
Ok(())
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
|
pub struct SystemTime {
|
|
pub year: u16,
|
|
pub month: u8,
|
|
pub day: u8,
|
|
pub hour: u8,
|
|
pub minute: u8,
|
|
pub second: u8,
|
|
pub nanos: u64,
|
|
}
|
|
|
|
impl SystemTime {
|
|
pub(crate) const fn zero() -> Self {
|
|
Self {
|
|
year: 0,
|
|
month: 0,
|
|
day: 0,
|
|
hour: 0,
|
|
minute: 0,
|
|
second: 0,
|
|
nanos: 0,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub(crate) static READ_TIME: Mutex<SystemTime> = Mutex::new(SystemTime::zero());
|
|
pub(crate) static START_TIME: Once<SystemTime> = Once::new();
|
|
|
|
/// get real time
|
|
pub fn get_real_time() -> SystemTime {
|
|
read()
|
|
}
|
|
|
|
pub fn read() -> SystemTime {
|
|
update_time();
|
|
*READ_TIME.lock()
|
|
}
|
|
|
|
fn update_time() {
|
|
let mut lock = READ_TIME.lock();
|
|
*lock = RTC_DRIVER.get().unwrap().read_rtc();
|
|
}
|
|
|
|
/// Return the `START_TIME`, which is the actual time when doing calibrate.
|
|
pub fn read_start_time() -> SystemTime {
|
|
*START_TIME.get().unwrap()
|
|
}
|
|
|
|
/// Return the monotonic time from the tsc clocksource.
|
|
pub fn read_monotonic_time() -> Duration {
|
|
let instant = tsc::read_instant();
|
|
Duration::new(instant.secs(), instant.nanos())
|
|
}
|
|
|
|
/// Return the tsc clocksource.
|
|
pub fn default_clocksource() -> Arc<ClockSource> {
|
|
tsc::CLOCK.get().unwrap().clone()
|
|
}
|