summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libc/stdlib/random.c51
1 files changed, 43 insertions, 8 deletions
diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c
index 9c5b9d0f3f..f299d8e2f6 100644
--- a/src/lib/libc/stdlib/random.c
+++ b/src/lib/libc/stdlib/random.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: random.c,v 1.17 2012/06/01 01:01:57 guenther Exp $ */ 1/* $OpenBSD: random.c,v 1.18 2013/03/15 19:07:53 tedu Exp $ */
2/* 2/*
3 * Copyright (c) 1983 Regents of the University of California. 3 * Copyright (c) 1983 Regents of the University of California.
4 * All rights reserved. 4 * All rights reserved.
@@ -36,6 +36,8 @@
36#include <stdlib.h> 36#include <stdlib.h>
37#include <unistd.h> 37#include <unistd.h>
38 38
39#include "thread_private.h"
40
39/* 41/*
40 * random.c: 42 * random.c:
41 * 43 *
@@ -174,6 +176,12 @@ static int rand_type = TYPE_3;
174static int rand_deg = DEG_3; 176static int rand_deg = DEG_3;
175static int rand_sep = SEP_3; 177static int rand_sep = SEP_3;
176 178
179_THREAD_PRIVATE_MUTEX(random);
180static long random_l(void);
181
182#define LOCK() _THREAD_PRIVATE_MUTEX_LOCK(random)
183#define UNLOCK() _THREAD_PRIVATE_MUTEX_UNLOCK(random)
184
177/* 185/*
178 * srandom: 186 * srandom:
179 * 187 *
@@ -186,8 +194,8 @@ static int rand_sep = SEP_3;
186 * introduced by the L.C.R.N.G. Note that the initialization of randtbl[] 194 * introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
187 * for default usage relies on values produced by this routine. 195 * for default usage relies on values produced by this routine.
188 */ 196 */
189void 197static void
190srandom(unsigned int x) 198srandom_l(unsigned int x)
191{ 199{
192 int i; 200 int i;
193 int32_t test; 201 int32_t test;
@@ -213,10 +221,18 @@ srandom(unsigned int x)
213 fptr = &state[rand_sep]; 221 fptr = &state[rand_sep];
214 rptr = &state[0]; 222 rptr = &state[0];
215 for (i = 0; i < 10 * rand_deg; i++) 223 for (i = 0; i < 10 * rand_deg; i++)
216 (void)random(); 224 (void)random_l();
217 } 225 }
218} 226}
219 227
228void
229srandom(unsigned int x)
230{
231 LOCK();
232 srandom_l(x);
233 UNLOCK();
234}
235
220/* 236/*
221 * srandomdev: 237 * srandomdev:
222 * 238 *
@@ -234,6 +250,7 @@ srandomdev(void)
234 int mib[2]; 250 int mib[2];
235 size_t len; 251 size_t len;
236 252
253 LOCK();
237 if (rand_type == TYPE_0) 254 if (rand_type == TYPE_0)
238 len = sizeof(state[0]); 255 len = sizeof(state[0]);
239 else 256 else
@@ -247,6 +264,7 @@ srandomdev(void)
247 fptr = &state[rand_sep]; 264 fptr = &state[rand_sep];
248 rptr = &state[0]; 265 rptr = &state[0];
249 } 266 }
267 UNLOCK();
250} 268}
251 269
252/* 270/*
@@ -273,12 +291,15 @@ initstate(u_int seed, char *arg_state, size_t n)
273{ 291{
274 char *ostate = (char *)(&state[-1]); 292 char *ostate = (char *)(&state[-1]);
275 293
294 LOCK();
276 if (rand_type == TYPE_0) 295 if (rand_type == TYPE_0)
277 state[-1] = rand_type; 296 state[-1] = rand_type;
278 else 297 else
279 state[-1] = MAX_TYPES * (rptr - state) + rand_type; 298 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
280 if (n < BREAK_0) 299 if (n < BREAK_0) {
300 UNLOCK();
281 return(NULL); 301 return(NULL);
302 }
282 if (n < BREAK_1) { 303 if (n < BREAK_1) {
283 rand_type = TYPE_0; 304 rand_type = TYPE_0;
284 rand_deg = DEG_0; 305 rand_deg = DEG_0;
@@ -302,11 +323,12 @@ initstate(u_int seed, char *arg_state, size_t n)
302 } 323 }
303 state = &(((int32_t *)arg_state)[1]); /* first location */ 324 state = &(((int32_t *)arg_state)[1]); /* first location */
304 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */ 325 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
305 srandom(seed); 326 srandom_l(seed);
306 if (rand_type == TYPE_0) 327 if (rand_type == TYPE_0)
307 state[-1] = rand_type; 328 state[-1] = rand_type;
308 else 329 else
309 state[-1] = MAX_TYPES*(rptr - state) + rand_type; 330 state[-1] = MAX_TYPES*(rptr - state) + rand_type;
331 UNLOCK();
310 return(ostate); 332 return(ostate);
311} 333}
312 334
@@ -333,6 +355,7 @@ setstate(char *arg_state)
333 int32_t rear = new_state[0] / MAX_TYPES; 355 int32_t rear = new_state[0] / MAX_TYPES;
334 char *ostate = (char *)(&state[-1]); 356 char *ostate = (char *)(&state[-1]);
335 357
358 LOCK();
336 if (rand_type == TYPE_0) 359 if (rand_type == TYPE_0)
337 state[-1] = rand_type; 360 state[-1] = rand_type;
338 else 361 else
@@ -348,6 +371,7 @@ setstate(char *arg_state)
348 rand_sep = seps[type]; 371 rand_sep = seps[type];
349 break; 372 break;
350 default: 373 default:
374 UNLOCK();
351 return(NULL); 375 return(NULL);
352 } 376 }
353 state = &new_state[1]; 377 state = &new_state[1];
@@ -356,6 +380,7 @@ setstate(char *arg_state)
356 fptr = &state[(rear + rand_sep) % rand_deg]; 380 fptr = &state[(rear + rand_sep) % rand_deg];
357 } 381 }
358 end_ptr = &state[rand_deg]; /* set end_ptr too */ 382 end_ptr = &state[rand_deg]; /* set end_ptr too */
383 UNLOCK();
359 return(ostate); 384 return(ostate);
360} 385}
361 386
@@ -376,8 +401,8 @@ setstate(char *arg_state)
376 * 401 *
377 * Returns a 31-bit random number. 402 * Returns a 31-bit random number.
378 */ 403 */
379long 404static long
380random(void) 405random_l(void)
381{ 406{
382 int32_t i; 407 int32_t i;
383 408
@@ -394,3 +419,13 @@ random(void)
394 } 419 }
395 return((long)i); 420 return((long)i);
396} 421}
422
423long
424random(void)
425{
426 long r;
427 LOCK();
428 r = random_l();
429 UNLOCK();
430 return r;
431}