rpkt_time/lib.rs
1/// This crate provides an alternative approach to the time crate of the stardard library.
2/// It relies on the tsc registers to get the current time instant in a faster and more accurate
3/// fasihon.
4///
5/// Note that this library does has the following limitations:
6///
7/// 1. It only works on 32/64 bits Linux systems with stable tsc (see this blog post for more information
8/// about stable tsc: http://oliveryang.net/2015/09/pitfalls-of-TSC-usage/).
9///
10/// 2. When this crate is loaded, it will check whether the system has stable tsc.
11/// If it does not detect tsc, it will report `false` through the `tsc_stable()` method.
12/// Any usage of this crate is strictly forbidended without stable tsc, as the APIs of this
13/// crate may report errorneous time result.
14///
15/// 3. When initializing this library, it may cause a panic if it fails to read the sysfs file or
16/// parse the file read result.
17///
18/// Some of the code is taken from minstant library, but remove some unncessary
19/// code path for performance.
20
21#[cfg(all(target_os = "linux", any(target_arch = "x86", target_arch = "x86_64")))]
22mod instant;
23
24#[cfg(all(target_os = "linux", any(target_arch = "x86", target_arch = "x86_64")))]
25pub use instant::{Anchor, Instant};
26
27#[cfg(all(target_os = "linux", any(target_arch = "x86", target_arch = "x86_64")))]
28mod tsc;
29
30#[cfg(all(target_os = "linux", any(target_arch = "x86", target_arch = "x86_64")))]
31/// Return whether tsc is stable on the current system.
32///
33/// Note that if this method returns `false`, the whole library should not be used,
34/// as the library may report erroneous time result.
35///
36/// # Examples
37/// ```
38/// use rdtsc_time;
39///
40/// assert!(rdtsc_time::tsc_stable());
41/// ```
42pub fn tsc_stable() -> bool {
43 tsc::tsc_stable()
44}
45
46#[cfg(all(target_os = "linux", any(target_arch = "x86", target_arch = "x86_64")))]
47/// Return the number of CPU cycles of 1 second. It can be used to caclculate future tsc
48/// counter value after a fixed time interval.
49///
50/// Note that this method may return 0 if it is not running on systems with stable tsc.
51///
52/// # Examples
53/// ```
54/// use rdtsc_time::Instant;
55///
56/// let ddl = Instant::now().raw().checked_add(rdtsc_time::cycles_per_sec()).unwrap();
57/// while Instant::now().raw() <= ddl {}
58///
59/// println!("1s has passed");
60/// ```
61#[inline]
62pub fn cycles_per_sec() -> u64 {
63 tsc::cycles_per_sec()
64}