-
Notifications
You must be signed in to change notification settings - Fork 297
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
aya: use montonic SinceBoot for loaded_at
This commit was written to deflake test_loaded_at. The flakiness is due to the lack of monotonicity in SystemTime clock calculations. See https://github.com/aya-rs/aya/actions/runs/6340369670/job/17221591723. This PR addresses that problem by introducing a wrapper type to encapsulate the monotonically increasing duration since boot, `SinceBoot`. This type has a method `into_system_time()` to convert it into a `SystemTime`.
- Loading branch information
Showing
6 changed files
with
123 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
//! Utilities for working with time. | ||
use std::time::{Duration, SystemTime, UNIX_EPOCH}; | ||
|
||
/// A timestamp relative to the system boot time. | ||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] | ||
pub struct SinceBoot(Duration); | ||
|
||
impl SinceBoot { | ||
/// The current SinceBoot. | ||
/// | ||
/// Note that these calls will be monotonic. | ||
pub fn now() -> Self { | ||
Self(get_time(libc::CLOCK_BOOTTIME)) | ||
} | ||
|
||
/// Converts the timestamp to a `SystemTime`. | ||
/// | ||
/// Note that this will not be robust to changes in the system clock, and thus these | ||
/// times should not be used for comparisons. | ||
pub fn into_system(self) -> SystemTime { | ||
let Self(since_boot) = self; | ||
boot_time() + since_boot | ||
} | ||
|
||
pub(crate) fn from_nanos(nanos: u64) -> Self { | ||
Self(Duration::from_nanos(nanos)) | ||
} | ||
} | ||
|
||
fn boot_time() -> SystemTime { | ||
let since_boot = get_time(libc::CLOCK_BOOTTIME); | ||
let since_epoch = get_time(libc::CLOCK_REALTIME); | ||
UNIX_EPOCH + since_epoch - since_boot | ||
} | ||
|
||
fn get_time(clock_id: libc::clockid_t) -> Duration { | ||
let mut time = unsafe { std::mem::zeroed::<libc::timespec>() }; | ||
assert_eq!( | ||
unsafe { libc::clock_gettime(clock_id, &mut time) }, | ||
0, | ||
"clock_gettime({}, _)", | ||
clock_id | ||
); | ||
let libc::timespec { tv_sec, tv_nsec } = time; | ||
Duration::new(tv_sec as u64, tv_nsec as u32) | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use super::*; | ||
|
||
#[test] | ||
fn test_since_boot_now_into_system_near_system_time() { | ||
let since_boot = SinceBoot::now().into_system(); | ||
let system_time = SystemTime::now(); | ||
let delta = system_time | ||
.duration_since(since_boot) | ||
.unwrap_or_else(|err| err.duration()); | ||
const MAX_DELTA: Duration = Duration::from_micros(10); | ||
assert!( | ||
delta <= MAX_DELTA, | ||
"delta {delta:?} > {MAX_DELTA:?}: since_boot: {:?}, system_time: {:?}", | ||
since_boot, | ||
system_time | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters