]> git.eshelyaron.com Git - emacs.git/commitdiff
Serialize random number generation on MS-Windows
authorEli Zaretskii <eliz@gnu.org>
Sat, 31 Dec 2016 11:01:19 +0000 (13:01 +0200)
committerEli Zaretskii <eliz@gnu.org>
Sat, 31 Dec 2016 11:01:19 +0000 (13:01 +0200)
* 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'.

src/w32.c

index e96f29791ea79c6912c0c94cc080adbba0d7bcb2..59dc685710efec6463197dcb2e94b8521e10bb79 100644 (file)
--- a/src/w32.c
+++ b/src/w32.c
@@ -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