Skip to main content

qubit_clock/monotonic/
std_monotonic_clock.rs

1// =============================================================================
2//    Copyright (c) 2025 - 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! Defines the standard-library monotonic clock implementation.
9
10use crate::{
11    ClockDomain,
12    MonotonicClock,
13    MonotonicInstant,
14    StdTimer,
15    Timer,
16};
17use std::sync::Arc;
18use std::time::Instant;
19
20/// A real monotonic clock backed by [`std::time::Instant`].
21///
22/// The type intentionally does not implement [`Clone`]. Shared identity is
23/// expressed explicitly with `Arc<StdMonotonicClock>`.
24#[derive(Debug)]
25pub struct StdMonotonicClock {
26    /// Domain carried by instants sampled from this clock.
27    domain: ClockDomain,
28    /// Native standard-library instant mapped to elapsed duration zero.
29    origin: Instant,
30}
31
32impl StdMonotonicClock {
33    /// Creates a new independent clock domain at the current native instant.
34    ///
35    /// # Returns
36    ///
37    /// A standard monotonic clock with a newly allocated domain.
38    ///
39    /// # Panics
40    ///
41    /// Panics if all process-wide clock-domain identifiers are exhausted.
42    #[must_use]
43    #[inline]
44    pub fn new() -> Self {
45        Self {
46            domain: ClockDomain::new(),
47            origin: Instant::now(),
48        }
49    }
50
51    /// Creates a private handle retaining this exact standard clock domain.
52    ///
53    /// # Returns
54    ///
55    /// A clock handle with the same domain identifier and native origin.
56    #[must_use]
57    #[inline]
58    pub(crate) const fn same_domain_handle(&self) -> Self {
59        Self {
60            domain: self.domain,
61            origin: self.origin,
62        }
63    }
64
65    /// Returns the native origin used by a paired standard timer.
66    ///
67    /// # Returns
68    ///
69    /// The standard-library instant mapped to elapsed duration zero.
70    #[must_use]
71    #[inline(always)]
72    pub(crate) const fn origin(&self) -> Instant {
73        self.origin
74    }
75
76    /// Returns this concrete clock's domain without sampling native time.
77    ///
78    /// # Returns
79    ///
80    /// This clock's process-unique domain.
81    #[inline(always)]
82    pub(crate) const fn domain(&self) -> ClockDomain {
83        self.domain
84    }
85}
86
87impl Default for StdMonotonicClock {
88    /// Creates a new independent standard monotonic clock domain.
89    ///
90    /// # Returns
91    ///
92    /// A standard monotonic clock with a newly allocated domain.
93    ///
94    /// # Panics
95    ///
96    /// Panics if all process-wide clock-domain identifiers are exhausted.
97    #[inline(always)]
98    fn default() -> Self {
99        Self::new()
100    }
101}
102
103impl MonotonicClock for StdMonotonicClock {
104    /// Returns the current instant in this clock's domain.
105    ///
106    /// # Returns
107    ///
108    /// The current elapsed duration represented in this clock's domain.
109    #[inline]
110    fn now(&self) -> MonotonicInstant {
111        MonotonicInstant::new(self.domain, self.origin.elapsed())
112    }
113
114    /// Creates a timer retaining this exact standard clock domain and origin.
115    ///
116    /// # Returns
117    ///
118    /// A shared timer backed by one lazy standard scheduler worker.
119    #[inline]
120    fn new_timer(&self) -> Arc<dyn Timer> {
121        Arc::new(StdTimer::from_clock(self))
122    }
123}