use std::time::{SystemTime, UNIX_EPOCH};
pub fn system_time_nanos() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("system time before UNIX epoch")
.as_nanos() as u64
}
pub fn system_time_secs() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("system time before UNIX epoch")
.as_secs()
}
#[cfg(target_os = "linux")]
fn boot_time_offset_ns() -> u64 {
let mut mono = libc::timespec {
tv_sec: 0,
tv_nsec: 0,
};
let mut real = libc::timespec {
tv_sec: 0,
tv_nsec: 0,
};
unsafe {
libc::clock_gettime(libc::CLOCK_MONOTONIC, &mut mono);
libc::clock_gettime(libc::CLOCK_REALTIME, &mut real);
}
let mono_ns = mono.tv_sec as u64 * 1_000_000_000 + mono.tv_nsec as u64;
let real_ns = real.tv_sec as u64 * 1_000_000_000 + real.tv_nsec as u64;
real_ns.saturating_sub(mono_ns)
}
#[cfg(target_os = "linux")]
pub fn boot_time_to_system_time(boot_time_ns: u64) -> u64 {
boot_time_ns + boot_time_offset_ns()
}
#[cfg(not(target_os = "linux"))]
pub fn boot_time_to_system_time(boot_time_ns: u64) -> u64 {
boot_time_ns
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_system_time() {
let nanos = system_time_nanos();
let secs = system_time_secs();
assert!(nanos > 0);
assert!(secs > 1_600_000_000); }
}