ic_host_process/observation/clock/
mod.rs1#[cfg(unix)]
4use rustix::time::{ClockId, DynamicClockId, clock_gettime_dynamic};
5
6#[cfg(unix)]
7#[expect(
8 clippy::cast_sign_loss,
9 reason = "successful native clocks have nonnegative seconds and nanoseconds"
10)]
11fn clock_ns(clock: ClockId) -> Option<u64> {
12 let value = clock_gettime_dynamic(DynamicClockId::Known(clock)).ok()?;
13 Some(
14 (value.tv_sec as u64)
15 .saturating_mul(1_000_000_000)
16 .saturating_add(value.tv_nsec as u64),
17 )
18}
19
20#[must_use]
22pub fn monotonic_ns() -> u64 {
23 static START: std::sync::OnceLock<std::time::Instant> = std::sync::OnceLock::new();
24 #[cfg(unix)]
25 if let Some(value) = clock_ns(ClockId::Monotonic) {
26 return value;
27 }
28 u64::try_from(
29 START
30 .get_or_init(std::time::Instant::now)
31 .elapsed()
32 .as_nanos(),
33 )
34 .unwrap_or(u64::MAX)
35}
36
37#[must_use]
39pub fn thread_cpu_ns() -> u64 {
40 #[cfg(unix)]
41 if let Some(value) = clock_ns(ClockId::ThreadCPUTime) {
42 return value;
43 }
44 0
45}
46
47#[must_use]
49pub fn tid() -> u64 {
50 #[cfg(target_os = "linux")]
51 {
52 u64::try_from(rustix::thread::gettid().as_raw_pid()).unwrap_or_default()
53 }
54 #[cfg(target_os = "macos")]
55 {
56 let mut id = 0;
57 #[expect(
59 unsafe_code,
60 reason = "Darwin thread ID has no matching Rustix interface"
61 )]
62 if unsafe { libc::pthread_threadid_np(0, &raw mut id) } == 0 {
63 id
64 } else {
65 0
66 }
67 }
68 #[cfg(not(any(target_os = "linux", target_os = "macos")))]
69 {
70 0
71 }
72}