summary refs log tree commit diff
path: root/stdlib/random.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1995-09-17 20:23:15 +0000
committerRoland McGrath <roland@gnu.org>1995-09-17 20:23:15 +0000
commit60478656fad8d8a487e9bc52d025f69767c3262b (patch)
tree0ae0836023f1c2f80064e7611f91d19c482208d9 /stdlib/random.c
parent9fd18b6c1b397e1af82a0b544f10f946c73864b6 (diff)
downloadglibc-60478656fad8d8a487e9bc52d025f69767c3262b.tar.gz
glibc-60478656fad8d8a487e9bc52d025f69767c3262b.tar.xz
glibc-60478656fad8d8a487e9bc52d025f69767c3262b.zip
Sat Sep 16 17:47:19 1995 Ulrich Drepper <drepper@ipd.info.uni-karlsruhe.de>
	* elf/elf.h (AT_GID): Fix typo: Read -> Real.

	* misc/efgvt_r.c: New file.  Reentrant version of [efg]cvt functions.
	* misc/efgcvt.c: Rewrite to use reentrant functions.
	* misc/hsearch_r.c: New file.  Reentrant version of functions from
	hsearch family.
	* misc/hsearch.c, misc/tsearch.c: New files.
	* misc/Makefile (routines): Add efgcvt_r, hsearch_r, hsearch, tsearch.

	* posix/unistd.h (ttyname_r): Add prototype for new function.

	* stdlib/drand48_r.c, stdlib/erand48_r.c, stdlib/jrand48_r.c,
	stdlib/lrand48_r.c, stdlib/mrand48_r.c, stdlib/nrand48_r.c,
	stdlib/seed48_r.c, stdlib/srand48_r.c, stdlib/lcong48_r.c,
	stdlib/drand48-iter.c: New files implementing reentrant versions
	of functions from drand48 family.
	* stdlib/seed48.c, stdlib/drand48.c, stdlib/erand48.c,
	stdlib/jrand48.c, stdlib/lrand48.c, stdlib/mrand48.c,
	stdlib/nrand48.c, stdlib/srand48.c, stdlib/lcong48.c:
	Rewrite to use reentrant versions.
	* stdlib/a64l.c, stdlib/l64a.c: New files.  Implement a64l()
	and l64a() functions from SysV library.
	* stdlib/Makefile (routines): Add drand48_r, erand48_r, lrand48_r,
	nrand48_r, mrand48_r, jrand48_r, srand48_r, seed48_r, lcong48_r,
	drand48-iter, a64l, l64a.
	* stdlib/stdlib.h: Declare them.

	* stdlib/random_r.c: New file.  Reentrant version of functions
	from random family.
	* stdlib/stdlib.h: Declare them.
	* stdlib/random.c: Rewrite to use reentrant functions.

	* string/strerror_r.c: New file.  Reentrant version.
	* string/strerror.c: Change for new _strerror_internal form.
	* string/Makefile (routines): Add strerror_r.

	* sysdeps/generic/dl-sysdep.c (_dl_sysdep_start): Set default
	value of user_entry to `_start'.
	Close AT_ENTRY case with `break'.

	* sysdeps/generic/strstr.c: New and much faster implementation
	by Stephen R. van den Berg.

	* sysdeps/generic/_strerror.c: _strerror_internal now takes
	three argument and has and explicit buffer length.
	* sysdeps/mach/_strerror.c: Change for new interface with three
	arguments.
	* stdio/perror.c, stdio/vfprintf.c: Callers changed.
	
	* sysdeps/mach/hurd/ttyname_r.c: New file.  Reentrant version.
	* sysdeps/posix/ttyname_r.c: New file.  Reentrant version.
	* sysdeps/stub/ttyname_r: New file.  Define as dummy function.

	* sysdeps/posix/utimes.c: Include <utime.h> for prototype.
	(utimes): First parameter to utime must be file, not path.

	* sysdeps/posix/sysconf.c (__sysconf): Test for CLK_TCK in case
	_SC_CLK_TCK and return it when available.
	Test for STREAM_MAX in case _SC_STREAM_MAX and return it when
	available.
	Add case for _SC_2_LOCALEDEF which is now available.

	* posix/sys/types.h [__USE_SVID] (key_t): New type.
	* sysvipc/Makefile, sysvipc/ftok.c, sysvipc/sys/ipc.h,
	sysvipc/sys/msg.h, sysvipc/sys/sem.h, sysvipc/sys/shm.h,
	sysdeps/stub/sys/msq_buf.h, sysdeps/stub/sys/sem_buf.h,
	sysdeps/stub/sys/shm_buf.h, sysdeps/stub/sys/ipc_buf.h,
	sysdeps/stub/semctl.c, sysdeps/stub/semget.c, sysdeps/stub/semop.c,
	sysdeps/stub/shmat.c, sysdeps/stub/shmctl.c, sysdeps/stub/shmdt.c,
	sysdeps/stub/shmget.c, sysdeps/stub/msgctl.c, sysdeps/stub/msgget.c,
	sysdeps/stub/msgrcv.c, sysdeps/stub/msgsnd.c: New files.
	Add implementation of System V IPC.
Diffstat (limited to 'stdlib/random.c')
-rw-r--r--stdlib/random.c187
1 files changed, 36 insertions, 151 deletions
diff --git a/stdlib/random.c b/stdlib/random.c
index 473a5b13d3..c3f8eaa0a3 100644
--- a/stdlib/random.c
+++ b/stdlib/random.c
@@ -19,10 +19,9 @@
  * This is derived from the Berkeley source:
  *	@(#)random.c	5.5 (Berkeley) 7/6/88
  * It was reworked for the GNU C Library by Roland McGrath.
+ * Rewritten to use reentrent functions by Ulrich Drepper, 1995.
  */
 
-#include <ansidecl.h>
-#include <errno.h>
 #include <limits.h>
 #include <stddef.h>
 #include <stdlib.h>
@@ -105,10 +104,6 @@
 
 #define	MAX_TYPES	5	/* Max number of types above.  */
 
-static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
-static int seps[MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
-
-
 
 /* Initially, everything is set up as if from:
 	initstate(1, randtbl, 128);
@@ -132,6 +127,9 @@ static long int randtbl[DEG_3 + 1] =
     -205601318, 
   };
 
+
+static struct random_data unsafe_state =
+  {
 /* FPTR and RPTR are two pointers into the state info, a front and a rear
    pointer.  These two pointers are always rand_sep places aparts, as they
    cycle through the state information.  (Yes, this does mean we could get
@@ -142,10 +140,8 @@ static long int randtbl[DEG_3 + 1] =
    in the initialization of randtbl) because the state table pointer is set
    to point to randtbl[1] (as explained below).)  */
 
-static long int *fptr = &randtbl[SEP_3 + 1];
-static long int *rptr = &randtbl[1];
-
-
+    fptr : &randtbl[SEP_3 + 1],
+    rptr : &randtbl[1],
 
 /* The following things are the pointer to the state information table,
    the type of the current generator, the degree of the current polynomial
@@ -157,13 +153,14 @@ static long int *rptr = &randtbl[1];
    indexing every time to find the address of the last element to see if
    the front and rear pointers have wrapped.  */
 
-static long int *state = &randtbl[1];
+    state : &randtbl[1],
 
-static int rand_type = TYPE_3;
-static int rand_deg = DEG_3;
-static int rand_sep = SEP_3;
+    rand_type : TYPE_3,
+    rand_deg : DEG_3,
+    rand_sep : SEP_3,
 
-static long int *end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])];
+    end_ptr : &randtbl[sizeof (randtbl) / sizeof (randtbl[0])]
+};
 
 /* Initialize the random number generator based on the given seed.  If the
    type is the trivial no-state-information type, just remember the seed.
@@ -174,27 +171,10 @@ static long int *end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])];
    introduced by the L.C.R.N.G.  Note that the initialization of randtbl[]
    for default usage relies on values produced by this routine.  */
 void
-DEFUN(__srandom, (x), unsigned int x)
+__srandom (x)
+     unsigned int x;
 {
-  state[0] = x;
-  if (rand_type != TYPE_0)
-    {
-      register long int i;
-      for (i = 1; i < rand_deg; ++i)
-	{
-	  /* This does:
-	       state[i] = (16807 * state[i - 1]) % 2147483647;
-	     but avoids overflowing 31 bits.  */
-	  long int hi = state[i - 1] / 127773;
-	  long int lo = state[i - 1] % 127773;
-	  long int test = 16807 * lo - 2836 * hi;
-	  state[i] = test + (test < 0 ? 2147483647 : 0);
-	}
-      fptr = &state[rand_sep];
-      rptr = &state[0];
-      for (i = 0; i < 10 * rand_deg; ++i)
-	(void) __random ();
-    }
+  (void) __srandom_r (x, &unsafe_state);
 }
 
 weak_alias (__srandom, srandom)
@@ -211,60 +191,15 @@ weak_alias (__srandom, srand)
    Note: The first thing we do is save the current state, if any, just like
    setstate so that it doesn't matter when initstate is called.
    Returns a pointer to the old state.  */
-PTR
-DEFUN(__initstate, (seed, arg_state, n),
-      unsigned int seed AND PTR arg_state AND size_t n)
+void *
+__initstate (seed, arg_state, n)
+     unsigned int seed;
+     void *arg_state;
+     size_t n;
 {
-  PTR ostate = (PTR) &state[-1];
-
-  if (rand_type == TYPE_0)
-    state[-1] = rand_type;
-  else
-    state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
-  if (n < BREAK_1)
-    {
-      if (n < BREAK_0)
-	{
-	  errno = EINVAL;
-	  return NULL;
-	}
-      rand_type = TYPE_0;
-      rand_deg = DEG_0;
-      rand_sep = SEP_0;
-    }
-  else if (n < BREAK_2)
-    {
-      rand_type = TYPE_1;
-      rand_deg = DEG_1;
-      rand_sep = SEP_1;
-    }
-  else if (n < BREAK_3)
-    {
-      rand_type = TYPE_2;
-      rand_deg = DEG_2;
-      rand_sep = SEP_2;
-    }
-  else if (n < BREAK_4)
-    {
-      rand_type = TYPE_3;
-      rand_deg = DEG_3;
-      rand_sep = SEP_3;
-    }
-  else
-    {
-      rand_type = TYPE_4;
-      rand_deg = DEG_4;
-      rand_sep = SEP_4;
-    }
-
-  state = &((long int *) arg_state)[1];	/* First location.  */
-  /* Must set END_PTR before srandom.  */
-  end_ptr = &state[rand_deg];
-  __srandom(seed);
-  if (rand_type == TYPE_0)
-    state[-1] = rand_type;
-  else
-    state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
+  void *ostate = (void *) &unsafe_state.state[-1];
+
+  __initstate_r (seed, arg_state, n, &unsafe_state);
 
   return ostate;
 }
@@ -279,44 +214,14 @@ weak_alias (__initstate, initstate)
    to the order in which things are done, it is OK to call setstate with the
    same state as the current state
    Returns a pointer to the old state information.  */
-PTR
-DEFUN(__setstate, (arg_state), PTR arg_state)
+void *
+__setstate (arg_state)
+     void *arg_state;
 {
-  register long int *new_state = (long int *) arg_state;
-  register int type = new_state[0] % MAX_TYPES;
-  register int rear = new_state[0] / MAX_TYPES;
-  PTR ostate = (PTR) &state[-1];
-
-  if (rand_type == TYPE_0)
-    state[-1] = rand_type;
-  else
-    state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
-
-  switch (type)
-    {
-    case TYPE_0:
-    case TYPE_1:
-    case TYPE_2:
-    case TYPE_3:
-    case TYPE_4:
-      rand_type = type;
-      rand_deg = degrees[type];
-      rand_sep = seps[type];
-      break;
-    default:
-      /* State info munged.  */
-      errno = EINVAL;
-      return NULL;
-    }
-
-  state = &new_state[1];
-  if (rand_type != TYPE_0)
-    {
-      rptr = &state[rear];
-      fptr = &state[(rear + rand_sep) % rand_deg];
-    }
-  /* Set end_ptr too.  */
-  end_ptr = &state[rand_deg];
+  void *ostate = (void *) &unsafe_state.state[-1];
+
+  if (__setstate_r (arg_state, &unsafe_state) < 0)
+    return NULL;
 
   return ostate;
 }
@@ -335,33 +240,13 @@ weak_alias (__setstate, setstate)
    pointer if the front one has wrapped.  Returns a 31-bit random number.  */
 
 long int
-DEFUN_VOID(__random)
+__random ()
 {
-  if (rand_type == TYPE_0)
-    {
-      state[0] = ((state[0] * 1103515245) + 12345) & LONG_MAX;
-      return state[0];
-    }
-  else
-    {
-      long int i;
-      *fptr += *rptr;
-      /* Chucking least random bit.  */
-      i = (*fptr >> 1) & LONG_MAX;
-      ++fptr;
-      if (fptr >= end_ptr)
-	{
-	  fptr = state;
-	  ++rptr;
-	}
-      else
-	{
-	  ++rptr;
-	  if (rptr >= end_ptr)
-	    rptr = state;
-	}
-      return i;
-    }
+  long int retval;
+
+  (void) __random_r (&unsafe_state, &retval);
+
+  return retval;
 }
 
 weak_alias (__random, random)