summaryrefslogtreecommitdiffstats
path: root/libc/stdlib/random_r.c
diff options
context:
space:
mode:
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
commit4d17e7e7c5dec2d055cf96b9c4a5fa457fdef772 (patch)
tree4e10e6338d55fe67bfcbc5a971a1dab14481f94f /libc/stdlib/random_r.c
parent0600b878cde4e363436e51833393463e715e2f04 (diff)
downloaduClibc-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.c129
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;
-}
-