indexbus_platform_ops/
time.rs1use crate::errors::{Error, Result};
9
10pub fn monotonic_now_ns() -> u64 {
18 #[cfg(target_os = "linux")]
19 unsafe {
20 let mut ts: libc::timespec = std::mem::zeroed();
21
22 #[allow(non_upper_case_globals)]
23 const CLOCK_MONOTONIC_RAW: libc::clockid_t = 4;
24
25 let mut rc = libc::clock_gettime(CLOCK_MONOTONIC_RAW, &mut ts as *mut _);
26 if rc != 0 {
27 rc = libc::clock_gettime(libc::CLOCK_MONOTONIC, &mut ts as *mut _);
28 }
29
30 if rc != 0 {
31 return 0;
32 }
33
34 (ts.tv_sec as u128)
35 .saturating_mul(1_000_000_000)
36 .saturating_add(ts.tv_nsec as u128)
37 .min(u128::from(u64::MAX)) as u64
38 }
39
40 #[cfg(not(target_os = "linux"))]
41 {
42 use std::time::SystemTime;
43 SystemTime::now()
44 .duration_since(SystemTime::UNIX_EPOCH)
45 .ok()
46 .map(|d| d.as_nanos().min(u128::from(u64::MAX)) as u64)
47 .unwrap_or(0)
48 }
49}
50
51pub fn try_monotonic_now_ns() -> Result<u64> {
53 let v = monotonic_now_ns();
54 if v == 0 {
55 Err(Error::msg("failed to read monotonic clock"))
56 } else {
57 Ok(v)
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
66 fn monotonic_now_is_nonzero() {
67 let v = try_monotonic_now_ns().unwrap();
68 assert!(v > 0);
69 }
70}