shithub: riscv

Download patch

ref: 10275ad6dd261b21774848e3d5913807ae293236
parent: 7713145638f45c07c47b9ef8c859d518d88f6127
author: cinap_lenrek <[email protected]>
date: Sat Sep 10 22:10:25 EDT 2016

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.

--- a/sys/src/9/port/devcons.c
+++ b/sys/src/9/port/devcons.c
@@ -845,24 +845,6 @@
 	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*
--- a/sys/src/9/port/lib.h
+++ b/sys/src/9/port/lib.h
@@ -52,6 +52,14 @@
 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);
 
 /*
--- a/sys/src/9/port/portfns.h
+++ b/sys/src/9/port/portfns.h
@@ -200,7 +200,6 @@
 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 @@
 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);
--- a/sys/src/9/port/random.c
+++ b/sys/src/9/port/random.c
@@ -120,3 +120,28 @@
 {
 	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;
+}