summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-03-14 00:26:37 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-03-14 00:26:37 -0700
commit62ec2d2ec9d427866c9dea6fc507ea1c7976fb0f (patch)
tree1a964b4a1c99a8d1c170655c2e9fb7bbc9b51e98
parent9753507cc7c47f080606ba86b280a7d6a2b212be (diff)
downloadtxr-62ec2d2ec9d427866c9dea6fc507ea1c7976fb0f.tar.gz
txr-62ec2d2ec9d427866c9dea6fc507ea1c7976fb0f.tar.bz2
txr-62ec2d2ec9d427866c9dea6fc507ea1c7976fb0f.zip
* eval.c (eval_init): Make seed argument optional in make-random-state.
* rand.c (make_random_state): Do argument defaulting on seed. Also, mix getpid() into the seed. (random_fixnum): Bugfix: do proper defaulting on optional agument, rather than relying on nil. (random): Fix 2014-02-05 regression. This was totally broken, ignoring the random state passed in and using the global random state. This function must only use the state passed in; there is no defaulting to the global random state. * txr.1: Documenting that seed is optional in make-random-state. Describing what guarantees can be expected with regard to calls made close together temporally.
-rw-r--r--ChangeLog17
-rw-r--r--eval.c2
-rw-r--r--rand.c15
-rw-r--r--txr.127
4 files changed, 52 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 4593c47d..e9dc9c2e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2014-03-14 Kaz Kylheku <kaz@kylheku.com>
+
+ * eval.c (eval_init): Make seed argument optional in make-random-state.
+
+ * rand.c (make_random_state): Do argument defaulting on seed.
+ Also, mix getpid() into the seed.
+ (random_fixnum): Bugfix: do proper defaulting on optional
+ agument, rather than relying on nil.
+ (random): Fix 2014-02-05 regression. This was totally broken,
+ ignoring the random state passed in and using the global
+ random state. This function must only use the state passed in;
+ there is no defaulting to the global random state.
+
+ * txr.1: Documenting that seed is optional in make-random-state.
+ Describing what guarantees can be expected with regard to
+ calls made close together temporally.
+
2014-03-13 Kaz Kylheku <kaz@kylheku.com>
Implementing @(if)/@(elif)/@(else) in the pattern language.
diff --git a/eval.c b/eval.c
index 8cf1f75c..a0f73610 100644
--- a/eval.c
+++ b/eval.c
@@ -3510,7 +3510,7 @@ void eval_init(void)
reg_fun(intern(lit("functionp"), user_package), func_n1(functionp));
reg_fun(intern(lit("interp-fun-p"), user_package), func_n1(interp_fun_p));
- reg_fun(intern(lit("make-random-state"), user_package), func_n1(make_random_state));
+ reg_fun(intern(lit("make-random-state"), user_package), func_n1o(make_random_state, 0));
reg_fun(intern(lit("random-state-p"), user_package), func_n1(random_state_p));
reg_fun(intern(lit("random-fixnum"), user_package), func_n1o(random_fixnum, 1));
reg_fun(intern(lit("random"), user_package), func_n2(random));
diff --git a/rand.c b/rand.c
index d9f939e3..a934667e 100644
--- a/rand.c
+++ b/rand.c
@@ -37,6 +37,9 @@
#include <time.h>
#include <signal.h>
#include "config.h"
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
#include "lib.h"
#include "signal.h"
#include "unwind.h"
@@ -110,6 +113,8 @@ val make_random_state(val seed)
r->cur = 0;
+ seed = default_bool_arg(seed);
+
if (bignump(seed)) {
int i, dig, bit;
mp_int *m = mp(seed);
@@ -139,7 +144,8 @@ val make_random_state(val seed)
val time = time_sec_usec();
r->state[0] = (rand32_t) c_num(car(time));
r->state[1] = (rand32_t) c_num(cdr(time));
- memset(r->state + 2, 0xAA, sizeof r->state - 2 * sizeof r->state[0]);
+ r->state[2] = (rand32_t) getpid();
+ memset(r->state + 3, 0xAA, sizeof r->state - 3 * sizeof r->state[0]);
} else if (random_state_p(seed)) {
struct rand_state *rseed = (struct rand_state *)
cobj_handle(seed, random_state_s);
@@ -157,16 +163,15 @@ val make_random_state(val seed)
val random_fixnum(val state)
{
- uses_or2;
- struct rand_state *r = (struct rand_state *) cobj_handle(or2(state,
- random_state),
+ struct rand_state *r = (struct rand_state *) cobj_handle(default_arg(state,
+ random_state),
random_state_s);
return num(rand32(r) & NUM_MAX);
}
val random(val state, val modulus)
{
- struct rand_state *r = (struct rand_state *) cobj_handle(random_state,
+ struct rand_state *r = (struct rand_state *) cobj_handle(state,
random_state_s);
if (bignump(modulus)) {
diff --git a/txr.1 b/txr.1
index 1f39a45c..86b30e8d 100644
--- a/txr.1
+++ b/txr.1
@@ -12546,7 +12546,7 @@ the call (make-random-state 42).
.TP
Syntax:
- (make-random-state <seed>)
+ (make-random-state [<seed>])
.TP
Description:
@@ -12554,11 +12554,32 @@ Description:
The make-random-state function creates and returns a new random state,
an object of the same kind as what is stored in the *random-state* variable.
-The seed must be an integer value.
+The seed, if specified, must be an integer value.
-Note that the sign of the value is ignored, so that negative seed
+Note that the sign of the seed is ignored, so that negative seed
values are equivalent to their additive inverses.
+If the seed is not specified, then make-random-state produces a seed based
+on some information in the process environment, such as current
+time of day. It is not guaranteed that two calls to (make-random-state nil)
+that are separated by less than some minimum increment of real time produce
+different seeds. The minimum time increment depends on the platform, but on any
+given platform, it is the platform's smallest available time increment, or a
+microsecond, whichever is longer.
+
+Of course, it is not guranteed that any two calls to make-random-state produce
+different values under any circumstances, due to possible collisions; however,
+time differences smaller than the minimum increment may predictably produce
+identical values.
+
+For instance, on a platform with a nanosecond-resolution real-time clock,
+the minimum time increment is a microsecond. Calls to make-random-state
+closer together than a microsecond may predictably produce the same seed.
+
+In a platform with a millisecond-resolution real-time clock, the minimum
+time increment is a millisecond. Calls to make-random-state less than
+a millisecond apart may predictably produce the same seed.
+
.SS Function random-state-p
.TP