From: Nathan Froyd Date: Sat, 27 Feb 2010 16:43:12 +0000 (+0000) Subject: 1.0.35.21: ANSI-fy random-state seeding changes X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=0c05012679ba995e3d70303704b8e1225d4dc5d5;p=sbcl.git 1.0.35.21: ANSI-fy random-state seeding changes Thanks to Fare for redoing his patch. --- diff --git a/NEWS b/NEWS index 19a996e..e137cd4 100644 --- a/NEWS +++ b/NEWS @@ -12,12 +12,11 @@ changes relative to sbcl-1.0.35: returns the function's declared, or derived FTYPE. * new feature: SB-POSIX now supports accessing the d_ino member of dirent structures. (Thanks to Philipp Marek and Pierre THEIRRY) - * new feature: MAKE-RANDOM-STATE has been extended to accept octet vectors, - (SIMPLE-ARRAY (UNSIGNED-BYTE 32) (*)), and UNSIGNED-BYTE arguments in - addition to the ones documented in the language specification. Also, - (MAKE-RANDOM-STATE T) will attempt to initialize the returned state - from the operating system's PRNG where possible. (Thanks to - Fare Rideau; launchpad bug lp#310116) + * new feature: The function SB-EXT:SEED-RANDOM-STATE has been added to + provide for seeding a RANDOM-STATE object with user-provided data or + from the operating system's PRNG. Also, (MAKE-RANDOM-STATE T) will + attempt to initialize the returned state from the operating system's + PRNG where possible. (Thanks to Fare Rideau; launchpad bug lp#310116) * bug fix: Fix SB-SIMPLE-STREAMS:READ-VECTOR to correctly set the FILE-POSITION of the stream being read from. (launchpad bug lp#491087) * bug fix: Fix grammer and style issues for the docstrings of diff --git a/package-data-list.lisp-expr b/package-data-list.lisp-expr index 8659ffb..156f364 100644 --- a/package-data-list.lisp-expr +++ b/package-data-list.lisp-expr @@ -756,6 +756,7 @@ like *STACK-TOP-HINT* and unsupported stuff like *TRACED-FUN-LIST*." "*ED-FUNCTIONS*" "*MODULE-PROVIDER-FUNCTIONS*" "WITH-TIMEOUT" "TIMEOUT" + "SEED-RANDOM-STATE" "TYPEXPAND-1" "TYPEXPAND" "TYPEXPAND-ALL" "DEFINED-TYPE-NAME-P" "VALID-TYPE-SPECIFIER-P" diff --git a/src/code/target-random.lisp b/src/code/target-random.lisp index 5ecbd14..ca89d4b 100644 --- a/src/code/target-random.lisp +++ b/src/code/target-random.lisp @@ -95,8 +95,26 @@ provided randomness source where available, otherwise a poor substitute based on internal time and pid) - As an SBCL extension (starting with SBCL 1.0.33), we also support receiving - as a seed an object of the following types: + See SB-EXT:SEED-RANDOM-STATE for a SBCL extension to this functionality." + (/show0 "entering MAKE-RANDOM-STATE") + (check-type state (or boolean random-state)) + (seed-random-state state)) + +(defun seed-random-state (&optional state) + #!+sb-doc + "Make a random state object. The optional STATE argument specifies a seed + for deterministic pseudo-random number generation. + + As per the Common Lisp standard for MAKE-RANDOM-STATE, + - If STATE is NIL or not supplied or is NIL, return a copy of the default + *RANDOM-STATE*. + - If STATE is a random state, return a copy of it. + - If STATE is T, return a randomly initialized state (using operating-system + provided randomness source where available, otherwise a poor substitute + based on internal time and pid) + + As a supported SBCL extension, we also support receiving as a seed an object + of the following types: - (SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*)) - UNSIGNED-BYTE While we support arguments of any size and will mix the provided bits into @@ -110,7 +128,6 @@ internal state only effectively contains about 19937 bits of information. http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html " - (/show0 "entering MAKE-RANDOM-STATE") (etypecase state ;; Easy standard cases (null @@ -122,7 +139,7 @@ ;; Standard case, less easy: try to randomly initialize a state. ((eql t) (/show0 "getting randomness from the operating system") - (make-random-state + (seed-random-state (or ;; On unices, we try to read from /dev/urandom and pass the results ;; to our (simple-array (unsigned-byte 32) (*)) processor below. @@ -165,7 +182,7 @@ (+ (aref state q) (if (< 1 r) (ash (aref state (+ q 1)) 8) 0) (if (= 3 r) (ash (aref state (+ q 2)) 16) 0))))) - (make-random-state y))) + (seed-random-state y))) ;; Also for convenience, we accept non-negative integers as seeds. ;; Small ones get passed to init-random-state, as before. ((unsigned-byte 32) @@ -179,7 +196,7 @@ for i below l for p from 0 by 32 do (setf (aref s i) (ldb (byte 32 p) state)) - finally (return (make-random-state s)))) + finally (return (seed-random-state s)))) ;; Last but not least, when provided an array of 32-bit words, we truncate ;; it to 19968 bits and mix these into an initial state. We reuse the same ;; method as the authors of the original algorithm. See diff --git a/version.lisp-expr b/version.lisp-expr index fcc7a2e..4e19447 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"1.0.35.20" +"1.0.35.21"