diff options
author | "Steven J. Hill" <sjhill@realitydiluted.com> | 2005-12-01 03:08:57 +0000 |
---|---|---|
committer | "Steven J. Hill" <sjhill@realitydiluted.com> | 2005-12-01 03:08:57 +0000 |
commit | 4d17e7e7c5dec2d055cf96b9c4a5fa457fdef772 (patch) | |
tree | 4e10e6338d55fe67bfcbc5a971a1dab14481f94f /libc/stdlib/random_r.c | |
parent | 0600b878cde4e363436e51833393463e715e2f04 (diff) | |
download | uClibc-alpine-4d17e7e7c5dec2d055cf96b9c4a5fa457fdef772.tar.bz2 uClibc-alpine-4d17e7e7c5dec2d055cf96b9c4a5fa457fdef772.tar.xz |
Mini-merge from trunk. Not as fun as a Mini Cooper, but oh well.
Diffstat (limited to 'libc/stdlib/random_r.c')
-rw-r--r-- | libc/stdlib/random_r.c | 129 |
1 files changed, 64 insertions, 65 deletions
diff --git a/libc/stdlib/random_r.c b/libc/stdlib/random_r.c index fce3a98ab..9e203f0d5 100644 --- a/libc/stdlib/random_r.c +++ b/libc/stdlib/random_r.c @@ -123,6 +123,66 @@ static const struct random_poly_info random_poly_info = +/* If we are using the trivial TYPE_0 R.N.G., just do the old linear + congruential bit. Otherwise, we do our fancy trinomial stuff, which is the + same in all the other cases due to all the global variables that have been + set up. The basic operation is to add the number at the rear pointer into + the one at the front pointer. Then both pointers are advanced to the next + location cyclically in the table. The value returned is the sum generated, + reduced to 31 bits by throwing away the "least random" low bit. + Note: The code takes advantage of the fact that both the front and + rear pointers can't wrap on the same call by not testing the rear + pointer if the front one has wrapped. Returns a 31-bit random number. */ + +int attribute_hidden __random_r(struct random_data *buf, int32_t *result) +{ + int32_t *state; + + if (buf == NULL || result == NULL) + goto fail; + + state = buf->state; + + if (buf->rand_type == TYPE_0) + { + int32_t val = state[0]; + val = ((state[0] * 1103515245) + 12345) & 0x7fffffff; + state[0] = val; + *result = val; + } + else + { + int32_t *fptr = buf->fptr; + int32_t *rptr = buf->rptr; + int32_t *end_ptr = buf->end_ptr; + int32_t val; + + val = *fptr += *rptr; + /* Chucking least random bit. */ + *result = (val >> 1) & 0x7fffffff; + ++fptr; + if (fptr >= end_ptr) + { + fptr = state; + ++rptr; + } + else + { + ++rptr; + if (rptr >= end_ptr) + rptr = state; + } + buf->fptr = fptr; + buf->rptr = rptr; + } + return 0; + +fail: + __set_errno (EINVAL); + return -1; +} +strong_alias(__random_r,random_r) + /* Initialize the random number generator based on the given seed. If the type is the trivial no-state-information type, just remember the seed. Otherwise, initializes state[] based on the given "seed" via a linear @@ -131,7 +191,7 @@ static const struct random_poly_info random_poly_info = information a given number of times to get rid of any initial dependencies introduced by the L.C.R.N.G. Note that the initialization of randtbl[] for default usage relies on values produced by this routine. */ -int srandom_r (unsigned int seed, struct random_data *buf) +int attribute_hidden __srandom_r (unsigned int seed, struct random_data *buf) { int type; int32_t *state; @@ -176,7 +236,7 @@ int srandom_r (unsigned int seed, struct random_data *buf) while (--kc >= 0) { int32_t discard; - (void) random_r (buf, &discard); + (void) __random_r (buf, &discard); } done: @@ -185,6 +245,7 @@ done: fail: return -1; } +strong_alias(__srandom_r,srandom_r) /* Initialize the state information in the given array of N bytes for future random number generation. Based on the number of bytes we @@ -237,7 +298,7 @@ int initstate_r (seed, arg_state, n, buf) buf->state = state; - srandom_r (seed, buf); + __srandom_r (seed, buf); state[-1] = TYPE_0; if (type != TYPE_0) @@ -301,65 +362,3 @@ fail: __set_errno (EINVAL); return -1; } - -/* If we are using the trivial TYPE_0 R.N.G., just do the old linear - congruential bit. Otherwise, we do our fancy trinomial stuff, which is the - same in all the other cases due to all the global variables that have been - set up. The basic operation is to add the number at the rear pointer into - the one at the front pointer. Then both pointers are advanced to the next - location cyclically in the table. The value returned is the sum generated, - reduced to 31 bits by throwing away the "least random" low bit. - Note: The code takes advantage of the fact that both the front and - rear pointers can't wrap on the same call by not testing the rear - pointer if the front one has wrapped. Returns a 31-bit random number. */ - -int random_r (buf, result) - struct random_data *buf; - int32_t *result; -{ - int32_t *state; - - if (buf == NULL || result == NULL) - goto fail; - - state = buf->state; - - if (buf->rand_type == TYPE_0) - { - int32_t val = state[0]; - val = ((state[0] * 1103515245) + 12345) & 0x7fffffff; - state[0] = val; - *result = val; - } - else - { - int32_t *fptr = buf->fptr; - int32_t *rptr = buf->rptr; - int32_t *end_ptr = buf->end_ptr; - int32_t val; - - val = *fptr += *rptr; - /* Chucking least random bit. */ - *result = (val >> 1) & 0x7fffffff; - ++fptr; - if (fptr >= end_ptr) - { - fptr = state; - ++rptr; - } - else - { - ++rptr; - if (rptr >= end_ptr) - rptr = state; - } - buf->fptr = fptr; - buf->rptr = rptr; - } - return 0; - -fail: - __set_errno (EINVAL); - return -1; -} - |