aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2012-08-31 18:04:26 -0700
committerPaul Eggert2012-08-31 18:04:26 -0700
commit0e23ef9ddeefadcba94824c09e412c961de283e7 (patch)
tree8bd5c2973ce8d2f96b727b2eed8b4603a577a141 /src
parent5bf647499a5f6d08ac8aa4809ebce22acf1330b3 (diff)
downloademacs-0e23ef9ddeefadcba94824c09e412c961de283e7.tar.gz
emacs-0e23ef9ddeefadcba94824c09e412c961de283e7.zip
Better seed support for (random).
* doc/lispref/numbers.texi (Random Numbers): Document new behavior of the calls (random) and (random STRING). * etc/NEWS: Document new behavior of (random), (random "string"). * lisp/play/5x5.el, lisp/play/animate.el, lisp/play/cookie1.el: * lisp/play/dissociate.el, lisp/play/doctor.el, lisp/play/dunnet.el: * lisp/play/gomoku.el, lisp/play/landmark.el, lisp/play/mpuz.el: * lisp/play/tetris.el, lisp/play/zone.el: * lisp/calc/calc-comb.el (math-init-random-base): * lisp/play/blackbox.el (bb-init-board): * lisp/play/life.el (life): * lisp/server.el (server-use-tcp): * lisp/type-break.el (type-break): Remove unnecessary call to (random t). * lisp/net/sasl.el (sasl-unique-id-function): Change (random t) to (random), now that the latter is more random. * lisp/play/life.el (life-initialized): Remove no-longer-needed var. * lisp/gnus/gnus-sync.el (gnus-sync-lesync-setup): * lisp/gnus/message.el (message-canlock-generate, message-unique-id): Change (random t) to (random), now that the latter is more random. * lisp/org/org-id.el (org-id-uuid): Change (random t) to (random), now that the latter is more random. * src/emacs.c (main): Call init_random. * src/fns.c (Frandom): Set the seed from a string argument, if given. Remove long-obsolete Gentzel cruft. * src/lisp.h, src/sysdep.c (seed_random): Now takes address and size, not long. (init_random): New function.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog9
-rw-r--r--src/emacs.c1
-rw-r--r--src/fns.c28
-rw-r--r--src/lisp.h3
-rw-r--r--src/sysdep.c24
5 files changed, 39 insertions, 26 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 4db48bbb969..ad96c948466 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,12 @@
12012-09-01 Paul Eggert <eggert@cs.ucla.edu>
2
3 Better seed support for (random).
4 * emacs.c (main): Call init_random.
5 * fns.c (Frandom): Set the seed from a string argument, if given.
6 Remove long-obsolete Gentzel cruft.
7 * lisp.h, sysdep.c (seed_random): Now takes address and size, not long.
8 (init_random): New function.
9
12012-08-31 Dmitry Antipov <dmantipov@yandex.ru> 102012-08-31 Dmitry Antipov <dmantipov@yandex.ru>
2 11
3 Remove mark_ttys function and fix tty_display_info initialization. 12 Remove mark_ttys function and fix tty_display_info initialization.
diff --git a/src/emacs.c b/src/emacs.c
index 7ff5c43dbea..842546461b6 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1281,6 +1281,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1281 init_data (); 1281 init_data ();
1282 init_atimer (); 1282 init_atimer ();
1283 running_asynch_code = 0; 1283 running_asynch_code = 0;
1284 init_random ();
1284 1285
1285 no_loadup 1286 no_loadup
1286 = argmatch (argv, argc, "-nl", "--no-loadup", 6, NULL, &skip_args); 1287 = argmatch (argv, argc, "-nl", "--no-loadup", 6, NULL, &skip_args);
diff --git a/src/fns.c b/src/fns.c
index f6acdcada3f..2dee8515799 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -74,32 +74,16 @@ Other values of LIMIT are ignored. */)
74 (Lisp_Object limit) 74 (Lisp_Object limit)
75{ 75{
76 EMACS_INT val; 76 EMACS_INT val;
77 Lisp_Object lispy_val;
78 77
79 if (EQ (limit, Qt)) 78 if (EQ (limit, Qt))
80 { 79 init_random ();
81 EMACS_TIME t = current_emacs_time (); 80 else if (STRINGP (limit))
82 seed_random (getpid () ^ EMACS_SECS (t) ^ EMACS_NSECS (t)); 81 seed_random (SSDATA (limit), SBYTES (limit));
83 }
84 82
83 val = get_random ();
85 if (NATNUMP (limit) && XFASTINT (limit) != 0) 84 if (NATNUMP (limit) && XFASTINT (limit) != 0)
86 { 85 val %= XFASTINT (limit);
87 /* Try to take our random number from the higher bits of VAL, 86 return make_number (val);
88 not the lower, since (says Gentzel) the low bits of `random'
89 are less random than the higher ones. We do this by using the
90 quotient rather than the remainder. At the high end of the RNG
91 it's possible to get a quotient larger than n; discarding
92 these values eliminates the bias that would otherwise appear
93 when using a large n. */
94 EMACS_INT denominator = (INTMASK + 1) / XFASTINT (limit);
95 do
96 val = get_random () / denominator;
97 while (val >= XFASTINT (limit));
98 }
99 else
100 val = get_random ();
101 XSETINT (lispy_val, val);
102 return lispy_val;
103} 87}
104 88
105/* Heuristic on how many iterations of a tight loop can be safely done 89/* Heuristic on how many iterations of a tight loop can be safely done
diff --git a/src/lisp.h b/src/lisp.h
index 80c49703f52..2815a2ae325 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3405,7 +3405,8 @@ extern void child_setup_tty (int);
3405extern void setup_pty (int); 3405extern void setup_pty (int);
3406extern int set_window_size (int, int, int); 3406extern int set_window_size (int, int, int);
3407extern EMACS_INT get_random (void); 3407extern EMACS_INT get_random (void);
3408extern void seed_random (long); 3408extern void seed_random (void *, ptrdiff_t);
3409extern void init_random (void);
3409extern int emacs_open (const char *, int, int); 3410extern int emacs_open (const char *, int, int);
3410extern int emacs_close (int); 3411extern int emacs_close (int);
3411extern ptrdiff_t emacs_read (int, char *, ptrdiff_t); 3412extern ptrdiff_t emacs_read (int, char *, ptrdiff_t);
diff --git a/src/sysdep.c b/src/sysdep.c
index 183ee005227..edd54de84d4 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1765,19 +1765,37 @@ init_signals (void)
1765#endif /* !RAND_BITS */ 1765#endif /* !RAND_BITS */
1766 1766
1767void 1767void
1768seed_random (long int arg) 1768seed_random (void *seed, ptrdiff_t seed_size)
1769{ 1769{
1770#if defined HAVE_RANDOM || ! defined HAV_LRAND48
1771 unsigned int arg = 0;
1772#else
1773 long int arg = 0;
1774#endif
1775 unsigned char *argp = (unsigned char *) &arg;
1776 unsigned char *seedp = seed;
1777 ptrdiff_t i;
1778 for (i = 0; i < seed_size; i++)
1779 argp[i % sizeof arg] ^= seedp[i];
1770#ifdef HAVE_RANDOM 1780#ifdef HAVE_RANDOM
1771 srandom ((unsigned int)arg); 1781 srandom (arg);
1772#else 1782#else
1773# ifdef HAVE_LRAND48 1783# ifdef HAVE_LRAND48
1774 srand48 (arg); 1784 srand48 (arg);
1775# else 1785# else
1776 srand ((unsigned int)arg); 1786 srand (arg);
1777# endif 1787# endif
1778#endif 1788#endif
1779} 1789}
1780 1790
1791void
1792init_random (void)
1793{
1794 EMACS_TIME t = current_emacs_time ();
1795 uintmax_t v = getpid () ^ EMACS_SECS (t) ^ EMACS_NSECS (t);
1796 seed_random (&v, sizeof v);
1797}
1798
1781/* 1799/*
1782 * Return a nonnegative random integer out of whatever we've got. 1800 * Return a nonnegative random integer out of whatever we've got.
1783 * It contains enough bits to make a random (signed) Emacs fixnum. 1801 * It contains enough bits to make a random (signed) Emacs fixnum.