1 // Copyright 2024 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 //! A helper binary for reading CLOCK_BOOTTIME and CLOCK_MONOTONIC
6 //! to verify the virtio-pvclock behavior.
7 //! This program is used by corresponding e2e_tests.
8
9 use std::time::Duration;
10
11 use serde::Deserialize;
12 use serde::Serialize;
13
14 #[cfg(any(target_os = "linux", target_os = "android"))]
clock_gettime_nanos(clock_id: i32) -> u6415 fn clock_gettime_nanos(clock_id: i32) -> u64 {
16 let mut ts = libc::timespec {
17 tv_sec: 0,
18 tv_nsec: 0,
19 };
20 // SAFETY: This is safe since clock_gettime will succeed always
21 // and will not break Rust's assumption on data structures
22 // because it is called with valid parameters.
23 assert_eq!(unsafe { libc::clock_gettime(clock_id, &mut ts) }, 0);
24 ts.tv_sec as u64 * 1_000_000_000u64 + ts.tv_nsec as u64
25 }
26
27 #[cfg(any(target_os = "linux", target_os = "android"))]
clock_monotonic_now() -> Duration28 fn clock_monotonic_now() -> Duration {
29 Duration::from_nanos(clock_gettime_nanos(libc::CLOCK_MONOTONIC))
30 }
31
32 #[cfg(any(target_os = "linux", target_os = "android"))]
clock_boottime_now() -> Duration33 fn clock_boottime_now() -> Duration {
34 Duration::from_nanos(clock_gettime_nanos(libc::CLOCK_BOOTTIME))
35 }
36
37 /// ClockValues hold the values read out from the kernel
38 /// via clock_gettime syscall.
39 #[derive(Serialize, Deserialize, Debug)]
40 pub struct ClockValues {
41 pub clock_monotonic: Duration,
42 pub clock_boottime: Duration,
43 }
44 impl ClockValues {
45 #[cfg(any(target_os = "linux", target_os = "android"))]
now() -> Self46 pub fn now() -> Self {
47 Self {
48 clock_monotonic: clock_monotonic_now(),
49 clock_boottime: clock_boottime_now(),
50 }
51 }
clock_monotonic(&self) -> Duration52 pub fn clock_monotonic(&self) -> Duration {
53 self.clock_monotonic
54 }
clock_boottime(&self) -> Duration55 pub fn clock_boottime(&self) -> Duration {
56 self.clock_boottime
57 }
58 }
59