Enhance the timer interface.
- Make Duration a generic type, supporting both isize and f64
representation.
- Derive comparison traits for Duration.
- Add a Timestamp type and arithmetic between Durations and Timestamps.
diff --git a/src/timer.rs b/src/timer.rs
index 0a1dbfd..6634282 100644
--- a/src/timer.rs
+++ b/src/timer.rs
@@ -6,6 +6,7 @@
use crate::syscalls;
use core::cell::Cell;
use core::isize;
+use core::ops::{Add, AddAssign, Sub};
const DRIVER_NUMBER: usize = 0x00000;
@@ -21,7 +22,7 @@
pub const SUBSCRIBE_CALLBACK: usize = 0;
}
-pub fn sleep(duration: Duration) {
+pub fn sleep(duration: Duration<isize>) {
let expired = Cell::new(false);
let mut with_callback = with_callback(|_, _| expired.set(true));
@@ -140,7 +141,7 @@
}
}
- pub fn set_alarm(&mut self, duration: Duration) -> TockResult<Alarm, SetAlarmError> {
+ pub fn set_alarm(&mut self, duration: Duration<isize>) -> TockResult<Alarm, SetAlarmError> {
let now = self.get_current_clock();
let alarm_instant =
now.num_ticks() as usize + (duration.ms() as usize * self.clock_frequency.hz()) / 1000;
@@ -187,6 +188,10 @@
1000 * (self.num_ticks / self.clock_frequency.hz() as isize)
}
}
+
+ pub fn ms_f64(&self) -> f64 {
+ 1000.0 * (self.num_ticks as f64) / (self.clock_frequency.hz() as f64)
+ }
}
pub struct Alarm {
@@ -209,17 +214,100 @@
NoMemoryAvailable,
}
-#[derive(Copy, Clone, Debug)]
-pub struct Duration {
- ms: isize,
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Duration<T> {
+ ms: T,
}
-impl Duration {
- pub fn from_ms(ms: isize) -> Duration {
+impl<T> Duration<T> {
+ pub const fn from_ms(ms: T) -> Duration<T> {
Duration { ms }
}
+}
- pub fn ms(&self) -> isize {
+impl<T> Duration<T>
+where
+ T: Copy,
+{
+ pub fn ms(&self) -> T {
self.ms
}
}
+
+impl<T> Sub for Duration<T>
+where
+ T: Sub<Output = T>,
+{
+ type Output = Duration<T>;
+
+ fn sub(self, other: Duration<T>) -> Duration<T> {
+ Duration {
+ ms: self.ms - other.ms,
+ }
+ }
+}
+
+#[derive(Copy, Clone, Debug)]
+pub struct Timestamp<T> {
+ ms: T,
+}
+
+impl<T> Timestamp<T> {
+ pub const fn from_ms(ms: T) -> Timestamp<T> {
+ Timestamp { ms }
+ }
+}
+
+impl<T> Timestamp<T>
+where
+ T: Copy,
+{
+ pub fn ms(&self) -> T {
+ self.ms
+ }
+}
+
+impl Timestamp<isize> {
+ pub fn from_clock_value(value: ClockValue) -> Timestamp<isize> {
+ Timestamp { ms: value.ms() }
+ }
+}
+
+impl Timestamp<f64> {
+ pub fn from_clock_value(value: ClockValue) -> Timestamp<f64> {
+ Timestamp { ms: value.ms_f64() }
+ }
+}
+
+impl<T> Sub for Timestamp<T>
+where
+ T: Sub<Output = T>,
+{
+ type Output = Duration<T>;
+
+ fn sub(self, other: Timestamp<T>) -> Duration<T> {
+ Duration::from_ms(self.ms - other.ms)
+ }
+}
+
+impl<T> Add<Duration<T>> for Timestamp<T>
+where
+ T: Copy + Add<Output = T>,
+{
+ type Output = Timestamp<T>;
+
+ fn add(self, duration: Duration<T>) -> Timestamp<T> {
+ Timestamp {
+ ms: self.ms + duration.ms(),
+ }
+ }
+}
+
+impl<T> AddAssign<Duration<T>> for Timestamp<T>
+where
+ T: Copy + AddAssign,
+{
+ fn add_assign(&mut self, duration: Duration<T>) {
+ self.ms += duration.ms();
+ }
+}