diff --git a/src/backends/rdrand.rs b/src/backends/rdrand.rs index 347786a5..b9f10bcc 100644 --- a/src/backends/rdrand.rs +++ b/src/backends/rdrand.rs @@ -1,10 +1,7 @@ //! RDRAND backend for x86(-64) targets -use crate::{util::slice_as_uninit, Error}; +use crate::{lazy::LazyBool, util::slice_as_uninit, Error}; use core::mem::{size_of, MaybeUninit}; -#[path = "../lazy.rs"] -mod lazy; - #[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))] compile_error!("`rdrand` backend can be enabled only for x86 and x86-64 targets!"); @@ -20,7 +17,7 @@ cfg_if! { } } -static RDRAND_GOOD: lazy::LazyBool = lazy::LazyBool::new(); +static RDRAND_GOOD: LazyBool = LazyBool::new(); // Recommendation from "IntelĀ® Digital Random Number Generator (DRNG) Software // Implementation Guide" - Section 5.2.1 and "IntelĀ® 64 and IA-32 Architectures diff --git a/src/backends/rndr.rs b/src/backends/rndr.rs index 7db90355..febdc673 100644 --- a/src/backends/rndr.rs +++ b/src/backends/rndr.rs @@ -60,10 +60,19 @@ unsafe fn rndr_fill(dest: &mut [MaybeUninit]) -> Option<()> { Some(()) } +#[cfg(target_feature = "rand")] fn is_rndr_available() -> bool { + true +} +#[cfg(not(target_feature = "rand"))] +fn is_rndr_available() -> bool { + use crate::lazy::LazyBool; + static RNDR_GOOD: LazyBool = LazyBool::new(); + cfg_if::cfg_if! { - if #[cfg(target_feature = "rand")] { - true + if #[cfg(feature = "std")] { + extern crate std; + RNDR_GOOD.unsync_init(|| std::arch::is_aarch64_feature_detected!("rand")) } else if #[cfg(target_os = "linux")] { /// Check whether FEAT_RNG is available on the system /// @@ -87,14 +96,7 @@ fn is_rndr_available() -> bool { (id_aa64isar0 >> 60) & 0xf >= 1 } - #[path = "../lazy.rs"] mod lazy; - static RNDR_GOOD: lazy::LazyBool = lazy::LazyBool::new(); RNDR_GOOD.unsync_init(mrs_check) - } else if #[cfg(feature = "std")] { - extern crate std; - #[path = "../lazy.rs"] mod lazy; - static RNDR_GOOD: lazy::LazyBool = lazy::LazyBool::new(); - RNDR_GOOD.unsync_init(|| std::arch::is_aarch64_feature_detected!("rand")) } else { compile_error!( "RNDR `no_std` runtime detection is currently supported only on Linux targets. \ @@ -105,32 +107,29 @@ fn is_rndr_available() -> bool { } pub fn inner_u32() -> Result { - if is_rndr_available() { - // SAFETY: after this point, we know the `rand` target feature is enabled - let res = unsafe { rndr() }; - res.map(truncate).ok_or(Error::RNDR_FAILURE) - } else { - Err(Error::RNDR_NOT_AVAILABLE) + if !is_rndr_available() { + return Err(Error::RNDR_NOT_AVAILABLE); } + // SAFETY: after this point, we know the `rand` target feature is enabled + let res = unsafe { rndr() }; + res.map(truncate).ok_or(Error::RNDR_FAILURE) } pub fn inner_u64() -> Result { - if is_rndr_available() { - // SAFETY: after this point, we know the `rand` target feature is enabled - let res = unsafe { rndr() }; - res.ok_or(Error::RNDR_FAILURE) - } else { - Err(Error::RNDR_NOT_AVAILABLE) + if !is_rndr_available() { + return Err(Error::RNDR_NOT_AVAILABLE); } + // SAFETY: after this point, we know the `rand` target feature is enabled + let res = unsafe { rndr() }; + res.ok_or(Error::RNDR_FAILURE) } pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - if is_rndr_available() { - // SAFETY: after this point, we know the `rand` target feature is enabled - unsafe { rndr_fill(dest).ok_or(Error::RNDR_FAILURE) } - } else { - Err(Error::RNDR_NOT_AVAILABLE) + if !is_rndr_available() { + return Err(Error::RNDR_NOT_AVAILABLE); } + // SAFETY: after this point, we know the `rand` target feature is enabled + unsafe { rndr_fill(dest).ok_or(Error::RNDR_FAILURE) } } impl Error { diff --git a/src/lazy.rs b/src/lazy.rs index b191aa6d..41ca8615 100644 --- a/src/lazy.rs +++ b/src/lazy.rs @@ -1,4 +1,5 @@ -//! Helpers built around pointer-sized atomics. +//! Helpers built around pointer-sized atomics. Not used for all targets. +#![allow(dead_code)] use core::sync::atomic::{AtomicUsize, Ordering}; // This structure represents a lazily initialized static usize value. Useful diff --git a/src/lib.rs b/src/lib.rs index 2ac0ad0b..2fef6f9e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,6 +33,8 @@ use core::mem::MaybeUninit; mod backends; mod error; +#[cfg(target_has_atomic = "ptr")] +mod lazy; mod util; #[cfg(feature = "std")]