]> git.lizzy.rs Git - plan9front.git/commitdiff
kernel: xoroshiro128+ generator for rand()/nrand()
authorcinap_lenrek <cinap_lenrek@felloff.net>
Sun, 11 Sep 2016 00:10:25 +0000 (02:10 +0200)
committercinap_lenrek <cinap_lenrek@felloff.net>
Sun, 11 Sep 2016 00:10:25 +0000 (02:10 +0200)
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
sys/src/9/port/lib.h
sys/src/9/port/portfns.h
sys/src/9/port/random.c

index 17848aed56d5d42f3893cd8bcf200e89602be255..814a6e238914c38d6ed0ab11425dfd1331f28ae1 100644 (file)
@@ -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*
index 7d58fed9de661f3e81b8a4bea30dea104b9923a2..e0a17bfee1991867c923cd8befed79d8d93bbec5 100644 (file)
@@ -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);
 
 /*
index 6f84fc6917d045b2f610737cde3d0089436c7f12..eb34dc2dd6a54b0edb442381fb10c4142f5eedb2 100644 (file)
@@ -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);
index d401e7e0181eccbe1f7a58b099cdbb64402f2c7c..253c89b031cda51eace685e5dcb31341e46dc1d8 100644 (file)
@@ -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;
+}