Add proper per-file copyright notices/licenses and top-level license.
[bluesky.git] / TBBT / trace_play / sfs_c_rnd.c
1 #ifndef lint
2 static char sfs_c_rndSid[] = "@(#)sfs_c_rnd.c   2.1     97/10/23";
3 #endif
4
5 /*
6  *   Copyright (c) 1992-1997,2001 by Standard Performance Evaluation Corporation
7  *      All rights reserved.
8  *              Standard Performance Evaluation Corporation (SPEC)
9  *              6585 Merchant Place, Suite 100
10  *              Warrenton, VA 20187
11  *
12  *      This product contains benchmarks acquired from several sources who
13  *      understand and agree with SPEC's goal of creating fair and objective
14  *      benchmarks to measure computer performance.
15  *
16  *      This copyright notice is placed here only to protect SPEC in the
17  *      event the source is misused in any manner that is contrary to the
18  *      spirit, the goals and the intent of SPEC.
19  *
20  *      The source code is provided to the user or company under the license
21  *      agreement for the SPEC Benchmark Suite for this product.
22  */
23
24 /*****************************************************************
25  *                                                               *
26  *      Copyright 1991,1992  Legato Systems, Inc.                *
27  *      Copyright 1991,1992  Auspex Systems, Inc.                *
28  *      Copyright 1991,1992  Data General Corporation            *
29  *      Copyright 1991,1992  Digital Equipment Corporation       *
30  *      Copyright 1991,1992  Interphase Corporation              *
31  *      Copyright 1991,1992  Sun Microsystems, Inc.              *
32  *                                                               *
33  *****************************************************************/
34
35 /*
36  * ---------------------- sfs_c_rnd.c ---------------------
37  *
38  *      Random number generator.
39  *
40  *.Exported_routines
41  *      int32_t sfs_random(void)
42  *      void sfs_srandom(int)
43  *
44  *.Local_routines
45  *      double ran(void)
46  *      int32_t spec_rand(void)
47  *      void spec_srand(int)
48  *
49  *.Revision_History
50  *      28-Nov-91       Teelucksingh    ANSI C
51  *      01-Aug-91       Wiryaman        sfs_srandom() and sfs_random()
52  *                                      now use spec_srand() and spec_rand()
53  *                                      instead of srandom() and random().
54  *      17-Apr-91       Wittle          Created.
55  */
56
57 /*
58  * ANSI C headers
59  */
60 #include <stdio.h>
61 #include <stdlib.h>
62 #include <string.h>
63 #include <errno.h>
64 #include <math.h>
65 #include <signal.h>
66
67 #include <sys/types.h>
68 #include <sys/stat.h>
69
70 #include <unistd.h>
71
72 #include "sfs_c_def.h"
73 #include "sfs_m_def.h"
74
75 /*
76  * Here's the source for the random number generator that SPEC uses.
77  * The function to be called is "spec_rand" which returns an integer
78  * between 1 and MAX_INT-1.
79  *
80  * One question we may wanna think about is the seeding of the random
81  * number generator. Do we start with the same seed everytime (for
82  * repeatability) or use a array of possible seeds (some seeds are better
83  * than others and SPEC prople mention that they have a list of 15
84  * "good" seeds).
85  */
86
87
88 /*
89  * -------------------------  Static Declarations  -------------------------
90  */
91
92 static int32_t seedi = 2231;
93
94
95 /*
96  * -------------------------  External Definitions  -------------------------
97  */
98
99 static double ran(void);
100 static int32_t spec_rand(void);
101 static void spec_srand(int);
102
103 /*
104  * -----------------------  Random Number Routines  -----------------------
105  */
106
107
108 /*
109  * Seed the random number generator.
110  */
111 static void
112 spec_srand(
113     int seed)
114 {
115     seedi = seed;
116 }
117
118
119 /*
120  * Returns a random number.
121  */
122 static int32_t
123 spec_rand(void)
124 {
125     (void) ran();
126     return(seedi);
127 }
128
129
130 /*
131  * Compute the next random number.
132  */
133 static double
134 ran(void)
135
136 /* See "Random Number Generators: Good Ones Are Hard To Find", */
137 /*     Park & Miller, CACM 31#10 October 1988 pages 1192-1201. */
138 /***********************************************************/
139 /* THIS IMPLEMENTATION REQUIRES AT LEAST 32 BIT INTEGERS ! */
140 /***********************************************************/
141
142 #define _A_MULTIPLIER  16807L
143 #define _M_MODULUS     2147483647L /* (2**31)-1 */
144 #define _Q_QUOTIENT    127773L     /* 2147483647 / 16807 */
145 #define _R_REMAINDER   2836L       /* 2147483647 % 16807 */
146 {
147     int32_t     lo;
148     int32_t     hi;
149     int32_t     test;
150
151     hi = seedi / _Q_QUOTIENT;
152     lo = seedi % _Q_QUOTIENT;
153     test = _A_MULTIPLIER * lo - _R_REMAINDER * hi;
154     if (test > 0) {
155         seedi = test;
156     } else {
157         seedi = test + _M_MODULUS;
158     }
159     return((float) seedi / _M_MODULUS);
160 }
161
162 /*
163  * Local interface to seed random number generator.
164  */
165 void
166 sfs_srandom(
167     int         seed)
168 {
169     spec_srand(seed);
170 }
171
172
173 /*
174  * Local interface to obtain a random number.
175  */
176 int32_t
177 sfs_random(void)
178 {
179     return(spec_rand());
180 }
181
182 static struct r_array {
183         int n1;
184         int n2;
185 } *r_array;
186
187 static int r_length = 0;
188
189 static int
190 r_array_compare(const void *i, const void *j)
191 {
192         if (((struct r_array *)i)->n2 > ((struct r_array *)j)->n2)
193                 return (1);
194         if (((struct r_array *)i)->n2 < ((struct r_array *)j)->n2)
195                 return (-1);
196         return (0);
197 }
198
199 int
200 init_rand_range(int length)
201 {
202         int i;
203
204         /*
205          * If array already exists free it
206          */
207         if (r_length != 0) {
208                 (void)free(r_array);
209                 r_length = 0;
210         }
211
212         /*
213          * If length is zero just free memory and return
214          */
215         if (length == 0)
216                 return (0);
217
218         /*
219          * Allocate array of sequential numbers and random numbers
220          */
221         if ((r_array = malloc(length * sizeof(struct r_array))) == NULL)
222                 return (1);
223
224         r_length = length;
225
226         /*
227          * Initialize array of sequential values and random values
228          */
229         for (i = 0; i < length; i++) {
230                 r_array[i].n1 = i;
231                 r_array[i].n2 = sfs_random();
232         }
233
234         /*
235          * Sort random array values to put sequential values in random order
236          */
237         qsort(r_array, length, sizeof(struct r_array), r_array_compare);
238
239         return (0);
240 }
241
242 int
243 rand_range(int index)
244 {
245         return (r_array[index].n1);
246 }
247 /* sfs_c_rnd.c */