open_coroutine_queue/
rand.rs1use std::cell::Cell;
2
3use parking_lot::Mutex;
4use std::collections::hash_map::RandomState;
5use std::hash::BuildHasher;
6use std::sync::atomic::AtomicU32;
7use std::sync::atomic::Ordering::Relaxed;
8
9static COUNTER: AtomicU32 = AtomicU32::new(1);
10
11pub(crate) fn seed() -> u64 {
12 let rand_state = RandomState::new();
13 rand_state.hash_one(COUNTER.fetch_add(1, Relaxed))
16}
17
18#[repr(C)]
27#[derive(Debug)]
28pub struct RngSeedGenerator {
29 state: Mutex<FastRand>,
32}
33
34impl RngSeedGenerator {
35 #[must_use]
37 pub fn new(seed: RngSeed) -> Self {
38 Self {
39 state: Mutex::new(FastRand::new(seed)),
40 }
41 }
42
43 pub fn next_seed(&self) -> RngSeed {
45 let rng = self.state.lock();
46
47 let s = rng.fastrand();
48 let r = rng.fastrand();
49
50 RngSeed::from_pair(s, r)
51 }
52
53 #[must_use]
55 pub fn next_generator(&self) -> Self {
56 RngSeedGenerator::new(self.next_seed())
57 }
58}
59
60impl Default for RngSeedGenerator {
61 fn default() -> Self {
62 Self::new(RngSeed::new())
63 }
64}
65
66#[allow(unreachable_pub)]
71#[derive(Debug, Copy, Clone)]
72pub struct RngSeed {
73 s: u32,
74 r: u32,
75}
76
77impl RngSeed {
78 #[must_use]
80 pub fn new() -> Self {
81 Self::from_u64(seed())
82 }
83
84 #[allow(clippy::cast_possible_truncation)]
85 fn from_u64(seed: u64) -> Self {
86 let one = (seed >> 32) as u32;
87 let mut two = seed as u32;
88
89 if two == 0 {
90 two = 1;
92 }
93
94 Self::from_pair(one, two)
95 }
96
97 fn from_pair(s: u32, r: u32) -> Self {
98 Self { s, r }
99 }
100}
101
102impl Default for RngSeed {
103 fn default() -> Self {
104 Self::new()
105 }
106}
107
108#[repr(C)]
116#[derive(Debug)]
117pub struct FastRand {
118 one: Cell<u32>,
119 two: Cell<u32>,
120}
121
122impl FastRand {
123 #[must_use]
125 pub fn new(seed: RngSeed) -> FastRand {
126 FastRand {
127 one: Cell::new(seed.s),
128 two: Cell::new(seed.r),
129 }
130 }
131
132 pub fn replace_seed(&self, seed: RngSeed) -> RngSeed {
138 let old_seed = RngSeed::from_pair(self.one.get(), self.two.get());
139
140 _ = self.one.replace(seed.s);
141 _ = self.two.replace(seed.r);
142
143 old_seed
144 }
145
146 pub fn fastrand_n(&self, n: u32) -> u32 {
147 let mul = (u64::from(self.fastrand())).wrapping_mul(u64::from(n));
150 (mul >> 32) as u32
151 }
152
153 fn fastrand(&self) -> u32 {
154 let mut s1 = self.one.get();
155 let s0 = self.two.get();
156
157 s1 ^= s1 << 17;
158 s1 = s1 ^ s0 ^ s1 >> 7 ^ s0 >> 16;
159
160 self.one.set(s0);
161 self.two.set(s1);
162
163 s0.wrapping_add(s1)
164 }
165}