Coverage Report

Created: 2026-04-01 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/cpufeatures-0.3.0/src/lib.rs
Line
Count
Source
1
#![no_std]
2
#![doc = include_str!("../README.md")]
3
#![doc(
4
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
5
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
6
)]
7
8
#[cfg(not(miri))]
9
#[cfg(target_arch = "aarch64")]
10
#[doc(hidden)]
11
pub mod aarch64;
12
13
#[cfg(not(miri))]
14
#[cfg(target_arch = "loongarch64")]
15
#[doc(hidden)]
16
pub mod loongarch64;
17
18
#[cfg(not(miri))]
19
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
20
mod x86;
21
22
#[cfg(miri)]
23
mod miri;
24
25
#[cfg(not(any(
26
    target_arch = "aarch64",
27
    target_arch = "loongarch64",
28
    target_arch = "x86",
29
    target_arch = "x86_64"
30
)))]
31
compile_error!("This crate works only on `aarch64`, `loongarch64`, `x86`, and `x86-64` targets.");
32
33
/// Create module with CPU feature detection code.
34
#[macro_export]
35
macro_rules! new {
36
    ($mod_name:ident, $($tf:tt),+ $(,)?) => {
37
        mod $mod_name {
38
            use core::sync::atomic::{AtomicU8, Ordering::Relaxed};
39
40
            const UNINIT: u8 = u8::max_value();
41
            static STORAGE: AtomicU8 = AtomicU8::new(UNINIT);
42
43
            /// Initialization token
44
            #[derive(Copy, Clone, Debug)]
45
            pub struct InitToken(());
46
47
            impl InitToken {
48
                /// Initialize token, performing CPU feature detection.
49
0
                pub fn init() -> Self {
50
0
                    init()
51
0
                }
Unexecuted instantiation: <chacha20::avx2_cpuid::InitToken>::init
Unexecuted instantiation: <chacha20::sse2_cpuid::InitToken>::init
52
53
                /// Initialize token and return a `bool` indicating if the feature is supported.
54
0
                pub fn init_get() -> (Self, bool) {
55
0
                    init_get()
56
0
                }
Unexecuted instantiation: <chacha20::avx2_cpuid::InitToken>::init_get
Unexecuted instantiation: <chacha20::sse2_cpuid::InitToken>::init_get
57
58
                /// Get initialized value.
59
                #[inline(always)]
60
0
                pub fn get(&self) -> bool {
61
0
                    $crate::__unless_target_features! {
62
                        $($tf),+ => {
63
0
                            STORAGE.load(Relaxed) == 1
64
                        }
65
                    }
66
0
                }
Unexecuted instantiation: <chacha20::avx2_cpuid::InitToken>::get
Unexecuted instantiation: <chacha20::sse2_cpuid::InitToken>::get
67
            }
68
69
            /// Get stored value and initialization token,
70
            /// initializing underlying storage if needed.
71
            #[inline]
72
0
            pub fn init_get() -> (InitToken, bool) {
73
0
                let res = $crate::__unless_target_features! {
74
                    $($tf),+ => {
75
                        #[cold]
76
0
                        fn init_inner() -> bool {
77
0
                            let res = $crate::__detect_target_features!($($tf),+);
78
0
                            STORAGE.store(res as u8, Relaxed);
79
0
                            res
80
0
                        }
81
82
                        // Relaxed ordering is fine, as we only have a single atomic variable.
83
0
                        let val = STORAGE.load(Relaxed);
84
85
0
                        if val == UNINIT {
86
0
                            init_inner()
87
                        } else {
88
0
                            val == 1
89
                        }
90
                    }
91
                };
92
93
0
                (InitToken(()), res)
94
0
            }
Unexecuted instantiation: chacha20::sse2_cpuid::init_get
Unexecuted instantiation: chacha20::avx2_cpuid::init_get
Unexecuted instantiation: chacha20::avx2_cpuid::init_get
Unexecuted instantiation: chacha20::sse2_cpuid::init_get
95
96
            /// Initialize underlying storage if needed and get initialization token.
97
            #[inline]
98
0
            pub fn init() -> InitToken {
99
0
                init_get().0
100
0
            }
Unexecuted instantiation: chacha20::sse2_cpuid::init
Unexecuted instantiation: chacha20::avx2_cpuid::init
Unexecuted instantiation: chacha20::avx2_cpuid::init
Unexecuted instantiation: chacha20::sse2_cpuid::init
101
102
            /// Initialize underlying storage if needed and get stored value.
103
            #[inline]
104
0
            pub fn get() -> bool {
105
0
                init_get().1
106
0
            }
Unexecuted instantiation: chacha20::avx2_cpuid::get
Unexecuted instantiation: chacha20::sse2_cpuid::get
107
        }
108
    };
109
}