1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
use nix::{
sys::time::TimeSpec,
time::{ClockId, clock_gettime},
};
use std::{ffi::c_long, time::Duration};
const NSEC_PER_SEC: c_long = 1_000_000_000;
#[cfg(any(target_os = "macos", target_os = "ios"))]
const CLOCK_ID: ClockId = ClockId::CLOCK_MONOTONIC;
#[cfg(any(target_os = "linux", target_os = "android"))]
const CLOCK_ID: ClockId = ClockId::CLOCK_BOOTTIME;
#[derive(Clone, Copy)]
pub struct Instant {
t: TimeSpec,
}
impl Instant {
pub fn now() -> Self {
Self { t: now() }
}
fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> {
// Assumptions:
// * `tv_sec >= 0`
// * `tv_nsec < NSEC_PER_SEC`
let (tv_sec, tv_nsec) = if self.t.tv_nsec() < earlier.t.tv_nsec() {
(
self.t.tv_sec() - earlier.t.tv_sec() - 1,
NSEC_PER_SEC - earlier.t.tv_nsec() + self.t.tv_nsec(),
)
} else {
(
self.t.tv_sec() - earlier.t.tv_sec(),
self.t.tv_nsec() - earlier.t.tv_nsec(),
)
};
if tv_sec < 0 {
return None;
}
Some(Duration::new(tv_sec as _, tv_nsec as _))
}
pub fn duration_since(&self, earlier: Instant) -> Duration {
self.checked_duration_since(earlier)
.unwrap_or(Duration::ZERO)
}
}
fn now() -> TimeSpec {
clock_gettime(CLOCK_ID).expect("Clock ID is valid")
}
|