Initialize random number generator in main

The random number generator can be initialized when MaxScale's other
systems are being initialized. This removes the need to initialized it
when the function is used for the first time.
This commit is contained in:
Markus Mäkelä
2017-02-08 16:42:35 +02:00
parent fdcc9333c8
commit 334e71b079
3 changed files with 50 additions and 58 deletions

View File

@ -16,6 +16,20 @@
MXS_BEGIN_DECLS MXS_BEGIN_DECLS
extern unsigned int random_jkiss(void); /**
* @brief Initialize the random number generator
*
* Uses /dev/urandom if available, and warms the generator up with 1000 iterations.
*/
void random_jkiss_init(void);
/**
* @brief Return a pseudo-random number
*
* Return a pseudo-random number that satisfies major tests for random sequences.
*
* @return A random number
*/
unsigned int random_jkiss(void);
MXS_END_DECLS MXS_END_DECLS

View File

@ -67,6 +67,7 @@
#include <maxscale/thread.h> #include <maxscale/thread.h>
#include <maxscale/utils.h> #include <maxscale/utils.h>
#include <maxscale/version.h> #include <maxscale/version.h>
#include <maxscale/random_jkiss.h>
#include "maxscale/config.h" #include "maxscale/config.h"
#include "maxscale/maxscale.h" #include "maxscale/maxscale.h"
@ -1666,6 +1667,9 @@ int main(int argc, char **argv)
goto return_main; goto return_main;
} }
/** Initialize the random number generator */
random_jkiss_init();
if (!utils_init()) if (!utils_init())
{ {
const char* logerr = "Failed to initialise utility library."; const char* logerr = "Failed to initialise utility library.";

View File

@ -16,14 +16,6 @@
* *
* See http://www0.cs.ucl.ac.uk/staff/d.jones/GoodPracticeRNG.pdf for discussion of random * See http://www0.cs.ucl.ac.uk/staff/d.jones/GoodPracticeRNG.pdf for discussion of random
* number generators (RNGs). * number generators (RNGs).
*
* @verbatim
* Revision History
*
* Date Who Description
* 26/08/15 Martin Brampton Initial implementation
*
* @endverbatim
*/ */
#include <stdbool.h> #include <stdbool.h>
@ -32,6 +24,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <maxscale/random_jkiss.h> #include <maxscale/random_jkiss.h>
#include <maxscale/debug.h>
/* Public domain code for JKISS RNG - Comment header added */ /* Public domain code for JKISS RNG - Comment header added */
@ -41,28 +34,12 @@
static unsigned int x = 123456789, y = 987654321, z = 43219876, c = 6543217; /* Seed variables */ static unsigned int x = 123456789, y = 987654321, z = 43219876, c = 6543217; /* Seed variables */
static bool init = false; static bool init = false;
static unsigned int random_jkiss_devrand(void); unsigned int random_jkiss(void)
static void random_init_jkiss(void);
/***
*
* Return a pseudo-random number that satisfies major tests for random sequences
*
* @return uint Random number
*
*/
unsigned int
random_jkiss(void)
{ {
unsigned long long t; unsigned long long t;
unsigned int result; unsigned int result;
ss_dassert(init);
if (!init)
{
/* Must set init first because initialisation calls this function */
init = true;
random_init_jkiss();
}
x = 314527869 * x + 1234567; x = 314527869 * x + 1234567;
y ^= y << 5; y ^= y << 5;
y ^= y >> 7; y ^= y >> 7;
@ -83,8 +60,7 @@ random_jkiss(void)
* @return uint Random number * @return uint Random number
* *
*/ */
static unsigned int static unsigned int random_jkiss_devrand(void)
random_jkiss_devrand(void)
{ {
int fn; int fn;
unsigned int r; unsigned int r;
@ -102,40 +78,38 @@ random_jkiss_devrand(void)
return r; return r;
} }
/*** void random_jkiss_init(void)
*
* Initialise the generator using /dev/urandom if available, and warm up
* with 1000 iterations
*
*/
static void
random_init_jkiss(void)
{ {
int newrand, i; if (!init)
if ((newrand = random_jkiss_devrand()) != 0)
{ {
x = newrand; int newrand, i;
}
if ((newrand = random_jkiss_devrand()) != 0) if ((newrand = random_jkiss_devrand()) != 0)
{ {
y = newrand; x = newrand;
} }
if ((newrand = random_jkiss_devrand()) != 0) if ((newrand = random_jkiss_devrand()) != 0)
{ {
z = newrand; y = newrand;
} }
if ((newrand = random_jkiss_devrand()) != 0) if ((newrand = random_jkiss_devrand()) != 0)
{ {
c = newrand % 698769068 + 1; /* Should be less than 698769069 */ z = newrand;
} }
/* "Warm up" our random number generator */ if ((newrand = random_jkiss_devrand()) != 0)
for (i = 0; i < 100; i++) {
{ c = newrand % 698769068 + 1; /* Should be less than 698769069 */
random_jkiss(); }
/* "Warm up" our random number generator */
for (i = 0; i < 100; i++)
{
random_jkiss();
}
init = true;
} }
} }