/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.48.0/src/util/rand.rs
Line  | Count  | Source  | 
1  |  | cfg_rt! { | 
2  |  |     mod rt;  | 
3  |  |     pub(crate) use rt::RngSeedGenerator;  | 
4  |  |  | 
5  |  |     cfg_unstable! { | 
6  |  |         mod rt_unstable;  | 
7  |  |     }  | 
8  |  | }  | 
9  |  |  | 
10  |  | /// A seed for random number generation.  | 
11  |  | ///  | 
12  |  | /// In order to make certain functions within a runtime deterministic, a seed  | 
13  |  | /// can be specified at the time of creation.  | 
14  |  | #[allow(unreachable_pub)]  | 
15  |  | #[derive(Clone, Debug)]  | 
16  |  | pub struct RngSeed { | 
17  |  |     s: u32,  | 
18  |  |     r: u32,  | 
19  |  | }  | 
20  |  |  | 
21  |  | /// Fast random number generate.  | 
22  |  | ///  | 
23  |  | /// Implement `xorshift64+`: 2 32-bit `xorshift` sequences added together.  | 
24  |  | /// Shift triplet `[17,7,16]` was calculated as indicated in Marsaglia's  | 
25  |  | /// `Xorshift` paper: <https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf>  | 
26  |  | /// This generator passes the SmallCrush suite, part of TestU01 framework:  | 
27  |  | /// <http://simul.iro.umontreal.ca/testu01/tu01.html>  | 
28  |  | #[derive(Clone, Copy, Debug)]  | 
29  |  | pub(crate) struct FastRand { | 
30  |  |     one: u32,  | 
31  |  |     two: u32,  | 
32  |  | }  | 
33  |  |  | 
34  |  | impl RngSeed { | 
35  |  |     /// Creates a random seed using loom internally.  | 
36  | 578k  |     pub(crate) fn new() -> Self { | 
37  | 578k  |         Self::from_u64(crate::loom::rand::seed())  | 
38  | 578k  |     }  | 
39  |  |  | 
40  | 578k  |     fn from_u64(seed: u64) -> Self { | 
41  | 578k  |         let one = (seed >> 32) as u32;  | 
42  | 578k  |         let mut two = seed as u32;  | 
43  |  |  | 
44  | 578k  |         if two == 0 { | 
45  | 0  |             // This value cannot be zero  | 
46  | 0  |             two = 1;  | 
47  | 578k  |         }  | 
48  |  |  | 
49  | 578k  |         Self::from_pair(one, two)  | 
50  | 578k  |     }  | 
51  |  |  | 
52  | 2.91M  |     fn from_pair(s: u32, r: u32) -> Self { | 
53  | 2.91M  |         Self { s, r } | 
54  | 2.91M  |     }  | 
55  |  | }  | 
56  |  |  | 
57  |  | impl FastRand { | 
58  |  |     /// Initialize a new fast random number generator using the default source of entropy.  | 
59  | 560k  |     pub(crate) fn new() -> FastRand { | 
60  | 560k  |         FastRand::from_seed(RngSeed::new())  | 
61  | 560k  |     }  | 
62  |  |  | 
63  |  |     /// Initializes a new, thread-local, fast random number generator.  | 
64  | 1.17M  |     pub(crate) fn from_seed(seed: RngSeed) -> FastRand { | 
65  | 1.17M  |         FastRand { | 
66  | 1.17M  |             one: seed.s,  | 
67  | 1.17M  |             two: seed.r,  | 
68  | 1.17M  |         }  | 
69  | 1.17M  |     }  | 
70  |  |  | 
71  |  |     #[cfg(any(  | 
72  |  |         feature = "macros",  | 
73  |  |         feature = "rt-multi-thread",  | 
74  |  |         all(feature = "sync", feature = "rt")  | 
75  |  |     ))]  | 
76  | 1.12M  |     pub(crate) fn fastrand_n(&mut self, n: u32) -> u32 { | 
77  |  |         // This is similar to fastrand() % n, but faster.  | 
78  |  |         // See https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/  | 
79  | 1.12M  |         let mul = (self.fastrand() as u64).wrapping_mul(n as u64);  | 
80  | 1.12M  |         (mul >> 32) as u32  | 
81  | 1.12M  |     }  | 
82  |  |  | 
83  | 3.47M  |     fn fastrand(&mut self) -> u32 { | 
84  | 3.47M  |         let mut s1 = self.one;  | 
85  | 3.47M  |         let s0 = self.two;  | 
86  |  |  | 
87  | 3.47M  |         s1 ^= s1 << 17;  | 
88  | 3.47M  |         s1 = s1 ^ s0 ^ s1 >> 7 ^ s0 >> 16;  | 
89  |  |  | 
90  | 3.47M  |         self.one = s0;  | 
91  | 3.47M  |         self.two = s1;  | 
92  |  |  | 
93  | 3.47M  |         s0.wrapping_add(s1)  | 
94  | 3.47M  |     }  | 
95  |  | }  |