Line data Source code
1 1 : /** 2 : * @file test/test_rng.h 3 : * 4 : * @brief Pseudo random number generator for tests 5 : * 6 : * An acceptable quality pseudo random number generator to be used in tests 7 : * 8 : * SPDX-FileCopyrightText: 2008-2021 HPDCS Group <rootsim@googlegroups.com> 9 : * SPDX-License-Identifier: GPL-3.0-only 10 : */ 11 : #pragma once 12 : 13 : #include <core/intrinsics.h> 14 : 15 : #include <memory.h> 16 : #include <stdint.h> 17 : 18 : /// The type of this pseudo random number generator state 19 1 : typedef __uint128_t test_rng_state; 20 : 21 : /// The multiplier of this linear congruential PRNG generator 22 1 : #define LCG_MULTIPLIER \ 23 : ((((__uint128_t)0x0fc94e3bf4e9ab32ULL) << 64) + 0x866458cd56f5e605ULL) 24 : 25 : /** 26 : * @brief Initializes the random number generator 27 : * @param rng_state a test_rng_state object which will be initialized 28 : * @param initseq the seed to use to initialize @a rng_state 29 : */ 30 1 : #define lcg_init(rng_state, initseq) (rng_state) = ((initseq) << 1u) | 1u 31 : 32 : /** 33 : * @brief Computes a pseudo random 64 bit number 34 : * @param rng_state a test_rng_state object 35 : * @return a uniformly distributed 64 bit pseudo random number 36 : */ 37 1 : #define lcg_random_u(rng_state) \ 38 : __extension__({ \ 39 : (rng_state) *= LCG_MULTIPLIER; \ 40 : uint64_t __rng_val = (uint64_t)((rng_state) >> 64); \ 41 : __rng_val; \ 42 : }) 43 : 44 : /** 45 : * @brief Computes a pseudo random number in the [0, 1] range 46 : * @param rng_state a test_rng_state object 47 : * @return a uniformly distributed pseudo random double value in [0, 1] 48 : */ 49 1 : #define lcg_random(rng_state) \ 50 : __extension__({ \ 51 : uint64_t __u_val = lcg_random_u(rng_state); \ 52 : double __ret = 0.0; \ 53 : if (__builtin_expect(!!__u_val, 1)) { \ 54 : unsigned __lzs = intrinsics_clz(__u_val) + 1; \ 55 : __u_val <<= __lzs; \ 56 : __u_val >>= 12; \ 57 : \ 58 : uint64_t __exp = 1023 - __lzs; \ 59 : __u_val |= __exp << 52; \ 60 : \ 61 : memcpy(&__ret, &__u_val, sizeof(double)); \ 62 : } \ 63 : __ret; \ 64 : }) 65 :