unsigned int make_toui (const char*, const char**);
char *make_lltoa (long long, char *);
char *make_ulltoa (unsigned long long, char *);
+void make_seed (unsigned int);
+unsigned int make_rand ();
pid_t make_pid ();
void *xmalloc (size_t);
void *xcalloc (size_t);
return buf;
}
+/* Simple random number generator, for use with shuffle.
+ This doesn't need to be truly random, just pretty random. Use our own
+ implementation rather than relying on the C runtime's rand() so we always
+ get the same results for a given seed, regardless of OS. */
+
+static unsigned int mk_state = 0;
+
+void
+make_seed(unsigned int seed)
+{
+ mk_state = seed;
+}
+
+unsigned int
+make_rand()
+{
+ /* mk_state must never be 0. */
+ if (mk_state == 0) {
+ mk_state = (unsigned int)(time (NULL) ^ make_pid ()) + 1;
+ }
+
+ /* A simple xorshift RNG. */
+ mk_state ^= mk_state << 13;
+ mk_state ^= mk_state >> 17;
+ mk_state ^= mk_state << 5;
+
+ return mk_state;
+}
+
/* Compare strings *S1 and *S2.
Return negative if the first is less, positive if it is greater,
zero if they are equal. */
}
else
{
- if (strcasecmp (cmdarg, "random") == 0)
- config.seed = (unsigned int) (time (NULL) ^ make_pid ());
- else
+ if (strcasecmp (cmdarg, "random") != 0)
{
/* Assume explicit seed. */
const char *err;
void *t;
/* Pick random element and swap. */
- unsigned int j = rand () % len;
+ unsigned int j = make_rand () % len;
if (i == j)
continue;
/* Set specific seed at the top level of recursion. */
if (config.mode == sm_random)
- srand (config.seed);
+ make_seed (config.seed);
shuffle_deps (deps);