-/*
- * random.c - Copyright © 2011 Szabolcs Nagy
- * Permission to use, copy, modify, and/or distribute this code
- * for any purpose with or without fee is hereby granted.
- * There is no warranty.
-*/
-
#include <stdlib.h>
#include <stdint.h>
-#include "libc.h"
+#include "lock.h"
+#include "fork_impl.h"
/*
this code uses the same lagged fibonacci generator as the
original bsd random implementation except for the seeding
-
-different seeds produce different sequences with long period
-(other libcs seed the state with a park-miller generator
-when seed=0 some fail to produce good random sequence
-others produce the same sequence as another seed)
+which was broken in the original
*/
static uint32_t init[] = {
static int i = 3;
static int j = 0;
static uint32_t *x = init+1;
-static int lock;
+static volatile int lock[1];
+volatile int *const __random_lockptr = lock;
static uint32_t lcg31(uint32_t x) {
return (1103515245*x + 12345) & 0x7fffffff;
}
void srandom(unsigned seed) {
- LOCK(&lock);
+ LOCK(lock);
__srandom(seed);
- UNLOCK(&lock);
+ UNLOCK(lock);
}
char *initstate(unsigned seed, char *state, size_t size) {
if (size < 8)
return 0;
- LOCK(&lock);
+ LOCK(lock);
old = savestate();
if (size < 32)
n = 0;
n = 63;
x = (uint32_t*)state + 1;
__srandom(seed);
- UNLOCK(&lock);
+ savestate();
+ UNLOCK(lock);
return old;
}
char *setstate(char *state) {
void *old;
- LOCK(&lock);
+ LOCK(lock);
old = savestate();
loadstate((uint32_t*)state);
- UNLOCK(&lock);
+ UNLOCK(lock);
return old;
}
long random(void) {
long k;
- LOCK(&lock);
+ LOCK(lock);
if (n == 0) {
k = x[0] = lcg31(x[0]);
goto end;
if (++j == n)
j = 0;
end:
- UNLOCK(&lock);
+ UNLOCK(lock);
return k;
}