Serialize random number generation on MS-Windows

* src/w32.c (rand_as183): New function.
(random): Use it instead of MS runtime's 'rand'.  This avoids
producing separate and identical random series in each Lisp
thread.
(srandom): Modify to supply 3 seed values to 'rand_as183'.
This commit is contained in:
Eli Zaretskii 2016-12-31 13:01:19 +02:00
parent 3b25ffa7eb
commit a78a167a4f

View file

@ -2154,17 +2154,40 @@ w32_init_random (void *buf, ptrdiff_t buflen)
return -1;
}
/* MS-Windows 'rand' produces separate identical series for each
thread, so we replace it with our version. */
/* Algorithm AS183: An Efficient and Portable Pseudo-random Number
Generator, by B.A. Wichmann, I.D. Hill. AS, v31, No. 2 (1982). */
static int ix = 3172, iy = 9814, iz = 20125;
#define RAND_MAX_X 30269
#define RAND_MAX_Y 30307
#define RAND_MAX_Z 30323
static int
rand_as183 (void)
{
ix = (171 * ix) % RAND_MAX_X;
iy = (172 * iy) % RAND_MAX_Y;
iz = (170 * iz) % RAND_MAX_Z;
return (ix + iy + iz) & 0x7fff;
}
int
random (void)
{
/* rand () on NT gives us 15 random bits...hack together 30 bits. */
return ((rand () << 15) | rand ());
/* rand_as183 () gives us 15 random bits...hack together 30 bits. */
return ((rand_as183 () << 15) | rand_as183 ());
}
void
srandom (int seed)
{
srand (seed);
ix = rand () % RAND_MAX_X;
iy = rand () % RAND_MAX_Y;
iz = rand () % RAND_MAX_Z;
}
/* Return the maximum length in bytes of a multibyte character