Skip to main content

proxima_core/time/drivers/
std_thread.rs

1//! Host fallback driver — spawns a `std::thread` per scheduled wake.
2//! Cheap to write, suboptimal under load; the right driver under heavy
3//! timer workloads is `prime-wheel` or `embassy-time`.
4
5use std::sync::OnceLock;
6use std::task::Waker;
7
8use crate::time::{Driver, Instant};
9
10/// Singleton driver instance — referenced by the static binding emitted
11/// by `proxima-core`'s `build.rs` when `timer = "std-thread"`.
12pub static DRIVER: StdThreadDriver = StdThreadDriver {
13    epoch: OnceLock::new(),
14};
15
16/// State for the host-thread driver. The epoch is captured lazily on
17/// first use so the driver remains construct-in-static-context.
18pub struct StdThreadDriver {
19    epoch: OnceLock<std::time::Instant>,
20}
21
22impl StdThreadDriver {
23    fn epoch(&self) -> std::time::Instant {
24        *self.epoch.get_or_init(std::time::Instant::now)
25    }
26}
27
28impl Driver for StdThreadDriver {
29    fn now(&self) -> Instant {
30        let elapsed = std::time::Instant::now().saturating_duration_since(self.epoch());
31        Instant::from_monotonic(elapsed)
32    }
33
34    fn schedule_wake(&self, deadline: Instant, waker: Waker) {
35        let target = self.epoch() + deadline.into_monotonic();
36        std::thread::spawn(move || {
37            let now = std::time::Instant::now();
38            if now < target {
39                std::thread::sleep(target - now);
40            }
41            waker.wake();
42        });
43    }
44}