Coverage Report

Created: 2025-11-16 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/x86-0.47.0/src/time.rs
Line
Count
Source
1
//! Functions to read time stamp counters on x86.
2
3
use crate::arch::{__rdtscp, _rdtsc};
4
5
/// Read the time stamp counter.
6
///
7
/// The RDTSC instruction is not a serializing instruction.
8
/// It does not necessarily wait until all previous instructions
9
/// have been executed before reading the counter. Similarly,
10
/// subsequent instructions may begin execution before the
11
/// read operation is performed. If software requires RDTSC to be
12
/// executed only after all previous instructions have completed locally,
13
/// it can either use RDTSCP or execute the sequence LFENCE;RDTSC.
14
///
15
/// # Safety
16
/// * Causes a GP fault if the TSD flag in register CR4 is set and the CPL
17
///   is greater than 0.
18
0
pub unsafe fn rdtsc() -> u64 {
19
0
    _rdtsc() as u64
20
0
}
21
22
/// Read the time stamp counter.
23
///
24
/// The RDTSCP instruction waits until all previous instructions
25
/// have been executed before reading the counter.
26
/// However, subsequent instructions may begin execution
27
/// before the read operation is performed.
28
///
29
/// Volatile is used here because the function may be used to act as
30
/// an instruction barrier.
31
///
32
/// # Safety
33
/// * Causes a GP fault if the TSD flag in register CR4 is set and the
34
///   CPL is greater than 0.
35
0
pub unsafe fn rdtscp() -> u64 {
36
0
    let mut _aux = 0;
37
0
    __rdtscp(&mut _aux)
38
0
}
39
40
#[cfg(all(test, feature = "utest"))]
41
mod test {
42
    use super::*;
43
44
    #[test]
45
    fn check_rdtsc() {
46
        let cpuid = crate::cpuid::CpuId::new();
47
        let has_tsc = cpuid
48
            .get_feature_info()
49
            .map_or(false, |finfo| finfo.has_tsc());
50
51
        if has_tsc {
52
            unsafe {
53
                assert!(rdtsc() > 0, "rdtsc returned 0, unlikely!");
54
            }
55
        }
56
    }
57
58
    #[test]
59
    fn check_rdtscp() {
60
        let cpuid = crate::cpuid::CpuId::new();
61
        let has_rdtscp = cpuid
62
            .get_extended_processor_and_feature_identifiers()
63
            .map_or(false, |einfo| einfo.has_rdtscp());
64
65
        if has_rdtscp {
66
            unsafe {
67
                assert!(rdtscp() > 0, "rdtscp returned 0, unlikely!");
68
            }
69
        }
70
    }
71
}