|
@ -1,4 +1,4 @@ |
|
|
/* $OpenBSD: random.c,v 1.17 2012/06/01 01:01:57 guenther Exp $ */ |
|
|
|
|
|
|
|
|
/* $OpenBSD: random.c,v 1.18 2013/03/15 19:07:53 tedu Exp $ */ |
|
|
/* |
|
|
/* |
|
|
* Copyright (c) 1983 Regents of the University of California. |
|
|
* Copyright (c) 1983 Regents of the University of California. |
|
|
* All rights reserved. |
|
|
* All rights reserved. |
|
@ -36,6 +36,8 @@ |
|
|
#include <stdlib.h> |
|
|
#include <stdlib.h> |
|
|
#include <unistd.h> |
|
|
#include <unistd.h> |
|
|
|
|
|
|
|
|
|
|
|
#include "thread_private.h" |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
|
* random.c: |
|
|
* random.c: |
|
|
* |
|
|
* |
|
@ -174,6 +176,12 @@ static int rand_type = TYPE_3; |
|
|
static int rand_deg = DEG_3; |
|
|
static int rand_deg = DEG_3; |
|
|
static int rand_sep = SEP_3; |
|
|
static int rand_sep = SEP_3; |
|
|
|
|
|
|
|
|
|
|
|
_THREAD_PRIVATE_MUTEX(random); |
|
|
|
|
|
static long random_l(void); |
|
|
|
|
|
|
|
|
|
|
|
#define LOCK() _THREAD_PRIVATE_MUTEX_LOCK(random) |
|
|
|
|
|
#define UNLOCK() _THREAD_PRIVATE_MUTEX_UNLOCK(random) |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
|
* srandom: |
|
|
* srandom: |
|
|
* |
|
|
* |
|
@ -186,8 +194,8 @@ static int rand_sep = SEP_3; |
|
|
* introduced by the L.C.R.N.G. Note that the initialization of randtbl[] |
|
|
* introduced by the L.C.R.N.G. Note that the initialization of randtbl[] |
|
|
* for default usage relies on values produced by this routine. |
|
|
* for default usage relies on values produced by this routine. |
|
|
*/ |
|
|
*/ |
|
|
void |
|
|
|
|
|
srandom(unsigned int x) |
|
|
|
|
|
|
|
|
static void |
|
|
|
|
|
srandom_l(unsigned int x) |
|
|
{ |
|
|
{ |
|
|
int i; |
|
|
int i; |
|
|
int32_t test; |
|
|
int32_t test; |
|
@ -213,10 +221,18 @@ srandom(unsigned int x) |
|
|
fptr = &state[rand_sep]; |
|
|
fptr = &state[rand_sep]; |
|
|
rptr = &state[0]; |
|
|
rptr = &state[0]; |
|
|
for (i = 0; i < 10 * rand_deg; i++) |
|
|
for (i = 0; i < 10 * rand_deg; i++) |
|
|
(void)random(); |
|
|
|
|
|
|
|
|
(void)random_l(); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
|
srandom(unsigned int x) |
|
|
|
|
|
{ |
|
|
|
|
|
LOCK(); |
|
|
|
|
|
srandom_l(x); |
|
|
|
|
|
UNLOCK(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
|
* srandomdev: |
|
|
* srandomdev: |
|
|
* |
|
|
* |
|
@ -234,6 +250,7 @@ srandomdev(void) |
|
|
int mib[2]; |
|
|
int mib[2]; |
|
|
size_t len; |
|
|
size_t len; |
|
|
|
|
|
|
|
|
|
|
|
LOCK(); |
|
|
if (rand_type == TYPE_0) |
|
|
if (rand_type == TYPE_0) |
|
|
len = sizeof(state[0]); |
|
|
len = sizeof(state[0]); |
|
|
else |
|
|
else |
|
@ -247,6 +264,7 @@ srandomdev(void) |
|
|
fptr = &state[rand_sep]; |
|
|
fptr = &state[rand_sep]; |
|
|
rptr = &state[0]; |
|
|
rptr = &state[0]; |
|
|
} |
|
|
} |
|
|
|
|
|
UNLOCK(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
@ -273,12 +291,15 @@ initstate(u_int seed, char *arg_state, size_t n) |
|
|
{ |
|
|
{ |
|
|
char *ostate = (char *)(&state[-1]); |
|
|
char *ostate = (char *)(&state[-1]); |
|
|
|
|
|
|
|
|
|
|
|
LOCK(); |
|
|
if (rand_type == TYPE_0) |
|
|
if (rand_type == TYPE_0) |
|
|
state[-1] = rand_type; |
|
|
state[-1] = rand_type; |
|
|
else |
|
|
else |
|
|
state[-1] = MAX_TYPES * (rptr - state) + rand_type; |
|
|
state[-1] = MAX_TYPES * (rptr - state) + rand_type; |
|
|
if (n < BREAK_0) |
|
|
|
|
|
|
|
|
if (n < BREAK_0) { |
|
|
|
|
|
UNLOCK(); |
|
|
return(NULL); |
|
|
return(NULL); |
|
|
|
|
|
} |
|
|
if (n < BREAK_1) { |
|
|
if (n < BREAK_1) { |
|
|
rand_type = TYPE_0; |
|
|
rand_type = TYPE_0; |
|
|
rand_deg = DEG_0; |
|
|
rand_deg = DEG_0; |
|
@ -302,11 +323,12 @@ initstate(u_int seed, char *arg_state, size_t n) |
|
|
} |
|
|
} |
|
|
state = &(((int32_t *)arg_state)[1]); /* first location */ |
|
|
state = &(((int32_t *)arg_state)[1]); /* first location */ |
|
|
end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */ |
|
|
end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */ |
|
|
srandom(seed); |
|
|
|
|
|
|
|
|
srandom_l(seed); |
|
|
if (rand_type == TYPE_0) |
|
|
if (rand_type == TYPE_0) |
|
|
state[-1] = rand_type; |
|
|
state[-1] = rand_type; |
|
|
else |
|
|
else |
|
|
state[-1] = MAX_TYPES*(rptr - state) + rand_type; |
|
|
state[-1] = MAX_TYPES*(rptr - state) + rand_type; |
|
|
|
|
|
UNLOCK(); |
|
|
return(ostate); |
|
|
return(ostate); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -333,6 +355,7 @@ setstate(char *arg_state) |
|
|
int32_t rear = new_state[0] / MAX_TYPES; |
|
|
int32_t rear = new_state[0] / MAX_TYPES; |
|
|
char *ostate = (char *)(&state[-1]); |
|
|
char *ostate = (char *)(&state[-1]); |
|
|
|
|
|
|
|
|
|
|
|
LOCK(); |
|
|
if (rand_type == TYPE_0) |
|
|
if (rand_type == TYPE_0) |
|
|
state[-1] = rand_type; |
|
|
state[-1] = rand_type; |
|
|
else |
|
|
else |
|
@ -348,6 +371,7 @@ setstate(char *arg_state) |
|
|
rand_sep = seps[type]; |
|
|
rand_sep = seps[type]; |
|
|
break; |
|
|
break; |
|
|
default: |
|
|
default: |
|
|
|
|
|
UNLOCK(); |
|
|
return(NULL); |
|
|
return(NULL); |
|
|
} |
|
|
} |
|
|
state = &new_state[1]; |
|
|
state = &new_state[1]; |
|
@ -356,6 +380,7 @@ setstate(char *arg_state) |
|
|
fptr = &state[(rear + rand_sep) % rand_deg]; |
|
|
fptr = &state[(rear + rand_sep) % rand_deg]; |
|
|
} |
|
|
} |
|
|
end_ptr = &state[rand_deg]; /* set end_ptr too */ |
|
|
end_ptr = &state[rand_deg]; /* set end_ptr too */ |
|
|
|
|
|
UNLOCK(); |
|
|
return(ostate); |
|
|
return(ostate); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -376,8 +401,8 @@ setstate(char *arg_state) |
|
|
* |
|
|
* |
|
|
* Returns a 31-bit random number. |
|
|
* Returns a 31-bit random number. |
|
|
*/ |
|
|
*/ |
|
|
long |
|
|
|
|
|
random(void) |
|
|
|
|
|
|
|
|
static long |
|
|
|
|
|
random_l(void) |
|
|
{ |
|
|
{ |
|
|
int32_t i; |
|
|
int32_t i; |
|
|
|
|
|
|
|
@ -394,3 +419,13 @@ random(void) |
|
|
} |
|
|
} |
|
|
return((long)i); |
|
|
return((long)i); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
long |
|
|
|
|
|
random(void) |
|
|
|
|
|
{ |
|
|
|
|
|
long r; |
|
|
|
|
|
LOCK(); |
|
|
|
|
|
r = random_l(); |
|
|
|
|
|
UNLOCK(); |
|
|
|
|
|
return r; |
|
|
|
|
|
} |