1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 //! A simple fast pseudorandom implementation, ranges from 0 to usize::MAX
15 //! Reference: xorshift* <https://dl.acm.org/doi/10.1145/2845077>
16 
17 use std::cell::Cell;
18 use std::collections::hash_map::RandomState;
19 use std::hash::{BuildHasher, Hasher};
20 use std::num::Wrapping;
21 
22 /// Generates a fast random ranging from 0 to usize::MAX
23 ///
24 /// # Examples
25 /// ```rust
26 /// use ylong_runtime::fastrand::fast_random;
27 /// let rand = fast_random();
28 /// assert!(rand <= u64::MAX);
29 /// ```
fast_random() -> u6430 pub fn fast_random() -> u64 {
31     thread_local! {
32         static RNG: Cell<Wrapping<u64>> = Cell::new(Wrapping(seed()));
33     }
34 
35     RNG.with(|rng| {
36         let mut s = rng.get();
37         s ^= s >> 12;
38         s ^= s << 25;
39         s ^= s >> 27;
40         rng.set(s);
41         s.0.wrapping_mul(0x2545_f491_4f6c_dd1d)
42     })
43 }
44 
seed() -> u6445 fn seed() -> u64 {
46     let seed = RandomState::new();
47 
48     let mut out = 0;
49     let mut count = 0;
50     while out == 0 {
51         count += 1;
52         let mut hasher = seed.build_hasher();
53         hasher.write_usize(count);
54         out = hasher.finish();
55     }
56     out
57 }
58