summaryrefslogtreecommitdiff
path: root/sys/src/9
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2016-09-11 02:10:25 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2016-09-11 02:10:25 +0200
commit10275ad6dd261b21774848e3d5913807ae293236 (patch)
treec86f38c1d6d7adf61cae05ed728f9355492ae3b3 /sys/src/9
parent7713145638f45c07c47b9ef8c859d518d88f6127 (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.c18
-rw-r--r--sys/src/9/port/lib.h8
-rw-r--r--sys/src/9/port/portfns.h2
-rw-r--r--sys/src/9/port/random.c25
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;
+}