88
99//! Thread-local random number generator
1010
11- use core:: mem:: size_of_val;
1211use core:: { cell:: UnsafeCell , convert:: Infallible } ;
1312use std:: fmt;
1413use std:: rc:: Rc ;
@@ -35,54 +34,45 @@ use rand_core::{TryCryptoRng, TryRng};
3534
3635// Number of generated bytes after which to reseed `ThreadRng`.
3736// According to benchmarks, reseeding has a noticeable impact with thresholds
38- // of 32 kB and less. We choose 64 kB to avoid significant overhead.
39- const THREAD_RNG_RESEED_THRESHOLD : i64 = 1024 * 64 ;
37+ // of 32 kB and less. We choose 64 kB = 4096 blocks to avoid significant overhead.
38+ const RESEED_BLOCK_THRESHOLD : u64 = 4096 ;
4039
4140type Core = chacha20:: ChaChaCore < chacha20:: R12 , chacha20:: variants:: Legacy > ;
4241type Results = <Core as Generator >:: Output ;
4342
4443struct ReseedingCore {
4544 inner : Core ,
46- bytes_until_reseed : i64 ,
4745}
4846
4947impl Generator for ReseedingCore {
5048 type Output = Results ;
5149
5250 fn generate ( & mut self , results : & mut Results ) {
53- if self . bytes_until_reseed <= 0 {
51+ if self . inner . get_block_pos ( ) >= RESEED_BLOCK_THRESHOLD {
5452 // We get better performance by not calling only `reseed` here
5553 // and continuing with the rest of the function, but by directly
5654 // returning from a non-inlined function.
5755 return self . reseed_and_generate ( results) ;
5856 }
59- let num_bytes = size_of_val ( results) ;
60- self . bytes_until_reseed -= num_bytes as i64 ;
6157 self . inner . generate ( results) ;
6258 }
6359}
6460
6561impl ReseedingCore {
6662 /// Reseed the internal PRNG.
6763 fn reseed ( & mut self ) -> Result < ( ) , SysError > {
68- Core :: try_from_rng ( & mut SysRng ) . map ( |result| {
69- self . bytes_until_reseed = THREAD_RNG_RESEED_THRESHOLD ;
70- self . inner = result
71- } )
64+ Core :: try_from_rng ( & mut SysRng ) . map ( |result| self . inner = result)
7265 }
7366
7467 #[ inline( never) ]
7568 fn reseed_and_generate ( & mut self , results : & mut Results ) {
7669 trace ! ( "Reseeding RNG (periodic reseed)" ) ;
7770
78- let num_bytes = size_of_val ( results) ;
79-
8071 if let Err ( e) = self . reseed ( ) {
8172 warn ! ( "Reseeding RNG failed: {}" , e) ;
8273 let _ = e;
8374 }
8475
85- self . bytes_until_reseed = THREAD_RNG_RESEED_THRESHOLD - num_bytes as i64 ;
8676 self . inner . generate ( results) ;
8777 }
8878}
@@ -171,7 +161,6 @@ thread_local!(
171161 inner: Core :: try_from_rng( & mut SysRng ) . unwrap_or_else( |err| {
172162 panic!( "could not initialize ThreadRng: {}" , err)
173163 } ) ,
174- bytes_until_reseed: THREAD_RNG_RESEED_THRESHOLD ,
175164 } ) ) )
176165 }
177166) ;
0 commit comments