time: optimize math by reducing fractions at compile time.
For example, `as_micros`, `from_micros` now are noops if tick rate is 1MHz.
This commit is contained in:
parent
eb922c4655
commit
640ddc9481
@ -1,7 +1,7 @@
|
|||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
|
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
|
||||||
|
|
||||||
use super::TICKS_PER_SECOND;
|
use super::{GCD_1K, GCD_1M, TICKS_PER_SECOND};
|
||||||
|
|
||||||
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
@ -28,12 +28,12 @@ impl Duration {
|
|||||||
|
|
||||||
/// Convert the `Duration` to milliseconds, rounding down.
|
/// Convert the `Duration` to milliseconds, rounding down.
|
||||||
pub const fn as_millis(&self) -> u64 {
|
pub const fn as_millis(&self) -> u64 {
|
||||||
self.ticks * 1000 / TICKS_PER_SECOND
|
self.ticks * (1000 / GCD_1K) / (TICKS_PER_SECOND / GCD_1K)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert the `Duration` to microseconds, rounding down.
|
/// Convert the `Duration` to microseconds, rounding down.
|
||||||
pub const fn as_micros(&self) -> u64 {
|
pub const fn as_micros(&self) -> u64 {
|
||||||
self.ticks * 1_000_000 / TICKS_PER_SECOND
|
self.ticks * (1_000_000 / GCD_1M) / (TICKS_PER_SECOND / GCD_1M)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a duration from the specified number of clock ticks
|
/// Creates a duration from the specified number of clock ticks
|
||||||
@ -51,7 +51,7 @@ impl Duration {
|
|||||||
/// Creates a duration from the specified number of milliseconds
|
/// Creates a duration from the specified number of milliseconds
|
||||||
pub const fn from_millis(millis: u64) -> Duration {
|
pub const fn from_millis(millis: u64) -> Duration {
|
||||||
Duration {
|
Duration {
|
||||||
ticks: millis * TICKS_PER_SECOND / 1000,
|
ticks: millis * (TICKS_PER_SECOND / GCD_1K) / (1000 / GCD_1K),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ impl Duration {
|
|||||||
/// NOTE: Delays this small may be inaccurate.
|
/// NOTE: Delays this small may be inaccurate.
|
||||||
pub const fn from_micros(micros: u64) -> Duration {
|
pub const fn from_micros(micros: u64) -> Duration {
|
||||||
Duration {
|
Duration {
|
||||||
ticks: micros * TICKS_PER_SECOND / 1_000_000,
|
ticks: micros * (TICKS_PER_SECOND / GCD_1M) / (1_000_000 / GCD_1M),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::ops::{Add, AddAssign, Sub, SubAssign};
|
use core::ops::{Add, AddAssign, Sub, SubAssign};
|
||||||
|
|
||||||
use super::{driver, Duration, TICKS_PER_SECOND};
|
use super::{driver, Duration, GCD_1K, GCD_1M, TICKS_PER_SECOND};
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
@ -31,14 +31,14 @@ impl Instant {
|
|||||||
/// Create an Instant from a microsecond count since system boot.
|
/// Create an Instant from a microsecond count since system boot.
|
||||||
pub const fn from_micros(micros: u64) -> Self {
|
pub const fn from_micros(micros: u64) -> Self {
|
||||||
Self {
|
Self {
|
||||||
ticks: micros * TICKS_PER_SECOND / 1_000_000,
|
ticks: micros * (TICKS_PER_SECOND / GCD_1M) / (1_000_000 / GCD_1M),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an Instant from a millisecond count since system boot.
|
/// Create an Instant from a millisecond count since system boot.
|
||||||
pub const fn from_millis(millis: u64) -> Self {
|
pub const fn from_millis(millis: u64) -> Self {
|
||||||
Self {
|
Self {
|
||||||
ticks: millis * TICKS_PER_SECOND / 1000,
|
ticks: millis * (TICKS_PER_SECOND / GCD_1K) / (1000 / GCD_1K),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,12 +61,12 @@ impl Instant {
|
|||||||
|
|
||||||
/// Milliseconds since system boot.
|
/// Milliseconds since system boot.
|
||||||
pub const fn as_millis(&self) -> u64 {
|
pub const fn as_millis(&self) -> u64 {
|
||||||
self.ticks * 1000 / TICKS_PER_SECOND
|
self.ticks * (1000 / GCD_1K) / (TICKS_PER_SECOND / GCD_1K)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Microseconds since system boot.
|
/// Microseconds since system boot.
|
||||||
pub const fn as_micros(&self) -> u64 {
|
pub const fn as_micros(&self) -> u64 {
|
||||||
self.ticks * 1_000_000 / TICKS_PER_SECOND
|
self.ticks * (1_000_000 / GCD_1M) / (TICKS_PER_SECOND / GCD_1M)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Duration between this Instant and another Instant
|
/// Duration between this Instant and another Instant
|
||||||
|
@ -75,3 +75,14 @@ const TPS: u64 = 1_000_000;
|
|||||||
/// allow you to choose a tick rate with Cargo features of their own. You should not
|
/// allow you to choose a tick rate with Cargo features of their own. You should not
|
||||||
/// set the `time-tick-*` features for embassy yourself as an end user.
|
/// set the `time-tick-*` features for embassy yourself as an end user.
|
||||||
pub const TICKS_PER_SECOND: u64 = TPS;
|
pub const TICKS_PER_SECOND: u64 = TPS;
|
||||||
|
|
||||||
|
const fn gcd(a: u64, b: u64) -> u64 {
|
||||||
|
if b == 0 {
|
||||||
|
a
|
||||||
|
} else {
|
||||||
|
gcd(b, a % b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) const GCD_1K: u64 = gcd(TICKS_PER_SECOND, 1_000);
|
||||||
|
pub(crate) const GCD_1M: u64 = gcd(TICKS_PER_SECOND, 1_000_000);
|
||||||
|
Loading…
Reference in New Issue
Block a user