aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-02-13 20:29:06 +0000
committerGitHub <[email protected]>2022-02-13 20:29:06 +0000
commitc8f9f1bead8aa02076ff8daec3c83c752808dbcb (patch)
treebbfc7be8b4e88179e5519b6d64db4d75eb04b31b
parenteb922c4655db4b22acf808855e3bc003d3b8ba89 (diff)
parent640ddc948190fe9a24d6db616cb103d6a94f81f9 (diff)
Merge #618
618: time: optimize math by reducing fractions at compile time. r=Dirbaio a=Dirbaio For example, `as_micros`, `from_micros` now are noops if tick rate is 1MHz. See: https://godbolt.org/z/fE1bf3ecP Co-authored-by: Dario Nieuwenhuis <[email protected]>
-rw-r--r--embassy/src/time/duration.rs10
-rw-r--r--embassy/src/time/instant.rs10
-rw-r--r--embassy/src/time/mod.rs11
3 files changed, 21 insertions, 10 deletions
diff --git a/embassy/src/time/duration.rs b/embassy/src/time/duration.rs
index e196a00c7..47b413f48 100644
--- a/embassy/src/time/duration.rs
+++ b/embassy/src/time/duration.rs
@@ -1,7 +1,7 @@
1use core::fmt; 1use core::fmt;
2use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; 2use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
3 3
4use super::TICKS_PER_SECOND; 4use super::{GCD_1K, GCD_1M, TICKS_PER_SECOND};
5 5
6#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] 6#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
7#[cfg_attr(feature = "defmt", derive(defmt::Format))] 7#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -28,12 +28,12 @@ impl Duration {
28 28
29 /// Convert the `Duration` to milliseconds, rounding down. 29 /// Convert the `Duration` to milliseconds, rounding down.
30 pub const fn as_millis(&self) -> u64 { 30 pub const fn as_millis(&self) -> u64 {
31 self.ticks * 1000 / TICKS_PER_SECOND 31 self.ticks * (1000 / GCD_1K) / (TICKS_PER_SECOND / GCD_1K)
32 } 32 }
33 33
34 /// Convert the `Duration` to microseconds, rounding down. 34 /// Convert the `Duration` to microseconds, rounding down.
35 pub const fn as_micros(&self) -> u64 { 35 pub const fn as_micros(&self) -> u64 {
36 self.ticks * 1_000_000 / TICKS_PER_SECOND 36 self.ticks * (1_000_000 / GCD_1M) / (TICKS_PER_SECOND / GCD_1M)
37 } 37 }
38 38
39 /// Creates a duration from the specified number of clock ticks 39 /// Creates a duration from the specified number of clock ticks
@@ -51,7 +51,7 @@ impl Duration {
51 /// Creates a duration from the specified number of milliseconds 51 /// Creates a duration from the specified number of milliseconds
52 pub const fn from_millis(millis: u64) -> Duration { 52 pub const fn from_millis(millis: u64) -> Duration {
53 Duration { 53 Duration {
54 ticks: millis * TICKS_PER_SECOND / 1000, 54 ticks: millis * (TICKS_PER_SECOND / GCD_1K) / (1000 / GCD_1K),
55 } 55 }
56 } 56 }
57 57
@@ -59,7 +59,7 @@ impl Duration {
59 /// NOTE: Delays this small may be inaccurate. 59 /// NOTE: Delays this small may be inaccurate.
60 pub const fn from_micros(micros: u64) -> Duration { 60 pub const fn from_micros(micros: u64) -> Duration {
61 Duration { 61 Duration {
62 ticks: micros * TICKS_PER_SECOND / 1_000_000, 62 ticks: micros * (TICKS_PER_SECOND / GCD_1M) / (1_000_000 / GCD_1M),
63 } 63 }
64 } 64 }
65 65
diff --git a/embassy/src/time/instant.rs b/embassy/src/time/instant.rs
index aff83be20..71adbeb3f 100644
--- a/embassy/src/time/instant.rs
+++ b/embassy/src/time/instant.rs
@@ -1,7 +1,7 @@
1use core::fmt; 1use core::fmt;
2use core::ops::{Add, AddAssign, Sub, SubAssign}; 2use core::ops::{Add, AddAssign, Sub, SubAssign};
3 3
4use super::{driver, Duration, TICKS_PER_SECOND}; 4use super::{driver, Duration, GCD_1K, GCD_1M, TICKS_PER_SECOND};
5 5
6#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] 6#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
7#[cfg_attr(feature = "defmt", derive(defmt::Format))] 7#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -31,14 +31,14 @@ impl Instant {
31 /// Create an Instant from a microsecond count since system boot. 31 /// Create an Instant from a microsecond count since system boot.
32 pub const fn from_micros(micros: u64) -> Self { 32 pub const fn from_micros(micros: u64) -> Self {
33 Self { 33 Self {
34 ticks: micros * TICKS_PER_SECOND / 1_000_000, 34 ticks: micros * (TICKS_PER_SECOND / GCD_1M) / (1_000_000 / GCD_1M),
35 } 35 }
36 } 36 }
37 37
38 /// Create an Instant from a millisecond count since system boot. 38 /// Create an Instant from a millisecond count since system boot.
39 pub const fn from_millis(millis: u64) -> Self { 39 pub const fn from_millis(millis: u64) -> Self {
40 Self { 40 Self {
41 ticks: millis * TICKS_PER_SECOND / 1000, 41 ticks: millis * (TICKS_PER_SECOND / GCD_1K) / (1000 / GCD_1K),
42 } 42 }
43 } 43 }
44 44
@@ -61,12 +61,12 @@ impl Instant {
61 61
62 /// Milliseconds since system boot. 62 /// Milliseconds since system boot.
63 pub const fn as_millis(&self) -> u64 { 63 pub const fn as_millis(&self) -> u64 {
64 self.ticks * 1000 / TICKS_PER_SECOND 64 self.ticks * (1000 / GCD_1K) / (TICKS_PER_SECOND / GCD_1K)
65 } 65 }
66 66
67 /// Microseconds since system boot. 67 /// Microseconds since system boot.
68 pub const fn as_micros(&self) -> u64 { 68 pub const fn as_micros(&self) -> u64 {
69 self.ticks * 1_000_000 / TICKS_PER_SECOND 69 self.ticks * (1_000_000 / GCD_1M) / (TICKS_PER_SECOND / GCD_1M)
70 } 70 }
71 71
72 /// Duration between this Instant and another Instant 72 /// Duration between this Instant and another Instant
diff --git a/embassy/src/time/mod.rs b/embassy/src/time/mod.rs
index c8971bd13..ac84b8f8d 100644
--- a/embassy/src/time/mod.rs
+++ b/embassy/src/time/mod.rs
@@ -75,3 +75,14 @@ const TPS: u64 = 1_000_000;
75/// allow you to choose a tick rate with Cargo features of their own. You should not 75/// allow you to choose a tick rate with Cargo features of their own. You should not
76/// set the `time-tick-*` features for embassy yourself as an end user. 76/// set the `time-tick-*` features for embassy yourself as an end user.
77pub const TICKS_PER_SECOND: u64 = TPS; 77pub const TICKS_PER_SECOND: u64 = TPS;
78
79const fn gcd(a: u64, b: u64) -> u64 {
80 if b == 0 {
81 a
82 } else {
83 gcd(b, a % b)
84 }
85}
86
87pub(crate) const GCD_1K: u64 = gcd(TICKS_PER_SECOND, 1_000);
88pub(crate) const GCD_1M: u64 = gcd(TICKS_PER_SECOND, 1_000_000);