Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ exclude = ["benches", "distr_test"]
rand_core = { version = "0.10.0-rc-6", default-features = false }
log = { version = "0.4.4", optional = true }
serde = { version = "1.0.103", features = ["derive"], optional = true }
chacha20 = { version = "0.10.0-rc.10", default-features = false, features = ["rng"], optional = true }
chacha20 = { version = "0.10.0-rc.11", default-features = false, features = ["rng"], optional = true }
getrandom = { version = "0.4.0-rc.1", optional = true }

[dev-dependencies]
Expand Down
8 changes: 4 additions & 4 deletions benches/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion benches/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ simd_support = ["rand/simd_support"]
[dev-dependencies]
rand = { path = ".." }
rand_pcg = { path = "../rand_pcg" }
chacha20 = { version = "0.10.0-rc.10", default-features = false, features = ["rng"] }
chacha20 = { version = "0.10.0-rc.11", default-features = false, features = ["rng"] }
criterion = "0.5"
criterion-cycles-per-byte = "0.6"

Expand Down
31 changes: 9 additions & 22 deletions src/rngs/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

//! Thread-local random number generator

use core::mem::size_of_val;
use core::{cell::UnsafeCell, convert::Infallible};
use std::fmt;
use std::rc::Rc;
Expand All @@ -35,54 +34,43 @@ use rand_core::{TryCryptoRng, TryRng};

// Number of generated bytes after which to reseed `ThreadRng`.
// According to benchmarks, reseeding has a noticeable impact with thresholds
// of 32 kB and less. We choose 64 kB to avoid significant overhead.
const THREAD_RNG_RESEED_THRESHOLD: i64 = 1024 * 64;
// of 32 kB and less. We choose 64 kiB output to avoid significant overhead;
// since a block consists of 16 4-byte words this equals 1024 blocks.
const RESEED_BLOCK_THRESHOLD: u64 = 1024;

type Core = chacha20::ChaChaCore<chacha20::R12, chacha20::variants::Legacy>;
type Results = <Core as Generator>::Output;

struct ReseedingCore {
inner: Core,
bytes_until_reseed: i64,
}

impl Generator for ReseedingCore {
type Output = Results;

#[inline(always)]
fn generate(&mut self, results: &mut Results) {
if self.bytes_until_reseed <= 0 {
// We get better performance by not calling only `reseed` here
// and continuing with the rest of the function, but by directly
// returning from a non-inlined function.
return self.reseed_and_generate(results);
if self.inner.get_block_pos() >= RESEED_BLOCK_THRESHOLD {
self.try_to_reseed();
}
let num_bytes = size_of_val(results);
self.bytes_until_reseed -= num_bytes as i64;
self.inner.generate(results);
}
}

impl ReseedingCore {
/// Reseed the internal PRNG.
fn reseed(&mut self) -> Result<(), SysError> {
Core::try_from_rng(&mut SysRng).map(|result| {
self.bytes_until_reseed = THREAD_RNG_RESEED_THRESHOLD;
self.inner = result
})
Core::try_from_rng(&mut SysRng).map(|result| self.inner = result)
}

#[cold]
#[inline(never)]
fn reseed_and_generate(&mut self, results: &mut Results) {
fn try_to_reseed(&mut self) {
trace!("Reseeding RNG (periodic reseed)");

let num_bytes = size_of_val(results);

if let Err(e) = self.reseed() {
warn!("Reseeding RNG failed: {e}");
}

self.bytes_until_reseed = THREAD_RNG_RESEED_THRESHOLD - num_bytes as i64;
self.inner.generate(results);
}
}

Expand Down Expand Up @@ -170,7 +158,6 @@ thread_local!(
inner: Core::try_from_rng(&mut SysRng).unwrap_or_else(|err| {
panic!("could not initialize ThreadRng: {}", err)
}),
bytes_until_reseed: THREAD_RNG_RESEED_THRESHOLD,
})))
}
);
Expand Down