diff --git a/kernel/aster-nix/src/syscall/alarm.rs b/kernel/aster-nix/src/syscall/alarm.rs index f6a66fe03..f1cc6e29c 100644 --- a/kernel/aster-nix/src/syscall/alarm.rs +++ b/kernel/aster-nix/src/syscall/alarm.rs @@ -3,13 +3,13 @@ use core::time::Duration; use super::SyscallReturn; -use crate::prelude::*; +use crate::{prelude::*, time::timer::Timeout}; pub fn sys_alarm(seconds: u32) -> Result { debug!("seconds = {}", seconds); let current = current!(); - let alarm_timer = current.alarm_timer(); + let alarm_timer = current.timer_manager().alarm_timer(); let remaining = alarm_timer.remain(); let mut remaining_secs = remaining.as_secs(); @@ -23,7 +23,7 @@ pub fn sys_alarm(seconds: u32) -> Result { return Ok(SyscallReturn::Return(remaining_secs as _)); } - alarm_timer.set_timeout(Duration::from_secs(seconds as u64)); + alarm_timer.set_timeout(Timeout::After(Duration::from_secs(seconds as u64))); Ok(SyscallReturn::Return(remaining_secs as _)) } diff --git a/kernel/aster-nix/src/time/core/timer.rs b/kernel/aster-nix/src/time/core/timer.rs index 5334cf4f1..bb191491c 100644 --- a/kernel/aster-nix/src/time/core/timer.rs +++ b/kernel/aster-nix/src/time/core/timer.rs @@ -15,6 +15,14 @@ use aster_frame::sync::SpinLock; use super::Clock; +/// A timeout, represented in one of the two ways. +pub enum Timeout { + /// The timeout is reached _after_ the `Duration` time is elapsed. + After(Duration), + /// The timeout is reached _when_ the clock's time is equal to `Duration`. + When(Duration), +} + /// A timer with periodic functionality. /// /// Setting the timer will trigger a callback function upon expiration of @@ -65,9 +73,15 @@ impl Timer { /// The registered callback function of this timer will be invoked /// when reaching timeout. If the timer has a valid interval, this timer /// will be set again with the interval when reaching timeout. - pub fn set_timeout(self: &Arc, timeout: Duration) { - let now = self.timer_manager.clock.read_time(); - let expired_time = now + timeout; + pub fn set_timeout(self: &Arc, timeout: Timeout) { + let expired_time = match timeout { + Timeout::After(timeout) => { + let now = self.timer_manager.clock.read_time(); + now + timeout + } + Timeout::When(timeout) => timeout, + }; + let timer_weak = Arc::downgrade(self); let new_timer_callback = Arc::new(TimerCallback::new( expired_time, @@ -107,6 +121,11 @@ impl Timer { pub fn timer_manager(&self) -> &Arc { &self.timer_manager } + + /// Returns the interval time of the current timer. + pub fn interval(&self) -> Duration { + *self.interval.lock_irq_disabled() + } } fn interval_timer_callback(timer: &Weak) { @@ -117,7 +136,7 @@ fn interval_timer_callback(timer: &Weak) { (timer.registered_callback)(); let interval = timer.interval.lock_irq_disabled(); if *interval != Duration::ZERO { - timer.set_timeout(*interval); + timer.set_timeout(Timeout::After(*interval)); } } diff --git a/kernel/aster-nix/src/time/wait.rs b/kernel/aster-nix/src/time/wait.rs index efd5c56dd..b8c920a06 100644 --- a/kernel/aster-nix/src/time/wait.rs +++ b/kernel/aster-nix/src/time/wait.rs @@ -4,7 +4,7 @@ use core::time::Duration; use aster_frame::sync::{WaitQueue, Waiter}; -use super::clocks::JIFFIES_TIMER_MANAGER; +use super::{clocks::JIFFIES_TIMER_MANAGER, timer::Timeout}; /// A trait that provide the timeout related function for [`WaitQueue`]`. pub trait WaitTimeout { @@ -34,7 +34,7 @@ impl WaitTimeout for WaitQueue { let jiffies_timer = JIFFIES_TIMER_MANAGER.get().unwrap().create_timer(move || { waker.wake_up(); }); - jiffies_timer.set_timeout(*timeout); + jiffies_timer.set_timeout(Timeout::After(*timeout)); let cancel_cond = { let jiffies_timer = jiffies_timer.clone(); diff --git a/kernel/aster-nix/src/vdso.rs b/kernel/aster-nix/src/vdso.rs index b2822973a..a9eaa0943 100644 --- a/kernel/aster-nix/src/vdso.rs +++ b/kernel/aster-nix/src/vdso.rs @@ -26,8 +26,8 @@ use spin::Once; use crate::{ fs::fs_resolver::{FsPath, FsResolver, AT_FDCWD}, - syscall::ClockID, - time::{clocks::MonotonicClock, SystemTime, START_TIME}, + syscall::ClockId, + time::{clocks::MonotonicClock, timer::Timeout, SystemTime, START_TIME}, vm::vmo::{Vmo, VmoOptions}, }; @@ -49,12 +49,12 @@ enum VdsoClockMode { /// Instant used in `VdsoData`. /// -/// Each `VdsoInstant` will store a instant information for a specified `ClockID`. +/// Each `VdsoInstant` will store a instant information for a specified `ClockId`. /// The `secs` field will record the seconds of the instant, /// and the `nanos_info` will store the nanoseconds of the instant /// (for `CLOCK_REALTIME_COARSE` and `CLOCK_MONOTONIC_COARSE`) or /// the calculation results of left-shift `nanos` with `lshift` -/// (for other high-resolution `ClockID`s). +/// (for other high-resolution `ClockId`s). #[repr(C)] #[derive(Debug, Default, Copy, Clone, Pod)] struct VdsoInstant { @@ -100,16 +100,16 @@ struct VdsoData { arch_data: ArchVdsoData, } -const HIGH_RES_CLOCK_IDS: [ClockID; 4] = [ - ClockID::CLOCK_REALTIME, - ClockID::CLOCK_MONOTONIC, - ClockID::CLOCK_MONOTONIC_RAW, - ClockID::CLOCK_BOOTTIME, +const HIGH_RES_CLOCK_IDS: [ClockId; 4] = [ + ClockId::CLOCK_REALTIME, + ClockId::CLOCK_MONOTONIC, + ClockId::CLOCK_MONOTONIC_RAW, + ClockId::CLOCK_BOOTTIME, ]; -const COARSE_RES_CLOCK_IDS: [ClockID; 2] = [ - ClockID::CLOCK_REALTIME_COARSE, - ClockID::CLOCK_MONOTONIC_COARSE, +const COARSE_RES_CLOCK_IDS: [ClockId; 2] = [ + ClockId::CLOCK_REALTIME_COARSE, + ClockId::CLOCK_MONOTONIC_COARSE, ]; impl VdsoData { @@ -159,7 +159,7 @@ impl VdsoData { fn update_high_res_instant(&mut self, instant: Instant, instant_cycles: u64) { self.last_cycles = instant_cycles; for clock_id in HIGH_RES_CLOCK_IDS { - let secs = if clock_id == ClockID::CLOCK_REALTIME { + let secs = if clock_id == ClockId::CLOCK_REALTIME { instant.secs() + START_SECS_COUNT.get().unwrap() } else { instant.secs() @@ -175,7 +175,7 @@ impl VdsoData { fn update_coarse_res_instant(&mut self, instant: Instant) { for clock_id in COARSE_RES_CLOCK_IDS { - let secs = if clock_id == ClockID::CLOCK_REALTIME_COARSE { + let secs = if clock_id == ClockId::CLOCK_REALTIME_COARSE { instant.secs() + START_SECS_COUNT.get().unwrap() } else { instant.secs() @@ -269,7 +269,7 @@ impl Vdso { } /// Update the requisite fields of the VDSO data in the `data_frame`. - fn update_data_frame_instant(&self, clockid: ClockID) { + fn update_data_frame_instant(&self, clockid: ClockId) { let clock_index = clockid as usize; let secs_offset = 0xA0 + clock_index * 0x10; let nanos_info_offset = 0xA8 + clock_index * 0x10; @@ -323,7 +323,7 @@ pub(super) fn init() { MonotonicClock::timer_manager().create_timer(update_vdso_coarse_res_instant), ); coarse_instant_timer.set_interval(Duration::from_millis(100)); - coarse_instant_timer.set_timeout(Duration::from_millis(100)); + coarse_instant_timer.set_timeout(Timeout::After(Duration::from_millis(100))); } /// Return the VDSO vmo.