mirror of
https://github.com/edera-dev/sprout.git
synced 2025-12-19 18:40:18 +00:00
82 lines
2.2 KiB
Rust
82 lines
2.2 KiB
Rust
|
|
use std::time::Duration;
|
||
|
|
|
||
|
|
/// Support for aarch64 timers.
|
||
|
|
#[cfg(target_arch = "aarch64")]
|
||
|
|
pub mod aarch64;
|
||
|
|
|
||
|
|
/// Support for x86_64 timers.
|
||
|
|
#[cfg(target_arch = "x86_64")]
|
||
|
|
pub mod x86_64;
|
||
|
|
|
||
|
|
/// The tick frequency of the platform.
|
||
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||
|
|
pub enum TickFrequency {
|
||
|
|
/// The platform provides the tick frequency.
|
||
|
|
Hardware(u64),
|
||
|
|
/// The tick frequency is measured internally.
|
||
|
|
Measured(u64, Duration),
|
||
|
|
}
|
||
|
|
|
||
|
|
impl TickFrequency {
|
||
|
|
/// Acquire the tick frequency reported by the platform.
|
||
|
|
fn ticks(&self) -> u64 {
|
||
|
|
match self {
|
||
|
|
TickFrequency::Hardware(frequency) => *frequency,
|
||
|
|
TickFrequency::Measured(frequency, _) => *frequency,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Calculate the nanoseconds represented by a tick.
|
||
|
|
fn nanos(&self) -> f64 {
|
||
|
|
1.0e9_f64 / (self.ticks() as f64)
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Produce a duration from the provided elapsed `ticks` value.
|
||
|
|
fn duration(&self, ticks: u64) -> Duration {
|
||
|
|
let accuracy = self.nanos();
|
||
|
|
let nanos = ticks as f64 * accuracy;
|
||
|
|
Duration::from_nanos(nanos as u64)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Acquire the tick value reported by the platform.
|
||
|
|
fn arch_ticks() -> u64 {
|
||
|
|
#[cfg(target_arch = "aarch64")]
|
||
|
|
return aarch64::ticks();
|
||
|
|
#[cfg(target_arch = "x86_64")]
|
||
|
|
return x86_64::ticks();
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Acquire the tick frequency reported by the platform.
|
||
|
|
fn arch_frequency() -> TickFrequency {
|
||
|
|
#[cfg(target_arch = "aarch64")]
|
||
|
|
return aarch64::frequency();
|
||
|
|
#[cfg(target_arch = "x86_64")]
|
||
|
|
return x86_64::frequency();
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Platform timer that allows measurement of the elapsed time.
|
||
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||
|
|
pub struct PlatformTimer {
|
||
|
|
/// The start tick value.
|
||
|
|
start: u64,
|
||
|
|
/// The tick frequency of the platform.
|
||
|
|
frequency: TickFrequency,
|
||
|
|
}
|
||
|
|
|
||
|
|
impl PlatformTimer {
|
||
|
|
/// Start a platform timer at the current instant.
|
||
|
|
pub fn start() -> Self {
|
||
|
|
Self {
|
||
|
|
start: arch_ticks(),
|
||
|
|
frequency: arch_frequency(),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Measure the elapsed duration since the timer was started.
|
||
|
|
pub fn elapsed(&self) -> Duration {
|
||
|
|
let duration = arch_ticks() - self.start;
|
||
|
|
self.frequency.duration(duration)
|
||
|
|
}
|
||
|
|
}
|