Back to index

glibc  2.9
Classes | Defines | Functions | Variables
random_r.c File Reference
#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>

Go to the source code of this file.

Classes

struct  random_poly_info

Defines

#define TYPE_0   0
#define BREAK_0   8
#define DEG_0   0
#define SEP_0   0
#define TYPE_1   1
#define BREAK_1   32
#define DEG_1   7
#define SEP_1   3
#define TYPE_2   2
#define BREAK_2   64
#define DEG_2   15
#define SEP_2   1
#define TYPE_3   3
#define BREAK_3   128
#define DEG_3   31
#define SEP_3   3
#define TYPE_4   4
#define BREAK_4   256
#define DEG_4   63
#define SEP_4   1
#define MAX_TYPES   5 /* Max number of types above. */

Functions

int __srandom_r (unsigned int seed, struct random_data *buf)
 weak_alias (__srandom_r, srandom_r)
 weak_alias (__initstate_r, initstate_r)
 weak_alias (__setstate_r, setstate_r)

Variables

static struct random_poly_info

Class Documentation

struct random_poly_info

Definition at line 138 of file random_r.c.

Class Members
int degrees
int seps

Define Documentation

#define BREAK_0   8

Definition at line 104 of file random_r.c.

#define BREAK_1   32

Definition at line 110 of file random_r.c.

#define BREAK_2   64

Definition at line 116 of file random_r.c.

#define BREAK_3   128

Definition at line 122 of file random_r.c.

#define BREAK_4   256

Definition at line 128 of file random_r.c.

#define DEG_0   0

Definition at line 105 of file random_r.c.

#define DEG_1   7

Definition at line 111 of file random_r.c.

#define DEG_2   15

Definition at line 117 of file random_r.c.

#define DEG_3   31

Definition at line 123 of file random_r.c.

#define DEG_4   63

Definition at line 129 of file random_r.c.

#define MAX_TYPES   5 /* Max number of types above. */

Definition at line 136 of file random_r.c.

#define SEP_0   0

Definition at line 106 of file random_r.c.

#define SEP_1   3

Definition at line 112 of file random_r.c.

#define SEP_2   1

Definition at line 118 of file random_r.c.

#define SEP_3   3

Definition at line 124 of file random_r.c.

#define SEP_4   1

Definition at line 130 of file random_r.c.

#define TYPE_0   0

Definition at line 103 of file random_r.c.

#define TYPE_1   1

Definition at line 109 of file random_r.c.

#define TYPE_2   2

Definition at line 115 of file random_r.c.

#define TYPE_3   3

Definition at line 121 of file random_r.c.

#define TYPE_4   4

Definition at line 127 of file random_r.c.


Function Documentation

int __srandom_r ( unsigned int  seed,
struct random_data buf 
)

Definition at line 162 of file random_r.c.

{
  int type;
  int32_t *state;
  long int i;
  long int word;
  int32_t *dst;
  int kc;

  if (buf == NULL)
    goto fail;
  type = buf->rand_type;
  if ((unsigned int) type >= MAX_TYPES)
    goto fail;

  state = buf->state;
  /* We must make sure the seed is not 0.  Take arbitrarily 1 in this case.  */
  if (seed == 0)
    seed = 1;
  state[0] = seed;
  if (type == TYPE_0)
    goto done;

  dst = state;
  word = seed;
  kc = buf->rand_deg;
  for (i = 1; i < kc; ++i)
    {
      /* This does:
          state[i] = (16807 * state[i - 1]) % 2147483647;
        but avoids overflowing 31 bits.  */
      long int hi = word / 127773;
      long int lo = word % 127773;
      word = 16807 * lo - 2836 * hi;
      if (word < 0)
       word += 2147483647;
      *++dst = word;
    }

  buf->fptr = &state[buf->rand_sep];
  buf->rptr = &state[0];
  kc *= 10;
  while (--kc >= 0)
    {
      int32_t discard;
      (void) __random_r (buf, &discard);
    }

 done:
  return 0;

 fail:
  return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

weak_alias ( __srandom_r  ,
srandom_r   
)

Definition at line 219 of file random_r.c.

{
  if (buf == NULL)
    goto fail;

  int32_t *old_state = buf->state;
  if (old_state != NULL)
    {
      int old_type = buf->rand_type;
      if (old_type == TYPE_0)
       old_state[-1] = TYPE_0;
      else
       old_state[-1] = (MAX_TYPES * (buf->rptr - old_state)) + old_type;
    }

  int type;
  if (n >= BREAK_3)
    type = n < BREAK_4 ? TYPE_3 : TYPE_4;
  else if (n < BREAK_1)
    {
      if (n < BREAK_0)
       {
         __set_errno (EINVAL);
         goto fail;
       }
      type = TYPE_0;
    }
  else
    type = n < BREAK_2 ? TYPE_1 : TYPE_2;

  int degree = random_poly_info.degrees[type];
  int separation = random_poly_info.seps[type];

  buf->rand_type = type;
  buf->rand_sep = separation;
  buf->rand_deg = degree;
  int32_t *state = &((int32_t *) arg_state)[1];  /* First location.  */
  /* Must set END_PTR before srandom.  */
  buf->end_ptr = &state[degree];

  buf->state = state;

  __srandom_r (seed, buf);

  state[-1] = TYPE_0;
  if (type != TYPE_0)
    state[-1] = (buf->rptr - state) * MAX_TYPES + type;

  return 0;

 fail:
  __set_errno (EINVAL);
  return -1;
}

Here is the call graph for this function:

weak_alias ( __initstate_r  ,
initstate_r   
)

Definition at line 292 of file random_r.c.

{
  int32_t *new_state = 1 + (int32_t *) arg_state;
  int type;
  int old_type;
  int32_t *old_state;
  int degree;
  int separation;

  if (arg_state == NULL || buf == NULL)
    goto fail;

  old_type = buf->rand_type;
  old_state = buf->state;
  if (old_type == TYPE_0)
    old_state[-1] = TYPE_0;
  else
    old_state[-1] = (MAX_TYPES * (buf->rptr - old_state)) + old_type;

  type = new_state[-1] % MAX_TYPES;
  if (type < TYPE_0 || type > TYPE_4)
    goto fail;

  buf->rand_deg = degree = random_poly_info.degrees[type];
  buf->rand_sep = separation = random_poly_info.seps[type];
  buf->rand_type = type;

  if (type != TYPE_0)
    {
      int rear = new_state[-1] / MAX_TYPES;
      buf->rptr = &new_state[rear];
      buf->fptr = &new_state[(rear + separation) % degree];
    }
  buf->state = new_state;
  /* Set end_ptr too.  */
  buf->end_ptr = &new_state[degree];

  return 0;

 fail:
  __set_errno (EINVAL);
  return -1;
}

Here is the call graph for this function:

weak_alias ( __setstate_r  ,
setstate_r   
)

Definition at line 349 of file random_r.c.

{
  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;
}

Here is the call graph for this function:


Variable Documentation

struct random_poly_info [static]
Initial value:

Definition at line 144 of file random_r.c.