1#![no_std]
4
5use core::marker::PhantomData;
6use spin::relax::{RelaxStrategy, Spin};
7
8pub trait Timestamp {
10 type Duration: PartialOrd;
11 type Error;
12
13 fn now() -> Self;
15
16 fn duration_since_epoch(self) -> Self::Duration;
18
19 fn duration_since(&self, other: &Self) -> Result<Self::Duration, Self::Error>;
23}
24
25pub trait ElapsedTimer {
27 type Timestamp: Timestamp;
28
29 fn timeout(
34 &self,
35 from: &Self::Timestamp,
36 to: &Self::Timestamp,
37 ) -> Result<bool, <Self::Timestamp as Timestamp>::Error>;
38}
39
40pub struct Timer<T: Timestamp> {
42 duration: T::Duration,
43}
44
45impl<T: Timestamp> Timer<T> {
46 pub const fn new(duration: T::Duration) -> Self {
48 Timer { duration }
49 }
50
51 pub fn borrow_duration(&self) -> &T::Duration {
53 &self.duration
54 }
55
56 pub fn borrow_mut_duration(&mut self) -> &mut T::Duration {
58 &mut self.duration
59 }
60}
61
62impl<T: Timestamp> ElapsedTimer for Timer<T> {
63 type Timestamp = T;
64
65 fn timeout(
66 &self,
67 from: &Self::Timestamp,
68 to: &Self::Timestamp,
69 ) -> Result<bool, <Self::Timestamp as Timestamp>::Error> {
70 Ok(to.duration_since(from)? >= self.duration)
71 }
72}
73
74pub struct Delay<T: Timestamp, R: RelaxStrategy = Spin> {
80 duration: T::Duration,
81 relax: PhantomData<R>,
82}
83
84impl<T: Timestamp, R: RelaxStrategy> Delay<T, R> {
85 pub const fn new(duration: T::Duration) -> Self {
87 Delay {
88 duration,
89 relax: PhantomData::<R>,
90 }
91 }
92
93 pub fn borrow_duration(&self) -> &T::Duration {
95 &self.duration
96 }
97
98 pub fn borrow_mut_duration(&mut self) -> &mut T::Duration {
100 &mut self.duration
101 }
102
103 pub fn exec(&self) -> Result<(), T::Error> {
107 let start = T::now();
108
109 while T::now().duration_since(&start)? < self.duration {
110 R::relax();
111 }
112
113 Ok(())
114 }
115}