diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-09-11 02:10:25 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-09-11 02:10:25 +0200 |
commit | 10275ad6dd261b21774848e3d5913807ae293236 (patch) | |
tree | c86f38c1d6d7adf61cae05ed728f9355492ae3b3 /sys/src/9 | |
parent | 7713145638f45c07c47b9ef8c859d518d88f6127 (diff) |
kernel: xoroshiro128+ generator for rand()/nrand()
the kernels custom rand() and nrand() functions where not working
as specified in rand(2). now we just use libc's rand() and nrand()
functions but provide a custom lrand() impelmenting the xoroshiro128+
algorithm as proposed by aiju.
Diffstat (limited to 'sys/src/9')
-rw-r--r-- | sys/src/9/port/devcons.c | 18 | ||||
-rw-r--r-- | sys/src/9/port/lib.h | 8 | ||||
-rw-r--r-- | sys/src/9/port/portfns.h | 2 | ||||
-rw-r--r-- | sys/src/9/port/random.c | 25 |
4 files changed, 33 insertions, 20 deletions
diff --git a/sys/src/9/port/devcons.c b/sys/src/9/port/devcons.c index 17848aed5..814a6e238 100644 --- a/sys/src/9/port/devcons.c +++ b/sys/src/9/port/devcons.c @@ -845,24 +845,6 @@ Dev consdevtab = { devwstat, }; -static ulong randn; - -int -rand(void) -{ - if(randn == 0) - randomread((void*)&randn, sizeof(randn)); - randn = randn*1103515245 + 12345 + MACHP(0)->ticks; - return randn; -} - -int -nrand(int n) -{ - rand(); - return (randn>>16) % n; -} - static uvlong uvorder = 0x0001020304050607ULL; static uchar* diff --git a/sys/src/9/port/lib.h b/sys/src/9/port/lib.h index 7d58fed9d..e0a17bfee 100644 --- a/sys/src/9/port/lib.h +++ b/sys/src/9/port/lib.h @@ -52,6 +52,14 @@ extern int utflen(char*); extern int utfnlen(char*, long); extern int runelen(long); +/* + * random number + */ +extern int rand(void); +extern int nrand(int); +extern long lrand(void); +extern long lnrand(long); + extern int abs(int); /* diff --git a/sys/src/9/port/portfns.h b/sys/src/9/port/portfns.h index 6f84fc691..eb34dc2dd 100644 --- a/sys/src/9/port/portfns.h +++ b/sys/src/9/port/portfns.h @@ -200,7 +200,6 @@ Rgrp* newrgrp(void); Proc* newproc(void); void nexterror(void); int notify(Ureg*); -int nrand(int); uvlong ns2fastticks(uvlong); int okaddr(uintptr, ulong, int); int openmode(ulong); @@ -284,7 +283,6 @@ void qunlock(QLock*); int qwindow(Queue*); int qwrite(Queue*, void*, int); void qnoblock(Queue*, int); -int rand(void); void randominit(void); ulong randomread(void*, ulong); void rdb(void); diff --git a/sys/src/9/port/random.c b/sys/src/9/port/random.c index d401e7e01..253c89b03 100644 --- a/sys/src/9/port/random.c +++ b/sys/src/9/port/random.c @@ -120,3 +120,28 @@ genrandom(uchar *p, int n) { randomread(p, n); } + +/* used by rand(),nrand() */ +long +lrand(void) +{ + /* xoroshiro128+ algorithm */ + static int seeded = 0; + static uvlong s[2]; + static Lock lk; + ulong r; + + if(seeded == 0){ + randomread(s, sizeof(s)); + seeded = (s[0] | s[1]) != 0; + } + + lock(&lk); + r = (s[0] + s[1]) >> 33; + s[1] ^= s[0]; + s[0] = (s[0] << 55 | s[0] >> 9) ^ s[1] ^ (s[1] << 14); + s[1] = (s[1] << 36 | s[1] >> 28); + unlock(&lk); + + return r; +} |