LCOV - code coverage report
Current view: top level - core/test - test_rng.h Hit Total Coverage
Test: ROOT-Sim develop Documentation Coverage Lines: 6 6 100.0 %
Date: 2021-03-02 11:24:52

          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             : 

Generated by: LCOV version 1.14