~ chicken-core (chicken-5) ef8c7d136487418159c706b30a46453baa4abf0a
commit ef8c7d136487418159c706b30a46453baa4abf0a
Author: felix <felix@call-with-current-continuation.org>
AuthorDate: Sat Nov 4 12:40:20 2017 +0100
Commit: felix <felix@call-with-current-continuation.org>
CommitDate: Sat Nov 4 12:40:20 2017 +0100
use direct syscall for getrandom(2), obtain uniformity via loop
diff --git a/runtime.c b/runtime.c
index df42986f..ffb526b4 100644
--- a/runtime.c
+++ b/runtime.c
@@ -12554,7 +12554,7 @@ C_word C_random_bytes(C_word buf, C_word size)
arc4random_buf(C_data_pointer(buf), count);
#elif defined(SYS_getrandom) && defined(__NR_getrandom)
while(count > 0) {
- r = getrandom(C_data_pointer(buf) + off, count, GRND_NONBLOCK);
+ r = syscall(SYS_getrandom, C_data_pointer(buf) + off, count, GRND_NONBLOCK);
if(r == -1) {
if(errno != EINTR) return C_SCHEME_FALSE;
@@ -12594,14 +12594,21 @@ C_word C_random_bytes(C_word buf, C_word size)
}
+#ifdef C_SIXTYFOUR
+# define rand_uint C_u32
+#else
+# define rand_uint C_u64
+#endif
+
+
/* WELL512 pseudo random number generator, see also:
https://en.wikipedia.org/wiki/Well_equidistributed_long-period_linear
http://lomont.org/Math/Papers/2008/Lomont_PRNG_2008.pdf
*/
-static C_u32 random_word(void)
+static rand_uint random_word(void)
{
- C_u32 a, b, c, d, r;
+ rand_uint a, b, c, d, r;
a = random_state[random_state_index];
c = random_state[(random_state_index+13)&15];
b = a^c^(a<<16)^(c<<15);
@@ -12615,11 +12622,21 @@ static C_u32 random_word(void)
r = random_state[random_state_index];
return r;
}
-
+
+
+static rand_uint random_uniform(rand_uint bound)
+{
+ rand_uint r;
+
+ do { r = random_word(); } while(r >= bound);
+
+ return r;
+}
+
C_regparm C_word C_random_fixnum(C_word n)
{
- C_u32 r = random_word();
+ rand_uint r;
C_word nf;
if (!(n & C_FIXNUM_BIT))
@@ -12630,7 +12647,7 @@ C_regparm C_word C_random_fixnum(C_word n)
if(nf < 0)
barf(C_OUT_OF_RANGE_ERROR, "pseudo-random-integer", n, C_fix(0));
- return C_fix(((double)r / 0xffffffffUL) * C_unfix(n));
+ return C_fix(random_uniform(nf));
}
@@ -12655,7 +12672,7 @@ C_s_a_u_i_random_int(C_word **ptr, C_word n, C_word rn)
len -= sizeof(C_u32);
}
- *end = random_word() >> len;
+ *end = random_word() >> len; /* XXX is this right? uniform? */
return C_bignum_simplify(result);
}
Trap