Enable Timer to set an absolute time

This commit is contained in:
Chen Chengjun
2024-05-31 18:22:55 +08:00
committed by Tate, Hongliang Tian
parent e952a16954
commit 13fd173b24
4 changed files with 44 additions and 25 deletions

View File

@ -3,13 +3,13 @@
use core::time::Duration; use core::time::Duration;
use super::SyscallReturn; use super::SyscallReturn;
use crate::prelude::*; use crate::{prelude::*, time::timer::Timeout};
pub fn sys_alarm(seconds: u32) -> Result<SyscallReturn> { pub fn sys_alarm(seconds: u32) -> Result<SyscallReturn> {
debug!("seconds = {}", seconds); debug!("seconds = {}", seconds);
let current = current!(); let current = current!();
let alarm_timer = current.alarm_timer(); let alarm_timer = current.timer_manager().alarm_timer();
let remaining = alarm_timer.remain(); let remaining = alarm_timer.remain();
let mut remaining_secs = remaining.as_secs(); let mut remaining_secs = remaining.as_secs();
@ -23,7 +23,7 @@ pub fn sys_alarm(seconds: u32) -> Result<SyscallReturn> {
return Ok(SyscallReturn::Return(remaining_secs as _)); 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 _)) Ok(SyscallReturn::Return(remaining_secs as _))
} }

View File

@ -15,6 +15,14 @@ use aster_frame::sync::SpinLock;
use super::Clock; 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. /// A timer with periodic functionality.
/// ///
/// Setting the timer will trigger a callback function upon expiration of /// 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 /// The registered callback function of this timer will be invoked
/// when reaching timeout. If the timer has a valid interval, this timer /// when reaching timeout. If the timer has a valid interval, this timer
/// will be set again with the interval when reaching timeout. /// will be set again with the interval when reaching timeout.
pub fn set_timeout(self: &Arc<Self>, timeout: Duration) { pub fn set_timeout(self: &Arc<Self>, timeout: Timeout) {
let now = self.timer_manager.clock.read_time(); let expired_time = match timeout {
let expired_time = now + 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 timer_weak = Arc::downgrade(self);
let new_timer_callback = Arc::new(TimerCallback::new( let new_timer_callback = Arc::new(TimerCallback::new(
expired_time, expired_time,
@ -107,6 +121,11 @@ impl Timer {
pub fn timer_manager(&self) -> &Arc<TimerManager> { pub fn timer_manager(&self) -> &Arc<TimerManager> {
&self.timer_manager &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<Timer>) { fn interval_timer_callback(timer: &Weak<Timer>) {
@ -117,7 +136,7 @@ fn interval_timer_callback(timer: &Weak<Timer>) {
(timer.registered_callback)(); (timer.registered_callback)();
let interval = timer.interval.lock_irq_disabled(); let interval = timer.interval.lock_irq_disabled();
if *interval != Duration::ZERO { if *interval != Duration::ZERO {
timer.set_timeout(*interval); timer.set_timeout(Timeout::After(*interval));
} }
} }

View File

@ -4,7 +4,7 @@ use core::time::Duration;
use aster_frame::sync::{WaitQueue, Waiter}; 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`]`. /// A trait that provide the timeout related function for [`WaitQueue`]`.
pub trait WaitTimeout { pub trait WaitTimeout {
@ -34,7 +34,7 @@ impl WaitTimeout for WaitQueue {
let jiffies_timer = JIFFIES_TIMER_MANAGER.get().unwrap().create_timer(move || { let jiffies_timer = JIFFIES_TIMER_MANAGER.get().unwrap().create_timer(move || {
waker.wake_up(); waker.wake_up();
}); });
jiffies_timer.set_timeout(*timeout); jiffies_timer.set_timeout(Timeout::After(*timeout));
let cancel_cond = { let cancel_cond = {
let jiffies_timer = jiffies_timer.clone(); let jiffies_timer = jiffies_timer.clone();

View File

@ -26,8 +26,8 @@ use spin::Once;
use crate::{ use crate::{
fs::fs_resolver::{FsPath, FsResolver, AT_FDCWD}, fs::fs_resolver::{FsPath, FsResolver, AT_FDCWD},
syscall::ClockID, syscall::ClockId,
time::{clocks::MonotonicClock, SystemTime, START_TIME}, time::{clocks::MonotonicClock, timer::Timeout, SystemTime, START_TIME},
vm::vmo::{Vmo, VmoOptions}, vm::vmo::{Vmo, VmoOptions},
}; };
@ -49,12 +49,12 @@ enum VdsoClockMode {
/// Instant used in `VdsoData`. /// 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, /// The `secs` field will record the seconds of the instant,
/// and the `nanos_info` will store the nanoseconds of the instant /// and the `nanos_info` will store the nanoseconds of the instant
/// (for `CLOCK_REALTIME_COARSE` and `CLOCK_MONOTONIC_COARSE`) or /// (for `CLOCK_REALTIME_COARSE` and `CLOCK_MONOTONIC_COARSE`) or
/// the calculation results of left-shift `nanos` with `lshift` /// the calculation results of left-shift `nanos` with `lshift`
/// (for other high-resolution `ClockID`s). /// (for other high-resolution `ClockId`s).
#[repr(C)] #[repr(C)]
#[derive(Debug, Default, Copy, Clone, Pod)] #[derive(Debug, Default, Copy, Clone, Pod)]
struct VdsoInstant { struct VdsoInstant {
@ -100,16 +100,16 @@ struct VdsoData {
arch_data: ArchVdsoData, arch_data: ArchVdsoData,
} }
const HIGH_RES_CLOCK_IDS: [ClockID; 4] = [ const HIGH_RES_CLOCK_IDS: [ClockId; 4] = [
ClockID::CLOCK_REALTIME, ClockId::CLOCK_REALTIME,
ClockID::CLOCK_MONOTONIC, ClockId::CLOCK_MONOTONIC,
ClockID::CLOCK_MONOTONIC_RAW, ClockId::CLOCK_MONOTONIC_RAW,
ClockID::CLOCK_BOOTTIME, ClockId::CLOCK_BOOTTIME,
]; ];
const COARSE_RES_CLOCK_IDS: [ClockID; 2] = [ const COARSE_RES_CLOCK_IDS: [ClockId; 2] = [
ClockID::CLOCK_REALTIME_COARSE, ClockId::CLOCK_REALTIME_COARSE,
ClockID::CLOCK_MONOTONIC_COARSE, ClockId::CLOCK_MONOTONIC_COARSE,
]; ];
impl VdsoData { impl VdsoData {
@ -159,7 +159,7 @@ impl VdsoData {
fn update_high_res_instant(&mut self, instant: Instant, instant_cycles: u64) { fn update_high_res_instant(&mut self, instant: Instant, instant_cycles: u64) {
self.last_cycles = instant_cycles; self.last_cycles = instant_cycles;
for clock_id in HIGH_RES_CLOCK_IDS { 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() instant.secs() + START_SECS_COUNT.get().unwrap()
} else { } else {
instant.secs() instant.secs()
@ -175,7 +175,7 @@ impl VdsoData {
fn update_coarse_res_instant(&mut self, instant: Instant) { fn update_coarse_res_instant(&mut self, instant: Instant) {
for clock_id in COARSE_RES_CLOCK_IDS { 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() instant.secs() + START_SECS_COUNT.get().unwrap()
} else { } else {
instant.secs() instant.secs()
@ -269,7 +269,7 @@ impl Vdso {
} }
/// Update the requisite fields of the VDSO data in the `data_frame`. /// 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 clock_index = clockid as usize;
let secs_offset = 0xA0 + clock_index * 0x10; let secs_offset = 0xA0 + clock_index * 0x10;
let nanos_info_offset = 0xA8 + 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), MonotonicClock::timer_manager().create_timer(update_vdso_coarse_res_instant),
); );
coarse_instant_timer.set_interval(Duration::from_millis(100)); 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. /// Return the VDSO vmo.