|
14 | 14 |
|
15 | 15 | namespace LIBC_NAMESPACE_DECL {
|
16 | 16 |
|
17 |
| -// An implementation of the xorshift64star pseudo random number generator. This |
18 |
| -// is a good general purpose generator for most non-cryptographics applications. |
19 | 17 | LLVM_LIBC_FUNCTION(int, rand, (void)) {
|
20 | 18 | unsigned long orig = rand_next.load(cpp::MemoryOrder::RELAXED);
|
21 |
| - for (;;) { |
22 |
| - unsigned long x = orig; |
23 |
| - x ^= x >> 12; |
24 |
| - x ^= x << 25; |
25 |
| - x ^= x >> 27; |
26 |
| - if (rand_next.compare_exchange_strong(orig, x, cpp::MemoryOrder::ACQUIRE, |
27 |
| - cpp::MemoryOrder::RELAXED)) |
28 |
| - return static_cast<int>((x * 0x2545F4914F6CDD1Dul) >> 32) & RAND_MAX; |
29 |
| - sleep_briefly(); |
| 19 | + |
| 20 | + // An implementation of the xorshift64star pseudo random number generator. |
| 21 | + // This is a good general purpose generator for most non-cryptographics |
| 22 | + // applications. |
| 23 | + if constexpr (sizeof(void *) == sizeof(uint64_t)) { |
| 24 | + for (;;) { |
| 25 | + unsigned long x = orig; |
| 26 | + x ^= x >> 12; |
| 27 | + x ^= x << 25; |
| 28 | + x ^= x >> 27; |
| 29 | + if (rand_next.compare_exchange_strong(orig, x, cpp::MemoryOrder::ACQUIRE, |
| 30 | + cpp::MemoryOrder::RELAXED)) |
| 31 | + return static_cast<int>((x * 0x2545F4914F6CDD1Dul) >> 32) & RAND_MAX; |
| 32 | + sleep_briefly(); |
| 33 | + } |
| 34 | + } else { |
| 35 | + // This is the xorshift32 pseudo random number generator, slightly different |
| 36 | + // from the 64-bit star version above, as the previous version fails to |
| 37 | + // generate uniform enough LSB in 32-bit systems. |
| 38 | + for (;;) { |
| 39 | + unsigned long x = orig; |
| 40 | + x ^= x >> 13; |
| 41 | + x ^= x << 27; |
| 42 | + x ^= x >> 5; |
| 43 | + if (rand_next.compare_exchange_strong(orig, x, cpp::MemoryOrder::ACQUIRE, |
| 44 | + cpp::MemoryOrder::RELAXED)) |
| 45 | + return static_cast<int>(x * 1597334677ul) & RAND_MAX; |
| 46 | + sleep_briefly(); |
| 47 | + } |
30 | 48 | }
|
| 49 | + __builtin_unreachable(); |
31 | 50 | }
|
32 | 51 |
|
33 | 52 | } // namespace LIBC_NAMESPACE_DECL
|
0 commit comments