1/*
2This 64 bit pseudo random number generator is based on the engine
3written by Sebastiano Vigna from Dipartimento di Informatica of the
4Università degli Studi di Milano. The original source code can be
5found here http://xoshiro.di.unimi.it/xoshiro256starstar.c. The
6engine is supposed to perform very well on various random engine
7benchmarks.
8The original author offered his work to the public domain per the
9following original comment.
10*/
11
12/* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
13
14To the extent possible under law, the author has dedicated all copyright
15and related and neighboring rights to this software to the public domain
16worldwide. This software is distributed without any warranty.
17
18See <http://creativecommons.org/publicdomain/zero/1.0/>. */
19
20static inline uint64_t rotl(const uint64_t x, int k) {
21 return (x << k) | (x >> (64 - k));
22}
23
24typedef uint64_t random_state_engine[4];
25
26static inline void
27init_random_state_engine(random_state_engine engine, uint64_t seed)
28{
29 for (int i = 0; i < 4; i++) {
30 /* we use the splitmix64 generator to generate the 4
31 * values in the state array from the given seed.
32 * This code is adapted from
33 * http://xoshiro.di.unimi.it/splitmix64.c which was
34 * put in the public domain in the same way as the
35 * "next" function below. */
36 uint64_t z = (seed += 0x9e3779b97f4a7c15);
37 z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
38 z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
39 engine[i] = z ^ (z >> 31);
40 }
41}
42
43static inline uint64_t next(random_state_engine rse) {
44 const uint64_t output = rotl(rse[0] * 5, 7) * 9;
45
46 const uint64_t t = rse[1] << 17;
47
48 rse[2] ^= rse[0];
49 rse[3] ^= rse[1];
50 rse[1] ^= rse[2];
51 rse[0] ^= rse[3];
52
53 rse[2] ^= t;
54
55 rse[3] = rotl(rse[3], 45);
56
57 return output;
58}
59