diff --git a/Cargo.lock b/Cargo.lock index f186117dbe..b0dffda920 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chacha20" -version = "0.10.0-rc.10" +version = "0.10.0-rc.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c536927023d1c432e6e23a25ef45f6756094eac2ab460db5fb17a772acdfd312" +checksum = "14f3c04cdd19f5ed3271e460267fb1d94b7899ae1f7bb10ac3dfc3afb749d659" dependencies = [ "cfg-if", "cpufeatures", diff --git a/Cargo.toml b/Cargo.toml index 490c6c7191..08bea58dfb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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] diff --git a/benches/Cargo.lock b/benches/Cargo.lock index 27c650c87c..62591cf018 100644 --- a/benches/Cargo.lock +++ b/benches/Cargo.lock @@ -72,9 +72,9 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chacha20" -version = "0.10.0-rc.10" +version = "0.10.0-rc.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c536927023d1c432e6e23a25ef45f6756094eac2ab460db5fb17a772acdfd312" +checksum = "14f3c04cdd19f5ed3271e460267fb1d94b7899ae1f7bb10ac3dfc3afb749d659" dependencies = [ "cfg-if", "cpufeatures", @@ -452,7 +452,7 @@ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rand" -version = "0.10.0-rc.8" +version = "0.10.0-rc.9" dependencies = [ "chacha20", "getrandom", @@ -467,7 +467,7 @@ checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" [[package]] name = "rand_pcg" -version = "0.10.0-rc.7" +version = "0.10.0-rc.9" dependencies = [ "rand_core", ] diff --git a/benches/Cargo.toml b/benches/Cargo.toml index c5b4b79835..cc1da706d6 100644 --- a/benches/Cargo.toml +++ b/benches/Cargo.toml @@ -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" diff --git a/src/rngs/thread.rs b/src/rngs/thread.rs index b57ea10503..63d334dae7 100644 --- a/src/rngs/thread.rs +++ b/src/rngs/thread.rs @@ -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; @@ -35,29 +34,25 @@ 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; type Results = ::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); } } @@ -65,24 +60,17 @@ impl Generator for ReseedingCore { 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); } } @@ -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, }))) } );