diff options
| author | Paul Eggert | 2012-08-31 18:04:26 -0700 |
|---|---|---|
| committer | Paul Eggert | 2012-08-31 18:04:26 -0700 |
| commit | 0e23ef9ddeefadcba94824c09e412c961de283e7 (patch) | |
| tree | 8bd5c2973ce8d2f96b727b2eed8b4603a577a141 /src | |
| parent | 5bf647499a5f6d08ac8aa4809ebce22acf1330b3 (diff) | |
| download | emacs-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/ChangeLog | 9 | ||||
| -rw-r--r-- | src/emacs.c | 1 | ||||
| -rw-r--r-- | src/fns.c | 28 | ||||
| -rw-r--r-- | src/lisp.h | 3 | ||||
| -rw-r--r-- | src/sysdep.c | 24 |
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 @@ | |||
| 1 | 2012-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 | |||
| 1 | 2012-08-31 Dmitry Antipov <dmantipov@yandex.ru> | 10 | 2012-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); |
| @@ -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); | |||
| 3405 | extern void setup_pty (int); | 3405 | extern void setup_pty (int); |
| 3406 | extern int set_window_size (int, int, int); | 3406 | extern int set_window_size (int, int, int); |
| 3407 | extern EMACS_INT get_random (void); | 3407 | extern EMACS_INT get_random (void); |
| 3408 | extern void seed_random (long); | 3408 | extern void seed_random (void *, ptrdiff_t); |
| 3409 | extern void init_random (void); | ||
| 3409 | extern int emacs_open (const char *, int, int); | 3410 | extern int emacs_open (const char *, int, int); |
| 3410 | extern int emacs_close (int); | 3411 | extern int emacs_close (int); |
| 3411 | extern ptrdiff_t emacs_read (int, char *, ptrdiff_t); | 3412 | extern 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 | ||
| 1767 | void | 1767 | void |
| 1768 | seed_random (long int arg) | 1768 | seed_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 | ||
| 1791 | void | ||
| 1792 | init_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. |