/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 | | } |