xref: /netbsd-src/common/lib/libc/stdlib/random.c (revision 1cb7819f041295655a920be44fda6df07e7f28fb)
1*1cb7819fSandvar /*	$NetBSD: random.c,v 1.7 2021/12/12 22:20:52 andvar Exp $	*/
237c9f0a6Schristos 
337c9f0a6Schristos /*
437c9f0a6Schristos  * Copyright (c) 1983, 1993
537c9f0a6Schristos  *	The Regents of the University of California.  All rights reserved.
637c9f0a6Schristos  *
737c9f0a6Schristos  * Redistribution and use in source and binary forms, with or without
837c9f0a6Schristos  * modification, are permitted provided that the following conditions
937c9f0a6Schristos  * are met:
1037c9f0a6Schristos  * 1. Redistributions of source code must retain the above copyright
1137c9f0a6Schristos  *    notice, this list of conditions and the following disclaimer.
1237c9f0a6Schristos  * 2. Redistributions in binary form must reproduce the above copyright
1337c9f0a6Schristos  *    notice, this list of conditions and the following disclaimer in the
1437c9f0a6Schristos  *    documentation and/or other materials provided with the distribution.
1537c9f0a6Schristos  * 3. Neither the name of the University nor the names of its contributors
1637c9f0a6Schristos  *    may be used to endorse or promote products derived from this software
1737c9f0a6Schristos  *    without specific prior written permission.
1837c9f0a6Schristos  *
1937c9f0a6Schristos  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2037c9f0a6Schristos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2137c9f0a6Schristos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2237c9f0a6Schristos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2337c9f0a6Schristos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2437c9f0a6Schristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2537c9f0a6Schristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2637c9f0a6Schristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2737c9f0a6Schristos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2837c9f0a6Schristos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2937c9f0a6Schristos  * SUCH DAMAGE.
3037c9f0a6Schristos  */
3137c9f0a6Schristos 
3293412868Schristos #if !defined(_KERNEL) && !defined(_STANDALONE)
3337c9f0a6Schristos #include <sys/cdefs.h>
3437c9f0a6Schristos #if defined(LIBC_SCCS) && !defined(lint)
3537c9f0a6Schristos #if 0
3637c9f0a6Schristos static char sccsid[] = "@(#)random.c	8.2 (Berkeley) 5/19/95";
3737c9f0a6Schristos #else
38*1cb7819fSandvar __RCSID("$NetBSD: random.c,v 1.7 2021/12/12 22:20:52 andvar Exp $");
3937c9f0a6Schristos #endif
4037c9f0a6Schristos #endif /* LIBC_SCCS and not lint */
4137c9f0a6Schristos 
4237c9f0a6Schristos #include "namespace.h"
4337c9f0a6Schristos 
4437c9f0a6Schristos #include <assert.h>
4537c9f0a6Schristos #include <errno.h>
4637c9f0a6Schristos #include <stdlib.h>
4737c9f0a6Schristos #include "reentrant.h"
4837c9f0a6Schristos 
4937c9f0a6Schristos #ifdef __weak_alias
5037c9f0a6Schristos __weak_alias(initstate,_initstate)
5137c9f0a6Schristos __weak_alias(random,_random)
5237c9f0a6Schristos __weak_alias(setstate,_setstate)
5337c9f0a6Schristos __weak_alias(srandom,_srandom)
5437c9f0a6Schristos #endif
5537c9f0a6Schristos 
5637c9f0a6Schristos 
5737c9f0a6Schristos #ifdef _REENTRANT
5837c9f0a6Schristos static mutex_t random_mutex = MUTEX_INITIALIZER;
5937c9f0a6Schristos #endif
6093412868Schristos #else
6193412868Schristos #include <lib/libkern/libkern.h>
6293412868Schristos #define mutex_lock(a)	(void)0
6393412868Schristos #define mutex_unlock(a) (void)0
6493412868Schristos #endif
6593412868Schristos 
6670b3b52aSchristos #ifndef SMALL_RANDOM
6793412868Schristos static void srandom_unlocked(unsigned int);
6893412868Schristos static long random_unlocked(void);
6937c9f0a6Schristos 
7037c9f0a6Schristos #define USE_BETTER_RANDOM
7137c9f0a6Schristos 
7237c9f0a6Schristos /*
7337c9f0a6Schristos  * random.c:
7437c9f0a6Schristos  *
7537c9f0a6Schristos  * An improved random number generation package.  In addition to the standard
7637c9f0a6Schristos  * rand()/srand() like interface, this package also has a special state info
7737c9f0a6Schristos  * interface.  The initstate() routine is called with a seed, an array of
7837c9f0a6Schristos  * bytes, and a count of how many bytes are being passed in; this array is
7937c9f0a6Schristos  * then initialized to contain information for random number generation with
8037c9f0a6Schristos  * that much state information.  Good sizes for the amount of state
8137c9f0a6Schristos  * information are 32, 64, 128, and 256 bytes.  The state can be switched by
82*1cb7819fSandvar  * calling the setstate() routine with the same array as was initialized
8337c9f0a6Schristos  * with initstate().  By default, the package runs with 128 bytes of state
8437c9f0a6Schristos  * information and generates far better random numbers than a linear
8537c9f0a6Schristos  * congruential generator.  If the amount of state information is less than
8637c9f0a6Schristos  * 32 bytes, a simple linear congruential R.N.G. is used.
8737c9f0a6Schristos  *
8837c9f0a6Schristos  * Internally, the state information is treated as an array of ints; the
8937c9f0a6Schristos  * zeroeth element of the array is the type of R.N.G. being used (small
9037c9f0a6Schristos  * integer); the remainder of the array is the state information for the
9137c9f0a6Schristos  * R.N.G.  Thus, 32 bytes of state information will give 7 ints worth of
9237c9f0a6Schristos  * state information, which will allow a degree seven polynomial.  (Note:
9337c9f0a6Schristos  * the zeroeth word of state information also has some other information
9437c9f0a6Schristos  * stored in it -- see setstate() for details).
9537c9f0a6Schristos  *
9637c9f0a6Schristos  * The random number generation technique is a linear feedback shift register
9737c9f0a6Schristos  * approach, employing trinomials (since there are fewer terms to sum up that
9837c9f0a6Schristos  * way).  In this approach, the least significant bit of all the numbers in
9937c9f0a6Schristos  * the state table will act as a linear feedback shift register, and will
10037c9f0a6Schristos  * have period 2^deg - 1 (where deg is the degree of the polynomial being
10137c9f0a6Schristos  * used, assuming that the polynomial is irreducible and primitive).  The
10237c9f0a6Schristos  * higher order bits will have longer periods, since their values are also
10337c9f0a6Schristos  * influenced by pseudo-random carries out of the lower bits.  The total
10437c9f0a6Schristos  * period of the generator is approximately deg*(2**deg - 1); thus doubling
10537c9f0a6Schristos  * the amount of state information has a vast influence on the period of the
10637c9f0a6Schristos  * generator.  Note: the deg*(2**deg - 1) is an approximation only good for
10737c9f0a6Schristos  * large deg, when the period of the shift register is the dominant factor.
10837c9f0a6Schristos  * With deg equal to seven, the period is actually much longer than the
10937c9f0a6Schristos  * 7*(2**7 - 1) predicted by this formula.
11037c9f0a6Schristos  *
11137c9f0a6Schristos  * Modified 28 December 1994 by Jacob S. Rosenberg.
11237c9f0a6Schristos  * The following changes have been made:
11337c9f0a6Schristos  * All references to the type u_int have been changed to unsigned long.
11437c9f0a6Schristos  * All references to type int have been changed to type long.  Other
11537c9f0a6Schristos  * cleanups have been made as well.  A warning for both initstate and
11637c9f0a6Schristos  * setstate has been inserted to the effect that on Sparc platforms
11737c9f0a6Schristos  * the 'arg_state' variable must be forced to begin on word boundaries.
11837c9f0a6Schristos  * This can be easily done by casting a long integer array to char *.
11937c9f0a6Schristos  * The overall logic has been left STRICTLY alone.  This software was
12037c9f0a6Schristos  * tested on both a VAX and Sun SpacsStation with exactly the same
12137c9f0a6Schristos  * results.  The new version and the original give IDENTICAL results.
12237c9f0a6Schristos  * The new version is somewhat faster than the original.  As the
12337c9f0a6Schristos  * documentation says:  "By default, the package runs with 128 bytes of
12437c9f0a6Schristos  * state information and generates far better random numbers than a linear
12537c9f0a6Schristos  * congruential generator.  If the amount of state information is less than
12637c9f0a6Schristos  * 32 bytes, a simple linear congruential R.N.G. is used."  For a buffer of
12737c9f0a6Schristos  * 128 bytes, this new version runs about 19 percent faster and for a 16
12837c9f0a6Schristos  * byte buffer it is about 5 percent faster.
12937c9f0a6Schristos  *
13037c9f0a6Schristos  * Modified 07 January 2002 by Jason R. Thorpe.
13137c9f0a6Schristos  * The following changes have been made:
13237c9f0a6Schristos  * All the references to "long" have been changed back to "int".  This
13337c9f0a6Schristos  * fixes memory corruption problems on LP64 platforms.
13437c9f0a6Schristos  */
13537c9f0a6Schristos 
13637c9f0a6Schristos /*
13737c9f0a6Schristos  * For each of the currently supported random number generators, we have a
13837c9f0a6Schristos  * break value on the amount of state information (you need at least this
13937c9f0a6Schristos  * many bytes of state info to support this random number generator), a degree
14037c9f0a6Schristos  * for the polynomial (actually a trinomial) that the R.N.G. is based on, and
14137c9f0a6Schristos  * the separation between the two lower order coefficients of the trinomial.
14237c9f0a6Schristos  */
14337c9f0a6Schristos #define	TYPE_0		0		/* linear congruential */
14437c9f0a6Schristos #define	BREAK_0		8
14537c9f0a6Schristos #define	DEG_0		0
14637c9f0a6Schristos #define	SEP_0		0
14737c9f0a6Schristos 
14837c9f0a6Schristos #define	TYPE_1		1		/* x**7 + x**3 + 1 */
14937c9f0a6Schristos #define	BREAK_1		32
15037c9f0a6Schristos #define	DEG_1		7
15137c9f0a6Schristos #define	SEP_1		3
15237c9f0a6Schristos 
15337c9f0a6Schristos #define	TYPE_2		2		/* x**15 + x + 1 */
15437c9f0a6Schristos #define	BREAK_2		64
15537c9f0a6Schristos #define	DEG_2		15
15637c9f0a6Schristos #define	SEP_2		1
15737c9f0a6Schristos 
15837c9f0a6Schristos #define	TYPE_3		3		/* x**31 + x**3 + 1 */
15937c9f0a6Schristos #define	BREAK_3		128
16037c9f0a6Schristos #define	DEG_3		31
16137c9f0a6Schristos #define	SEP_3		3
16237c9f0a6Schristos 
16337c9f0a6Schristos #define	TYPE_4		4		/* x**63 + x + 1 */
16437c9f0a6Schristos #define	BREAK_4		256
16537c9f0a6Schristos #define	DEG_4		63
16637c9f0a6Schristos #define	SEP_4		1
16737c9f0a6Schristos 
16837c9f0a6Schristos /*
16937c9f0a6Schristos  * Array versions of the above information to make code run faster --
17037c9f0a6Schristos  * relies on fact that TYPE_i == i.
17137c9f0a6Schristos  */
17237c9f0a6Schristos #define	MAX_TYPES	5		/* max number of types above */
17337c9f0a6Schristos 
17437c9f0a6Schristos static const int degrees[MAX_TYPES] =	{ DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
17537c9f0a6Schristos static const int seps[MAX_TYPES] =	{ SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
17637c9f0a6Schristos 
17737c9f0a6Schristos /*
17837c9f0a6Schristos  * Initially, everything is set up as if from:
17937c9f0a6Schristos  *
18037c9f0a6Schristos  *	initstate(1, &randtbl, 128);
18137c9f0a6Schristos  *
18237c9f0a6Schristos  * Note that this initialization takes advantage of the fact that srandom()
18337c9f0a6Schristos  * advances the front and rear pointers 10*rand_deg times, and hence the
18437c9f0a6Schristos  * rear pointer which starts at 0 will also end up at zero; thus the zeroeth
18537c9f0a6Schristos  * element of the state information, which contains info about the current
18637c9f0a6Schristos  * position of the rear pointer is just
18737c9f0a6Schristos  *
18837c9f0a6Schristos  *	MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
18937c9f0a6Schristos  */
19037c9f0a6Schristos 
19137c9f0a6Schristos /* LINTED */
192819b6be2Sfox static uint32_t randtbl[DEG_3 + 1] = {
19337c9f0a6Schristos 	TYPE_3,
19437c9f0a6Schristos #ifdef USE_BETTER_RANDOM
19537c9f0a6Schristos 	0x991539b1, 0x16a5bce3, 0x6774a4cd,
19637c9f0a6Schristos 	0x3e01511e, 0x4e508aaa, 0x61048c05,
19737c9f0a6Schristos 	0xf5500617, 0x846b7115, 0x6a19892c,
19837c9f0a6Schristos 	0x896a97af, 0xdb48f936, 0x14898454,
19937c9f0a6Schristos 	0x37ffd106, 0xb58bff9c, 0x59e17104,
20037c9f0a6Schristos 	0xcf918a49, 0x09378c83, 0x52c7a471,
20137c9f0a6Schristos 	0x8d293ea9, 0x1f4fc301, 0xc3db71be,
20237c9f0a6Schristos 	0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
20337c9f0a6Schristos 	0x19edc328, 0x87bf4bdd, 0xc9b240e5,
20437c9f0a6Schristos 	0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
20537c9f0a6Schristos 	0xf3bec5da,
20637c9f0a6Schristos #else
20737c9f0a6Schristos 	0x9a319039, 0x32d9c024, 0x9b663182,
20837c9f0a6Schristos 	0x5da1f342, 0xde3b81e0, 0xdf0a6fb5,
20937c9f0a6Schristos 	0xf103bc02, 0x48f340fb, 0x7449e56b,
21037c9f0a6Schristos 	0xbeb1dbb0, 0xab5c5918, 0x946554fd,
21137c9f0a6Schristos 	0x8c2e680f, 0xeb3d799f, 0xb11ee0b7,
21237c9f0a6Schristos 	0x2d436b86, 0xda672e2a, 0x1588ca88,
21337c9f0a6Schristos 	0xe369735d, 0x904f35f7, 0xd7158fd6,
21437c9f0a6Schristos 	0x6fa6f051, 0x616e6b96, 0xac94efdc,
21537c9f0a6Schristos 	0x36413f93, 0xc622c298, 0xf5a42ab8,
21637c9f0a6Schristos 	0x8a88d77b, 0xf5ad9d0e, 0x8999220b,
21737c9f0a6Schristos 	0x27fb47b9,
21837c9f0a6Schristos #endif /* USE_BETTER_RANDOM */
21937c9f0a6Schristos };
22037c9f0a6Schristos 
22137c9f0a6Schristos /*
22237c9f0a6Schristos  * fptr and rptr are two pointers into the state info, a front and a rear
22337c9f0a6Schristos  * pointer.  These two pointers are always rand_sep places aparts, as they
22437c9f0a6Schristos  * cycle cyclically through the state information.  (Yes, this does mean we
22537c9f0a6Schristos  * could get away with just one pointer, but the code for random() is more
22637c9f0a6Schristos  * efficient this way).  The pointers are left positioned as they would be
22737c9f0a6Schristos  * from the call
22837c9f0a6Schristos  *
22937c9f0a6Schristos  *	initstate(1, randtbl, 128);
23037c9f0a6Schristos  *
23137c9f0a6Schristos  * (The position of the rear pointer, rptr, is really 0 (as explained above
23237c9f0a6Schristos  * in the initialization of randtbl) because the state table pointer is set
23337c9f0a6Schristos  * to point to randtbl[1] (as explained below).
23437c9f0a6Schristos  */
235819b6be2Sfox static uint32_t *fptr = &randtbl[SEP_3 + 1];
236819b6be2Sfox static uint32_t *rptr = &randtbl[1];
23737c9f0a6Schristos 
23837c9f0a6Schristos /*
23937c9f0a6Schristos  * The following things are the pointer to the state information table, the
24037c9f0a6Schristos  * type of the current generator, the degree of the current polynomial being
24137c9f0a6Schristos  * used, and the separation between the two pointers.  Note that for efficiency
24237c9f0a6Schristos  * of random(), we remember the first location of the state information, not
24337c9f0a6Schristos  * the zeroeth.  Hence it is valid to access state[-1], which is used to
24437c9f0a6Schristos  * store the type of the R.N.G.  Also, we remember the last location, since
24537c9f0a6Schristos  * this is more efficient than indexing every time to find the address of
24637c9f0a6Schristos  * the last element to see if the front and rear pointers have wrapped.
24737c9f0a6Schristos  */
248819b6be2Sfox static uint32_t *state = &randtbl[1];
24937c9f0a6Schristos static int rand_type = TYPE_3;
25037c9f0a6Schristos static int rand_deg = DEG_3;
25137c9f0a6Schristos static int rand_sep = SEP_3;
252819b6be2Sfox static uint32_t *end_ptr = &randtbl[DEG_3 + 1];
25337c9f0a6Schristos 
25437c9f0a6Schristos /*
25537c9f0a6Schristos  * srandom:
25637c9f0a6Schristos  *
25737c9f0a6Schristos  * Initialize the random number generator based on the given seed.  If the
25837c9f0a6Schristos  * type is the trivial no-state-information type, just remember the seed.
25937c9f0a6Schristos  * Otherwise, initializes state[] based on the given "seed" via a linear
26037c9f0a6Schristos  * congruential generator.  Then, the pointers are set to known locations
26137c9f0a6Schristos  * that are exactly rand_sep places apart.  Lastly, it cycles the state
26237c9f0a6Schristos  * information a given number of times to get rid of any initial dependencies
26337c9f0a6Schristos  * introduced by the L.C.R.N.G.  Note that the initialization of randtbl[]
26437c9f0a6Schristos  * for default usage relies on values produced by this routine.
26537c9f0a6Schristos  */
26637c9f0a6Schristos static void
srandom_unlocked(unsigned int x)26793412868Schristos srandom_unlocked(unsigned int x)
26837c9f0a6Schristos {
26937c9f0a6Schristos 	int i;
27037c9f0a6Schristos 
27137c9f0a6Schristos 	if (rand_type == TYPE_0)
27237c9f0a6Schristos 		state[0] = x;
27337c9f0a6Schristos 	else {
27437c9f0a6Schristos 		state[0] = x;
27537c9f0a6Schristos 		for (i = 1; i < rand_deg; i++) {
27637c9f0a6Schristos #ifdef USE_BETTER_RANDOM
27737c9f0a6Schristos 			int x1, hi, lo, t;
27837c9f0a6Schristos 
27937c9f0a6Schristos 			/*
28037c9f0a6Schristos 			 * Compute x[n + 1] = (7^5 * x[n]) mod (2^31 - 1).
28137c9f0a6Schristos 			 * From "Random number generators: good ones are hard
28237c9f0a6Schristos 			 * to find", Park and Miller, Communications of the ACM,
28337c9f0a6Schristos 			 * vol. 31, no. 10,
28437c9f0a6Schristos 			 * October 1988, p. 1195.
28537c9f0a6Schristos 			 */
28637c9f0a6Schristos 			x1 = state[i - 1];
28737c9f0a6Schristos 			hi = x1 / 127773;
28837c9f0a6Schristos 			lo = x1 % 127773;
28937c9f0a6Schristos 			t = 16807 * lo - 2836 * hi;
29037c9f0a6Schristos 			if (t <= 0)
29137c9f0a6Schristos 				t += 0x7fffffff;
29237c9f0a6Schristos 			state[i] = t;
29337c9f0a6Schristos #else
29437c9f0a6Schristos 			state[i] = 1103515245 * state[i - 1] + 12345;
29537c9f0a6Schristos #endif /* USE_BETTER_RANDOM */
29637c9f0a6Schristos 		}
29737c9f0a6Schristos 		fptr = &state[rand_sep];
29837c9f0a6Schristos 		rptr = &state[0];
29937c9f0a6Schristos 		for (i = 0; i < 10 * rand_deg; i++)
30037c9f0a6Schristos 			(void)random_unlocked();
30137c9f0a6Schristos 	}
30237c9f0a6Schristos }
30337c9f0a6Schristos 
30437c9f0a6Schristos void
srandom(unsigned int x)305f16aa474Schristos srandom(unsigned int x)
30637c9f0a6Schristos {
30737c9f0a6Schristos 
30837c9f0a6Schristos 	mutex_lock(&random_mutex);
309f16aa474Schristos 	srandom_unlocked(x);
31037c9f0a6Schristos 	mutex_unlock(&random_mutex);
31137c9f0a6Schristos }
31237c9f0a6Schristos 
31337c9f0a6Schristos /*
31437c9f0a6Schristos  * initstate:
31537c9f0a6Schristos  *
31637c9f0a6Schristos  * Initialize the state information in the given array of n bytes for future
31737c9f0a6Schristos  * random number generation.  Based on the number of bytes we are given, and
31837c9f0a6Schristos  * the break values for the different R.N.G.'s, we choose the best (largest)
31937c9f0a6Schristos  * one we can and set things up for it.  srandom() is then called to
32037c9f0a6Schristos  * initialize the state information.
32137c9f0a6Schristos  *
32237c9f0a6Schristos  * Note that on return from srandom(), we set state[-1] to be the type
32337c9f0a6Schristos  * multiplexed with the current value of the rear pointer; this is so
32437c9f0a6Schristos  * successive calls to initstate() won't lose this information and will be
32537c9f0a6Schristos  * able to restart with setstate().
32637c9f0a6Schristos  *
32737c9f0a6Schristos  * Note: the first thing we do is save the current state, if any, just like
32837c9f0a6Schristos  * setstate() so that it doesn't matter when initstate is called.
32937c9f0a6Schristos  *
33037c9f0a6Schristos  * Returns a pointer to the old state.
33137c9f0a6Schristos  *
33237c9f0a6Schristos  * Note: The Sparc platform requires that arg_state begin on an int
33337c9f0a6Schristos  * word boundary; otherwise a bus error will occur. Even so, lint will
33437c9f0a6Schristos  * complain about mis-alignment, but you should disregard these messages.
33537c9f0a6Schristos  */
33637c9f0a6Schristos char *
initstate(unsigned int seed,char * arg_state,size_t n)33793412868Schristos initstate(
338f16aa474Schristos 	unsigned int seed,		/* seed for R.N.G. */
33993412868Schristos 	char *arg_state,		/* pointer to state array */
34093412868Schristos 	size_t n)			/* # bytes of state info */
34137c9f0a6Schristos {
34237c9f0a6Schristos 	void *ostate = (void *)(&state[-1]);
343819b6be2Sfox 	uint32_t *int_arg_state;
34437c9f0a6Schristos 
34537c9f0a6Schristos 	_DIAGASSERT(arg_state != NULL);
34637c9f0a6Schristos 
347819b6be2Sfox 	int_arg_state = (uint32_t *)(void *)arg_state;
34837c9f0a6Schristos 
34937c9f0a6Schristos 	mutex_lock(&random_mutex);
35037c9f0a6Schristos 	if (rand_type == TYPE_0)
35137c9f0a6Schristos 		state[-1] = rand_type;
35237c9f0a6Schristos 	else
353819b6be2Sfox 		state[-1] = MAX_TYPES * (uint32_t)(rptr - state) + rand_type;
35437c9f0a6Schristos 	if (n < BREAK_0) {
35537c9f0a6Schristos 		mutex_unlock(&random_mutex);
35637c9f0a6Schristos 		return (NULL);
35737c9f0a6Schristos 	} else if (n < BREAK_1) {
35837c9f0a6Schristos 		rand_type = TYPE_0;
35937c9f0a6Schristos 		rand_deg = DEG_0;
36037c9f0a6Schristos 		rand_sep = SEP_0;
36137c9f0a6Schristos 	} else if (n < BREAK_2) {
36237c9f0a6Schristos 		rand_type = TYPE_1;
36337c9f0a6Schristos 		rand_deg = DEG_1;
36437c9f0a6Schristos 		rand_sep = SEP_1;
36537c9f0a6Schristos 	} else if (n < BREAK_3) {
36637c9f0a6Schristos 		rand_type = TYPE_2;
36737c9f0a6Schristos 		rand_deg = DEG_2;
36837c9f0a6Schristos 		rand_sep = SEP_2;
36937c9f0a6Schristos 	} else if (n < BREAK_4) {
37037c9f0a6Schristos 		rand_type = TYPE_3;
37137c9f0a6Schristos 		rand_deg = DEG_3;
37237c9f0a6Schristos 		rand_sep = SEP_3;
37337c9f0a6Schristos 	} else {
37437c9f0a6Schristos 		rand_type = TYPE_4;
37537c9f0a6Schristos 		rand_deg = DEG_4;
37637c9f0a6Schristos 		rand_sep = SEP_4;
37737c9f0a6Schristos 	}
378819b6be2Sfox 	state = (uint32_t *) (int_arg_state + 1); /* first location */
37937c9f0a6Schristos 	end_ptr = &state[rand_deg];	/* must set end_ptr before srandom */
380f16aa474Schristos 	srandom_unlocked(seed);
38137c9f0a6Schristos 	if (rand_type == TYPE_0)
38237c9f0a6Schristos 		int_arg_state[0] = rand_type;
38337c9f0a6Schristos 	else
384819b6be2Sfox 		int_arg_state[0] = MAX_TYPES * (uint32_t)(rptr - state) + rand_type;
38537c9f0a6Schristos 	mutex_unlock(&random_mutex);
38637c9f0a6Schristos 	return((char *)ostate);
38737c9f0a6Schristos }
38837c9f0a6Schristos 
38937c9f0a6Schristos /*
39037c9f0a6Schristos  * setstate:
39137c9f0a6Schristos  *
39237c9f0a6Schristos  * Restore the state from the given state array.
39337c9f0a6Schristos  *
39437c9f0a6Schristos  * Note: it is important that we also remember the locations of the pointers
39537c9f0a6Schristos  * in the current state information, and restore the locations of the pointers
39637c9f0a6Schristos  * from the old state information.  This is done by multiplexing the pointer
39737c9f0a6Schristos  * location into the zeroeth word of the state information.
39837c9f0a6Schristos  *
39937c9f0a6Schristos  * Note that due to the order in which things are done, it is OK to call
40037c9f0a6Schristos  * setstate() with the same state as the current state.
40137c9f0a6Schristos  *
40237c9f0a6Schristos  * Returns a pointer to the old state information.
40337c9f0a6Schristos  *
40437c9f0a6Schristos  * Note: The Sparc platform requires that arg_state begin on a long
40537c9f0a6Schristos  * word boundary; otherwise a bus error will occur. Even so, lint will
40637c9f0a6Schristos  * complain about mis-alignment, but you should disregard these messages.
40737c9f0a6Schristos  */
40837c9f0a6Schristos char *
setstate(char * arg_state)40993412868Schristos setstate(char *arg_state)		/* pointer to state array */
41037c9f0a6Schristos {
411819b6be2Sfox 	uint32_t *new_state;
412819b6be2Sfox 	uint32_t type;
413819b6be2Sfox 	uint32_t rear;
41437c9f0a6Schristos 	void *ostate = (void *)(&state[-1]);
41537c9f0a6Schristos 
41637c9f0a6Schristos 	_DIAGASSERT(arg_state != NULL);
41737c9f0a6Schristos 
418819b6be2Sfox 	new_state = (uint32_t *)(void *)arg_state;
419819b6be2Sfox 	type = (uint32_t)(new_state[0] % MAX_TYPES);
420819b6be2Sfox 	rear = (uint32_t)(new_state[0] / MAX_TYPES);
42137c9f0a6Schristos 
42237c9f0a6Schristos 	mutex_lock(&random_mutex);
42337c9f0a6Schristos 	if (rand_type == TYPE_0)
42437c9f0a6Schristos 		state[-1] = rand_type;
42537c9f0a6Schristos 	else
426819b6be2Sfox 		state[-1] = MAX_TYPES * (uint32_t)(rptr - state) + rand_type;
42737c9f0a6Schristos 	switch(type) {
42837c9f0a6Schristos 	case TYPE_0:
42937c9f0a6Schristos 	case TYPE_1:
43037c9f0a6Schristos 	case TYPE_2:
43137c9f0a6Schristos 	case TYPE_3:
43237c9f0a6Schristos 	case TYPE_4:
43337c9f0a6Schristos 		rand_type = type;
43437c9f0a6Schristos 		rand_deg = degrees[type];
43537c9f0a6Schristos 		rand_sep = seps[type];
43637c9f0a6Schristos 		break;
43737c9f0a6Schristos 	default:
43837c9f0a6Schristos 		mutex_unlock(&random_mutex);
43937c9f0a6Schristos 		return (NULL);
44037c9f0a6Schristos 	}
441819b6be2Sfox 	state = (uint32_t *) (new_state + 1);
44237c9f0a6Schristos 	if (rand_type != TYPE_0) {
44337c9f0a6Schristos 		rptr = &state[rear];
44437c9f0a6Schristos 		fptr = &state[(rear + rand_sep) % rand_deg];
44537c9f0a6Schristos 	}
44637c9f0a6Schristos 	end_ptr = &state[rand_deg];		/* set end_ptr too */
44737c9f0a6Schristos 	mutex_unlock(&random_mutex);
44837c9f0a6Schristos 	return((char *)ostate);
44937c9f0a6Schristos }
45037c9f0a6Schristos 
45137c9f0a6Schristos /*
45237c9f0a6Schristos  * random:
45337c9f0a6Schristos  *
45437c9f0a6Schristos  * If we are using the trivial TYPE_0 R.N.G., just do the old linear
45537c9f0a6Schristos  * congruential bit.  Otherwise, we do our fancy trinomial stuff, which is
45637c9f0a6Schristos  * the same in all the other cases due to all the global variables that have
45737c9f0a6Schristos  * been set up.  The basic operation is to add the number at the rear pointer
45837c9f0a6Schristos  * into the one at the front pointer.  Then both pointers are advanced to
45937c9f0a6Schristos  * the next location cyclically in the table.  The value returned is the sum
46037c9f0a6Schristos  * generated, reduced to 31 bits by throwing away the "least random" low bit.
46137c9f0a6Schristos  *
46237c9f0a6Schristos  * Note: the code takes advantage of the fact that both the front and
46337c9f0a6Schristos  * rear pointers can't wrap on the same call by not testing the rear
46437c9f0a6Schristos  * pointer if the front one has wrapped.
46537c9f0a6Schristos  *
46637c9f0a6Schristos  * Returns a 31-bit random number.
46737c9f0a6Schristos  */
46837c9f0a6Schristos static long
random_unlocked(void)46993412868Schristos random_unlocked(void)
47037c9f0a6Schristos {
471819b6be2Sfox 	uint32_t i;
472819b6be2Sfox 	uint32_t *f, *r;
47337c9f0a6Schristos 
47437c9f0a6Schristos 	if (rand_type == TYPE_0) {
47537c9f0a6Schristos 		i = state[0];
47637c9f0a6Schristos 		state[0] = i = (i * 1103515245 + 12345) & 0x7fffffff;
47737c9f0a6Schristos 	} else {
47837c9f0a6Schristos 		/*
47937c9f0a6Schristos 		 * Use local variables rather than static variables for speed.
48037c9f0a6Schristos 		 */
48137c9f0a6Schristos 		f = fptr; r = rptr;
48237c9f0a6Schristos 		*f += *r;
48337c9f0a6Schristos 		/* chucking least random bit */
484819b6be2Sfox 		i = ((uint32_t)*f >> 1) & 0x7fffffff;
48537c9f0a6Schristos 		if (++f >= end_ptr) {
48637c9f0a6Schristos 			f = state;
48737c9f0a6Schristos 			++r;
48837c9f0a6Schristos 		}
48937c9f0a6Schristos 		else if (++r >= end_ptr) {
49037c9f0a6Schristos 			r = state;
49137c9f0a6Schristos 		}
49237c9f0a6Schristos 
49337c9f0a6Schristos 		fptr = f; rptr = r;
49437c9f0a6Schristos 	}
49537c9f0a6Schristos 	return(i);
49637c9f0a6Schristos }
49737c9f0a6Schristos 
49837c9f0a6Schristos long
random(void)49993412868Schristos random(void)
50037c9f0a6Schristos {
50137c9f0a6Schristos 	long r;
50237c9f0a6Schristos 
50337c9f0a6Schristos 	mutex_lock(&random_mutex);
50437c9f0a6Schristos 	r = random_unlocked();
50537c9f0a6Schristos 	mutex_unlock(&random_mutex);
50637c9f0a6Schristos 	return (r);
50737c9f0a6Schristos }
50870b3b52aSchristos #else
50970b3b52aSchristos long
random(void)51070b3b52aSchristos random(void)
51170b3b52aSchristos {
51270b3b52aSchristos 	static u_long randseed = 1;
51370b3b52aSchristos 	long x, hi, lo, t;
51470b3b52aSchristos 
51570b3b52aSchristos 	/*
51670b3b52aSchristos 	 * Compute x[n + 1] = (7^5 * x[n]) mod (2^31 - 1).
51770b3b52aSchristos 	 * From "Random number generators: good ones are hard to find",
51870b3b52aSchristos 	 * Park and Miller, Communications of the ACM, vol. 31, no. 10,
51970b3b52aSchristos 	 * October 1988, p. 1195.
52070b3b52aSchristos 	 */
52170b3b52aSchristos 	x = randseed;
52270b3b52aSchristos 	hi = x / 127773;
52370b3b52aSchristos 	lo = x % 127773;
52470b3b52aSchristos 	t = 16807 * lo - 2836 * hi;
52570b3b52aSchristos 	if (t <= 0)
52670b3b52aSchristos 		t += 0x7fffffff;
52770b3b52aSchristos 	randseed = t;
52870b3b52aSchristos 	return (t);
52970b3b52aSchristos }
53070b3b52aSchristos #endif /* SMALL_RANDOM */
531