First step at speeding up io_u rand refill

Makes it 3x faster here.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
diff --git a/Makefile b/Makefile
index 12042f4..837f421 100644
--- a/Makefile
+++ b/Makefile
@@ -9,6 +9,8 @@
 	rbtree.o diskutil.o fifo.o blktrace.o smalloc.o filehash.o helpers.o \
 	cgroup.o profile.o debug.o
 
+OBJS += lib/rand.o
+
 OBJS += crc/crc7.o
 OBJS += crc/crc16.o
 OBJS += crc/crc32.o
diff --git a/Makefile.FreeBSD b/Makefile.FreeBSD
index deae03d..3c59a99 100644
--- a/Makefile.FreeBSD
+++ b/Makefile.FreeBSD
@@ -8,6 +8,8 @@
 	eta.o verify.o memory.o io_u.o parse.o mutex.o options.o \
 	rbtree.o smalloc.o filehash.o helpers.o profile.o debug.o
 
+OBJS += lib/rand.o
+
 OBJS += crc/crc7.o
 OBJS += crc/crc16.o
 OBJS += crc/crc32.o
diff --git a/Makefile.mac b/Makefile.mac
index a726546..fe84297 100644
--- a/Makefile.mac
+++ b/Makefile.mac
@@ -8,6 +8,8 @@
 	eta.o verify.o memory.o io_u.o parse.o mutex.o options.o \
 	rbtree.o smalloc.o filehash.o helpers.o profile.o debug.o
 
+OBJS += lib/rand.o
+
 OBJS += crc/crc7.o
 OBJS += crc/crc16.o
 OBJS += crc/crc32.o
diff --git a/Makefile.solaris b/Makefile.solaris
index 0ec6d73..49a4ef9 100644
--- a/Makefile.solaris
+++ b/Makefile.solaris
@@ -7,6 +7,8 @@
 	rbtree.o fifo.o smalloc.o filehash.o lib/strsep.o helpers.o solaris.o \
 	profile.o debug.o
 
+OBJS += lib/rand.o
+
 OBJS += crc/crc7.o
 OBJS += crc/crc16.o
 OBJS += crc/crc32.o
diff --git a/io_u.c b/io_u.c
index afc90de..4d3116b 100644
--- a/io_u.c
+++ b/io_u.c
@@ -8,6 +8,7 @@
 #include "fio.h"
 #include "hash.h"
 #include "verify.h"
+#include "lib/rand.h"
 
 struct io_completion_data {
 	int nr;				/* input */
@@ -1217,7 +1218,7 @@
 
 	if (!td->o.zero_buffers) {
 		while ((void *) ptr - io_u->buf < max_bs) {
-			*ptr = rand() * GOLDEN_RATIO_PRIME;
+			*ptr = __rand(&__fio_rand_state);
 			ptr++;
 		}
 	} else
diff --git a/lib/rand.c b/lib/rand.c
new file mode 100644
index 0000000..b8d8f78
--- /dev/null
+++ b/lib/rand.c
@@ -0,0 +1,24 @@
+#include "rand.h"
+
+struct frand_state __fio_rand_state;
+
+static inline int __seed(unsigned int x, unsigned int m)
+{
+	return (x < m) ? x + m : x;
+}
+
+void init_rand(struct frand_state *state)
+{
+#define LCG(x)  ((x) * 69069)   /* super-duper LCG */
+
+	state->s1 = __seed(LCG((2^31) + (2^17) + (2^7)), 1);
+	state->s2 = __seed(LCG(state->s1), 7);
+	state->s3 = __seed(LCG(state->s2), 15);
+
+	__rand(state);
+	__rand(state);
+	__rand(state);
+	__rand(state);
+	__rand(state);
+	__rand(state);
+}
diff --git a/lib/rand.h b/lib/rand.h
new file mode 100644
index 0000000..363e7b6
--- /dev/null
+++ b/lib/rand.h
@@ -0,0 +1,23 @@
+#ifndef FIO_RAND_H
+#define FIO_RAND_H
+
+struct frand_state {
+	unsigned int s1, s2, s3;
+};
+
+extern struct frand_state __fio_rand_state;
+
+static inline unsigned int __rand(struct frand_state *state)
+{
+#define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b)
+
+	state->s1 = TAUSWORTHE(state->s1, 13, 19, 4294967294UL, 12);
+	state->s2 = TAUSWORTHE(state->s2, 2, 25, 4294967288UL, 4);
+	state->s3 = TAUSWORTHE(state->s3, 3, 11, 4294967280UL, 17);
+
+	return (state->s1 ^ state->s2 ^ state->s3);
+}
+
+extern void init_rand(struct frand_state *);
+
+#endif