xref: /freebsd/sys/contrib/openzfs/module/zfs/vdev_draid_rand.c (revision 61145dc2b94f12f6a47344fb9aac702321880e43)
1 // SPDX-License-Identifier: LicenseRef-OpenZFS-ThirdParty-PublicDomain
2 /*
3  * Xorshift Pseudo Random Number Generator based on work by David Blackman
4  * and Sebastiano Vigna (vigna@acm.org).
5  *
6  *   "Further scramblings of Marsaglia's xorshift generators"
7  *   http://vigna.di.unimi.it/ftp/papers/xorshiftplus.pdf
8  *   http://prng.di.unimi.it/xoroshiro128plusplus.c
9  *
10  * To the extent possible under law, the author has dedicated all copyright
11  * and related and neighboring rights to this software to the public domain
12  * worldwide. This software is distributed without any warranty.
13  *
14  * See <http://creativecommons.org/publicdomain/zero/1.0/>.
15  *
16  * This is xoroshiro128++ 1.0, one of our all-purpose, rock-solid,
17  * small-state generators. It is extremely (sub-ns) fast and it passes all
18  * tests we are aware of, but its state space is large enough only for
19  * mild parallelism.
20  */
21 
22 #include <sys/vdev_draid.h>
23 
rotl(const uint64_t x,int k)24 static inline uint64_t rotl(const uint64_t x, int k)
25 {
26 	return (x << k) | (x >> (64 - k));
27 }
28 
29 uint64_t
vdev_draid_rand(uint64_t * s)30 vdev_draid_rand(uint64_t *s)
31 {
32 	const uint64_t s0 = s[0];
33 	uint64_t s1 = s[1];
34 	const uint64_t result = rotl(s0 + s1, 17) + s0;
35 
36 	s1 ^= s0;
37 	s[0] = rotl(s0, 49) ^ s1 ^ (s1 << 21); // a, b
38 	s[1] = rotl(s1, 28); // c
39 
40 	return (result);
41 }
42