From 10275ad6dd261b21774848e3d5913807ae293236 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sun, 11 Sep 2016 02:10:25 +0200 Subject: 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. --- sys/src/9/port/devcons.c | 18 ------------------ sys/src/9/port/lib.h | 8 ++++++++ sys/src/9/port/portfns.h | 2 -- 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; +} -- cgit v1.2.3