Skip to main content

dope_core/driver/schedule/clock/
range.rs

1use o3::base::time::DurationExt as _;
2use std::{borrow, time};
3
4use crate::driver::schedule::clock::Origin;
5
6/// Exact future deadline that exceeds the platform monotonic range.
7#[derive(Clone, Copy, Eq, PartialEq, Debug)]
8pub struct Range<D = time::Duration> {
9    origin: Origin,
10    duration: D,
11}
12
13impl<D: Copy> Range<D> {
14    pub(super) const fn new(origin: Origin, duration: D) -> Self {
15        Self { origin, duration }
16    }
17
18    pub const fn duration(self) -> D {
19        self.duration
20    }
21
22    #[cold]
23    pub(super) fn furthest(self) -> time::Instant
24    where
25        D: borrow::Borrow<time::Duration>,
26    {
27        let mut lower = time::Duration::ZERO;
28        let mut upper = *self.duration.borrow();
29        let mut at = self.origin.0;
30        while lower < upper {
31            let middle = lower.average::<2>(upper);
32            let next = if middle == lower { upper } else { middle };
33            match self.origin.0.checked_add(next) {
34                Some(value) => {
35                    lower = next;
36                    at = value;
37                }
38                None => {
39                    let nanos = next.subsec_nanos();
40                    upper = if nanos == 0 {
41                        time::Duration::new(next.as_secs() - 1, 999_999_999)
42                    } else {
43                        time::Duration::new(next.as_secs(), nanos - 1)
44                    };
45                }
46            }
47        }
48        at
49    }
50}
51
52const _: () = {
53    use std::mem;
54
55    use o3::base::time::Positive;
56
57    assert!(mem::size_of::<Range<Positive>>() == mem::size_of::<Range>());
58    assert!(mem::align_of::<Range<Positive>>() == mem::align_of::<Range>());
59    assert!(!mem::needs_drop::<Range<Positive>>());
60};