提交 f7dff185 编写于 作者: R Rich Felker

locking support for random() prng

these interfaces are required to be thread-safe even though they are
not state-free. the random number sequence is shared across all
threads.
上级 af3d5405
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include "libc.h"
/* /*
this code uses the same lagged fibonacci generator as the this code uses the same lagged fibonacci generator as the
...@@ -32,6 +33,7 @@ static int n = 31; ...@@ -32,6 +33,7 @@ static int n = 31;
static int i = 3; static int i = 3;
static int j = 0; static int j = 0;
static uint32_t *x = init+1; static uint32_t *x = init+1;
static int lock;
static uint32_t lcg31(uint32_t x) { static uint32_t lcg31(uint32_t x) {
return (1103515245*x + 12345) & 0x7fffffff; return (1103515245*x + 12345) & 0x7fffffff;
...@@ -53,7 +55,7 @@ static void loadstate(uint32_t *state) { ...@@ -53,7 +55,7 @@ static void loadstate(uint32_t *state) {
j = x[-1]&0xff; j = x[-1]&0xff;
} }
void srandom(unsigned seed) { static void __srandom(unsigned seed) {
int k; int k;
uint64_t s = seed; uint64_t s = seed;
...@@ -71,11 +73,20 @@ void srandom(unsigned seed) { ...@@ -71,11 +73,20 @@ void srandom(unsigned seed) {
x[0] |= 1; x[0] |= 1;
} }
void srandom(unsigned seed) {
LOCK(&lock);
__srandom(seed);
UNLOCK(&lock);
}
char *initstate(unsigned seed, char *state, size_t size) { char *initstate(unsigned seed, char *state, size_t size) {
void *old = savestate(); void *old;
if (size < 8) if (size < 8)
return 0; return 0;
else if (size < 32) LOCK(&lock);
old = savestate();
if (size < 32)
n = 0; n = 0;
else if (size < 64) else if (size < 64)
n = 7; n = 7;
...@@ -86,26 +97,36 @@ char *initstate(unsigned seed, char *state, size_t size) { ...@@ -86,26 +97,36 @@ char *initstate(unsigned seed, char *state, size_t size) {
else else
n = 63; n = 63;
x = (uint32_t*)state + 1; x = (uint32_t*)state + 1;
srandom(seed); __srandom(seed);
UNLOCK(&lock);
return old; return old;
} }
char *setstate(char *state) { char *setstate(char *state) {
void *old = savestate(); void *old;
LOCK(&lock);
old = savestate();
loadstate((uint32_t*)state); loadstate((uint32_t*)state);
UNLOCK(&lock);
return old; return old;
} }
long random(void) { long random(void) {
long k; long k;
if (n == 0) LOCK(&lock);
return x[0] = lcg31(x[0]); if (n == 0) {
k = x[0] = lcg31(x[0]);
goto end;
}
x[i] += x[j]; x[i] += x[j];
k = x[i]>>1; k = x[i]>>1;
if (++i == n) if (++i == n)
i = 0; i = 0;
if (++j == n) if (++j == n)
j = 0; j = 0;
end:
UNLOCK(&lock);
return k; return k;
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册