Skip to content

Commit 9bfe39b

Browse files
committed
Add LazyBool for lock-free initialization
1 parent e02e946 commit 9bfe39b

File tree

5 files changed

+38
-21
lines changed

5 files changed

+38
-21
lines changed

Cargo.toml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ libc = "0.2.54"
2727
[target.'cfg(any(unix, target_os = "redox"))'.dependencies]
2828
lazy_static = "1.3.0"
2929

30-
# For caching result of CPUID check for RDRAND
31-
[target.'cfg(target_os = "uefi")'.dependencies]
32-
lazy_static = { version = "1.3.0", features = ["spin_no_std"] }
33-
3430
[target.wasm32-unknown-unknown.dependencies]
3531
wasm-bindgen = { version = "0.2.29", optional = true }
3632
stdweb = { version = "0.4.9", optional = true }

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ macro_rules! error {
141141
extern crate std;
142142

143143
mod error;
144+
#[allow(dead_code)]
145+
mod util;
144146
pub use crate::error::Error;
145147

146148
// System-specific implementations.

src/linux_android.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
//! Implementation for Linux / Android
1010
extern crate std;
1111

12+
use crate::util::LazyBool;
1213
use crate::{use_file, Error};
1314
use core::num::NonZeroU32;
14-
use lazy_static::lazy_static;
1515
use std::io;
1616

1717
fn syscall_getrandom(dest: &mut [u8], block: bool) -> Result<usize, io::Error> {
@@ -29,18 +29,15 @@ fn syscall_getrandom(dest: &mut [u8], block: bool) -> Result<usize, io::Error> {
2929
}
3030

3131
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
32-
lazy_static! {
33-
static ref HAS_GETRANDOM: bool = is_getrandom_available();
34-
}
35-
match *HAS_GETRANDOM {
36-
true => {
37-
let mut start = 0;
38-
while start < dest.len() {
39-
start += syscall_getrandom(&mut dest[start..], true)?;
40-
}
41-
Ok(())
32+
static HAS_GETRANDOM: LazyBool = LazyBool::new();
33+
if HAS_GETRANDOM.unsync_init(is_getrandom_available) {
34+
let mut start = 0;
35+
while start < dest.len() {
36+
start += syscall_getrandom(&mut dest[start..], true)?;
4237
}
43-
false => use_file::getrandom_inner(dest),
38+
Ok(())
39+
} else {
40+
use_file::getrandom_inner(dest)
4441
}
4542
}
4643

src/rdrand.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// except according to those terms.
88

99
//! Implementation for SGX using RDRAND instruction
10+
use crate::util::LazyBool;
1011
use crate::Error;
1112
use core::arch::x86_64::_rdrand64_step;
1213
use core::mem;
@@ -55,13 +56,10 @@ fn is_rdrand_supported() -> bool {
5556
#[cfg(not(target_feature = "rdrand"))]
5657
fn is_rdrand_supported() -> bool {
5758
use core::arch::x86_64::__cpuid;
58-
use lazy_static::lazy_static;
5959
// SAFETY: All x86_64 CPUs support CPUID leaf 1
6060
const FLAG: u32 = 1 << 30;
61-
lazy_static! {
62-
static ref HAS_RDRAND: bool = unsafe { __cpuid(1).ecx & FLAG != 0 };
63-
}
64-
*HAS_RDRAND
61+
static HAS_RDRAND: LazyBool = LazyBool::new();
62+
HAS_RDRAND.unsync_init(|| unsafe { (__cpuid(1).ecx & FLAG) != 0 })
6563
}
6664

6765
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {

src/util.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use core::sync::atomic::{AtomicBool, Ordering};
2+
3+
#[derive(Debug)]
4+
pub struct LazyBool {
5+
value: AtomicBool,
6+
needs_init: AtomicBool,
7+
}
8+
9+
impl LazyBool {
10+
pub const fn new() -> Self {
11+
LazyBool {
12+
value: AtomicBool::new(false),
13+
needs_init: AtomicBool::new(true),
14+
}
15+
}
16+
17+
pub fn unsync_init(&self, init: impl FnOnce() -> bool) -> bool {
18+
if self.needs_init.load(Ordering::SeqCst) {
19+
self.value.store(init(), Ordering::SeqCst);
20+
self.needs_init.store(false, Ordering::SeqCst);
21+
}
22+
self.value.load(Ordering::SeqCst)
23+
}
24+
}

0 commit comments

Comments
 (0)