emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master a78a167: Serialize random number generation on MS-W


From: Eli Zaretskii
Subject: [Emacs-diffs] master a78a167: Serialize random number generation on MS-Windows
Date: Sat, 31 Dec 2016 11:02:11 +0000 (UTC)

branch: master
commit a78a167a4f74759fd291802b95193a0f39a4cb59
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    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'.
---
 src/w32.c |   27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/src/w32.c b/src/w32.c
index e96f297..59dc685 100644
--- 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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]