|
13 | 13 |
|
14 | 14 | namespace LIBC_NAMESPACE {
|
15 | 15 |
|
16 |
| -// An implementation of the xorshift64star pseudo random number generator. This |
| 16 | +// An implementation of the xorshift* pseudo random number generator. This |
17 | 17 | // is a good general purpose generator for most non-cryptographics applications.
|
18 |
| -LLVM_LIBC_FUNCTION(int, rand, (void)) { |
| 18 | +static inline unsigned long xorshiftstar(unsigned long a, unsigned long b, |
| 19 | + unsigned long c, unsigned long d) { |
19 | 20 | unsigned long orig = rand_next.load(cpp::MemoryOrder::RELAXED);
|
20 | 21 | for (;;) {
|
21 | 22 | unsigned long x = orig;
|
22 |
| - x ^= x >> 12; |
23 |
| - x ^= x << 25; |
24 |
| - x ^= x >> 27; |
| 23 | + x ^= x >> a; |
| 24 | + x ^= x << b; |
| 25 | + x ^= x >> c; |
25 | 26 | if (rand_next.compare_exchange_strong(orig, x, cpp::MemoryOrder::ACQUIRE,
|
26 | 27 | cpp::MemoryOrder::RELAXED))
|
27 |
| - return static_cast<int>((x * 0x2545F4914F6CDD1Dul) >> 32) & RAND_MAX; |
| 28 | + return x * d; |
28 | 29 | sleep_briefly();
|
29 | 30 | }
|
30 | 31 | }
|
31 | 32 |
|
| 33 | +// An implementation of the xorshift64star pseudo random number generator. This |
| 34 | +// is a good general purpose generator for most non-cryptographics applications. |
| 35 | +LLVM_LIBC_FUNCTION(int, rand, (void)) { |
| 36 | + int res; |
| 37 | + if constexpr (sizeof(void *) == sizeof(uint64_t)) |
| 38 | + res = |
| 39 | + static_cast<int>(xorshiftstar(12, 25, 27, 0x2545F4914F6CDD1Dul) >> 32); |
| 40 | + else |
| 41 | + res = static_cast<int>(xorshiftstar(13, 17, 5, 1597334677ul)); |
| 42 | + return res & RAND_MAX; |
| 43 | +} |
| 44 | + |
32 | 45 | } // namespace LIBC_NAMESPACE
|
0 commit comments