diff --git a/kernel/comps/time/src/clocksource.rs b/kernel/comps/time/src/clocksource.rs index 61780bb0d..3cd216128 100644 --- a/kernel/comps/time/src/clocksource.rs +++ b/kernel/comps/time/src/clocksource.rs @@ -16,9 +16,10 @@ use core::{cmp::max, ops::Add, time::Duration}; use aster_util::coeff::Coeff; use ostd::sync::{LocalIrqDisabled, RwLock}; -use crate::NANOS_PER_SECOND; +const NANOS_PER_SECOND: u32 = 1_000_000_000; /// `ClockSource` is an abstraction for hardware-assisted timing mechanisms. +/// /// A `ClockSource` can be created based on any counter that operates at a stable frequency. /// Users are able to measure time by retrieving `Instant` from this source. /// @@ -60,8 +61,9 @@ pub struct ClockSource { impl ClockSource { /// Creates a new `ClockSource` instance. - /// Require basic information of based time counter, including the function for reading cycles, - /// the frequency and the maximum delay seconds to update this `ClockSource`. + /// + /// This method requires basic information of the time counter, including the function for + /// reading cycles, the frequency, and the maximum delay seconds to update this `ClockSource`. /// The `ClockSource` also calculates a reliable `Coeff` based on the counter's frequency and /// the maximum delay seconds. This `Coeff` is used to convert the number of cycles into /// the duration of time that has passed for those cycles. @@ -71,7 +73,7 @@ impl ClockSource { read_cycles: Arc u64 + Sync + Send>, ) -> Self { let base = ClockSourceBase::new(freq, max_delay_secs); - // Too big `max_delay_secs` will lead to a low resolution Coeff. + // Too big `max_delay_secs` will lead to a low resolution `Coeff`. debug_assert!(max_delay_secs < 600); let coeff = Coeff::new(NANOS_PER_SECOND as u64, freq, max_delay_secs * freq); Self { diff --git a/kernel/comps/time/src/lib.rs b/kernel/comps/time/src/lib.rs index 455c7a921..cde6ecb8c 100644 --- a/kernel/comps/time/src/lib.rs +++ b/kernel/comps/time/src/lib.rs @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MPL-2.0 //! The system time of Asterinas. + #![feature(let_chains)] #![no_std] #![deny(unsafe_code)] @@ -10,10 +11,8 @@ extern crate alloc; use alloc::sync::Arc; use core::time::Duration; -use clocksource::ClockSource; -pub use clocksource::Instant; +pub use clocksource::{ClockSource, Instant}; use component::{init_component, ComponentInitError}; -use ostd::sync::Mutex; use rtc::Driver; use spin::Once; @@ -21,9 +20,8 @@ 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> = - Once::new(); +pub static VDSO_DATA_HIGH_RES_UPDATE_FN: Once = Once::new(); + static RTC_DRIVER: Once> = Once::new(); #[init_component] @@ -45,50 +43,20 @@ pub struct SystemTime { 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, - } - } -} +static START_TIME: Once = Once::new(); -pub(crate) static READ_TIME: Mutex = Mutex::new(SystemTime::zero()); -pub(crate) static START_TIME: Once = 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. +/// Returns the `START_TIME`, which is the system time when calibrating. pub fn read_start_time() -> SystemTime { *START_TIME.get().unwrap() } -/// Return the monotonic time from the tsc clocksource. +/// Returns 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. +/// Returns the default (TSC) clocksource. pub fn default_clocksource() -> Arc { tsc::CLOCK.get().unwrap().clone() } diff --git a/kernel/comps/time/src/tsc.rs b/kernel/comps/time/src/tsc.rs index dab55ffa6..c8ad04738 100644 --- a/kernel/comps/time/src/tsc.rs +++ b/kernel/comps/time/src/tsc.rs @@ -1,8 +1,7 @@ // SPDX-License-Identifier: MPL-2.0 //! This module provide a instance of `ClockSource` based on TSC. -//! -//! Use `init` to initialize this module. + use alloc::sync::Arc; use core::sync::atomic::{AtomicU64, Ordering}; @@ -17,12 +16,12 @@ use crate::{ START_TIME, VDSO_DATA_HIGH_RES_UPDATE_FN, }; -/// A instance of TSC clocksource. -pub static CLOCK: Once> = Once::new(); +/// An instance of the TSC clocksource. +pub(super) static CLOCK: Once> = Once::new(); const MAX_DELAY_SECS: u64 = 100; -/// Init tsc clocksource module. +/// Initializes the TSC clocksource module. pub(super) fn init() { init_clock(); calibrate(); @@ -39,15 +38,15 @@ fn init_clock() { }); } -/// Calibrate the TSC and system time based on the RTC time. +/// Calibrates the TSC and system time based on the RTC time. fn calibrate() { let clock = CLOCK.get().unwrap(); let cycles = clock.read_cycles(); clock.calibrate(cycles); - START_TIME.call_once(crate::read); + START_TIME.call_once(|| crate::RTC_DRIVER.get().unwrap().read_rtc()); } -/// Read an `Instant` of tsc clocksource. +/// Reads an `Instant` of the TSC clocksource. pub(super) fn read_instant() -> Instant { let clock = CLOCK.get().unwrap(); clock.read_instant() @@ -57,7 +56,7 @@ fn update_clocksource() { let clock = CLOCK.get().unwrap(); clock.update(); - // Update vdso data. + // Update vDSO data. if let Some(update_fn) = VDSO_DATA_HIGH_RES_UPDATE_FN.get() { let (last_instant, last_cycles) = clock.last_record(); update_fn(last_instant, last_cycles); @@ -84,6 +83,6 @@ fn init_timer() { } }; - // TODO: re-organize the code structure and use the `Timer` to achieve the updating. + // TODO: Re-organize the code structure and use the `Timer` to achieve the updating. timer::register_callback_on_cpu(update); } diff --git a/kernel/src/vdso.rs b/kernel/src/vdso.rs index 0211c329e..30f72ebb4 100644 --- a/kernel/src/vdso.rs +++ b/kernel/src/vdso.rs @@ -361,7 +361,7 @@ pub(super) fn init_in_first_kthread() { init_start_secs_count(); init_vdso(); - aster_time::VDSO_DATA_HIGH_RES_UPDATE_FN.call_once(|| Arc::new(update_vdso_high_res_instant)); + aster_time::VDSO_DATA_HIGH_RES_UPDATE_FN.call_once(|| update_vdso_high_res_instant); // Coarse resolution clock IDs directly read the instant stored in vDSO data without // using coefficients for calculation, thus the related instant requires more frequent updating.