Remove the C(++) ISAAC Rng from the old rt.
This has to leave rust_gen_seed and rng_gen_seed around since they're used to initialise the std::rand RNGs.
This commit is contained in:
parent
fb923c7d3f
commit
0951313c1e
1
mk/rt.mk
1
mk/rt.mk
|
@ -74,7 +74,6 @@ RUNTIME_CXXS_$(1)_$(2) := \
|
|||
rt/rust_rng.cpp \
|
||||
rt/rust_upcall.cpp \
|
||||
rt/rust_uv.cpp \
|
||||
rt/isaac/randport.cpp \
|
||||
rt/miniz.cpp \
|
||||
rt/memory_region.cpp \
|
||||
rt/boxed_region.cpp \
|
||||
|
|
|
@ -242,7 +242,6 @@ pub mod rustrt {
|
|||
use libc::size_t;
|
||||
|
||||
extern {
|
||||
pub fn rand_seed_size() -> size_t;
|
||||
pub fn rand_gen_seed(buf: *mut u8, sz: size_t);
|
||||
}
|
||||
}
|
||||
|
@ -822,8 +821,8 @@ pub fn seed() -> ~[u8] {
|
|||
#[fixed_stack_segment]; #[inline(never)];
|
||||
|
||||
unsafe {
|
||||
let n = rustrt::rand_seed_size() as uint;
|
||||
let mut s = vec::from_elem(n, 0_u8);
|
||||
let n = RAND_SIZE * 4;
|
||||
let mut s = vec::from_elem(n as uint, 0_u8);
|
||||
do s.as_mut_buf |p, sz| {
|
||||
rustrt::rand_gen_seed(p, sz as size_t)
|
||||
}
|
||||
|
@ -1053,46 +1052,6 @@ mod test {
|
|||
(f32, (f64, (float,)))) = random();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compare_isaac_implementation() {
|
||||
#[fixed_stack_segment]; #[inline(never)];
|
||||
|
||||
// This is to verify that the implementation of the ISAAC rng is
|
||||
// correct (i.e. matches the output of the upstream implementation,
|
||||
// which is in the runtime)
|
||||
use libc::size_t;
|
||||
|
||||
#[abi = "cdecl"]
|
||||
mod rustrt {
|
||||
use libc::size_t;
|
||||
|
||||
#[allow(non_camel_case_types)] // runtime type
|
||||
pub enum rust_rng {}
|
||||
|
||||
extern {
|
||||
pub fn rand_new_seeded(buf: *u8, sz: size_t) -> *rust_rng;
|
||||
pub fn rand_next(rng: *rust_rng) -> u32;
|
||||
pub fn rand_free(rng: *rust_rng);
|
||||
}
|
||||
}
|
||||
|
||||
// run against several seeds
|
||||
do 10.times {
|
||||
unsafe {
|
||||
let seed = super::seed();
|
||||
let rt_rng = do seed.as_imm_buf |p, sz| {
|
||||
rustrt::rand_new_seeded(p, sz as size_t)
|
||||
};
|
||||
let mut rng = IsaacRng::new_seeded(seed);
|
||||
|
||||
do 10000.times {
|
||||
assert_eq!(rng.next(), rustrt::rand_next(rt_rng));
|
||||
}
|
||||
rustrt::rand_free(rt_rng);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sample() {
|
||||
let MIN_VAL = 1;
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
------------------------------------------------------------------------------
|
||||
rand.h: definitions for a random number generator
|
||||
By Bob Jenkins, 1996, Public Domain
|
||||
MODIFIED:
|
||||
960327: Creation (addition of randinit, really)
|
||||
970719: use context, not global variables, for internal state
|
||||
980324: renamed seed to flag
|
||||
980605: recommend RANDSIZL=4 for noncryptography.
|
||||
010626: note this is public domain
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef STANDARD
|
||||
#include "standard.h"
|
||||
#endif
|
||||
|
||||
#ifndef RAND
|
||||
#define RAND
|
||||
#define RANDSIZL (8) /* I recommend 8 for crypto, 4 for simulations */
|
||||
#define RANDSIZ (1<<RANDSIZL)
|
||||
|
||||
/* context of random number generator */
|
||||
struct randctx
|
||||
{
|
||||
ub4 randcnt;
|
||||
ub4 randrsl[RANDSIZ];
|
||||
ub4 randmem[RANDSIZ];
|
||||
ub4 randa;
|
||||
ub4 randb;
|
||||
ub4 randc;
|
||||
};
|
||||
typedef struct randctx randctx;
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
If (flag==TRUE), then use the contents of randrsl[0..RANDSIZ-1] as the seed.
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
void randinit(randctx *r, word flag);
|
||||
|
||||
void isaac(randctx *r);
|
||||
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Call isaac_rand(/o_ randctx *r _o/) to retrieve a single 32-bit random value
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
#define isaac_rand(r) \
|
||||
(!(r)->randcnt-- ? \
|
||||
(isaac(r), (r)->randcnt=RANDSIZ-1, (r)->randrsl[(r)->randcnt]) : \
|
||||
(r)->randrsl[(r)->randcnt])
|
||||
|
||||
#endif /* RAND */
|
|
@ -1,139 +0,0 @@
|
|||
/*
|
||||
------------------------------------------------------------------------------
|
||||
rand.c: By Bob Jenkins. My random number generator, ISAAC. Public Domain
|
||||
MODIFIED:
|
||||
960327: Creation (addition of randinit, really)
|
||||
970719: use context, not global variables, for internal state
|
||||
980324: make a portable version
|
||||
010626: Note this is public domain
|
||||
100725: Mask on use of >32 bits, not on assignment: from Paul Eggert
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef STANDARD
|
||||
#include "standard.h"
|
||||
#endif
|
||||
#ifndef RAND
|
||||
#include "rand.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define ind(mm,x) ((mm)[(x>>2)&(RANDSIZ-1)])
|
||||
#define rngstep(mix,a,b,mm,m,m2,r,x) \
|
||||
{ \
|
||||
x = *m; \
|
||||
a = ((a^(mix)) + *(m2++)) & 0xffffffff; \
|
||||
*(m++) = y = (ind(mm,x) + a + b) & 0xffffffff; \
|
||||
*(r++) = b = (ind(mm,y>>RANDSIZL) + x) & 0xffffffff; \
|
||||
}
|
||||
|
||||
void isaac(randctx *ctx)
|
||||
{
|
||||
ub4 a,b,x,y,*m,*mm,*m2,*r,*mend;
|
||||
mm=ctx->randmem; r=ctx->randrsl;
|
||||
a = ctx->randa; b = ctx->randb + (++ctx->randc);
|
||||
for (m = mm, mend = m2 = m+(RANDSIZ/2); m<mend; )
|
||||
{
|
||||
rngstep( a<<13, a, b, mm, m, m2, r, x);
|
||||
rngstep( (a & 0xffffffff) >>6 , a, b, mm, m, m2, r, x);
|
||||
rngstep( a<<2 , a, b, mm, m, m2, r, x);
|
||||
rngstep( (a & 0xffffffff) >>16, a, b, mm, m, m2, r, x);
|
||||
}
|
||||
for (m2 = mm; m2<mend; )
|
||||
{
|
||||
rngstep( a<<13, a, b, mm, m, m2, r, x);
|
||||
rngstep( (a & 0xffffffff) >>6 , a, b, mm, m, m2, r, x);
|
||||
rngstep( a<<2 , a, b, mm, m, m2, r, x);
|
||||
rngstep( (a & 0xffffffff) >>16, a, b, mm, m, m2, r, x);
|
||||
}
|
||||
ctx->randb = b; ctx->randa = a;
|
||||
}
|
||||
|
||||
|
||||
#define mix(a,b,c,d,e,f,g,h) \
|
||||
{ \
|
||||
a^=b<<11; d+=a; b+=c; \
|
||||
b^=(c&0xffffffff)>>2; e+=b; c+=d; \
|
||||
c^=d<<8; f+=c; d+=e; \
|
||||
d^=(e&0xffffffff)>>16; g+=d; e+=f; \
|
||||
e^=f<<10; h+=e; f+=g; \
|
||||
f^=(g&0xffffffff)>>4; a+=f; g+=h; \
|
||||
g^=h<<8; b+=g; h+=a; \
|
||||
h^=(a&0xffffffff)>>9; c+=h; a+=b; \
|
||||
}
|
||||
|
||||
/* if (flag==TRUE), then use the contents of randrsl[] to initialize mm[]. */
|
||||
void randinit(randctx *ctx, word flag)
|
||||
{
|
||||
word i;
|
||||
ub4 a,b,c,d,e,f,g,h;
|
||||
ub4 *m,*r;
|
||||
ctx->randa = ctx->randb = ctx->randc = 0;
|
||||
m=ctx->randmem;
|
||||
r=ctx->randrsl;
|
||||
a=b=c=d=e=f=g=h=0x9e3779b9; /* the golden ratio */
|
||||
|
||||
for (i=0; i<4; ++i) /* scramble it */
|
||||
{
|
||||
mix(a,b,c,d,e,f,g,h);
|
||||
}
|
||||
|
||||
if (flag)
|
||||
{
|
||||
/* initialize using the contents of r[] as the seed */
|
||||
for (i=0; i<RANDSIZ; i+=8)
|
||||
{
|
||||
a+=r[i ]; b+=r[i+1];
|
||||
c+=r[i+2]; d+=r[i+3];
|
||||
e+=r[i+4]; f+=r[i+5];
|
||||
g+=r[i+6]; h+=r[i+7];
|
||||
mix(a,b,c,d,e,f,g,h);
|
||||
m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
|
||||
m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
|
||||
}
|
||||
/* do a second pass to make all of the seed affect all of m */
|
||||
for (i=0; i<RANDSIZ; i+=8)
|
||||
{
|
||||
a+=m[i ]; b+=m[i+1];
|
||||
c+=m[i+2]; d+=m[i+3];
|
||||
e+=m[i+4]; f+=m[i+5];
|
||||
g+=m[i+6]; h+=m[i+7];
|
||||
mix(a,b,c,d,e,f,g,h);
|
||||
m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
|
||||
m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i<RANDSIZ; i+=8)
|
||||
{
|
||||
/* fill in mm[] with messy stuff */
|
||||
mix(a,b,c,d,e,f,g,h);
|
||||
m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
|
||||
m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
|
||||
}
|
||||
}
|
||||
|
||||
isaac(ctx); /* fill in the first set of results */
|
||||
ctx->randcnt=RANDSIZ; /* prepare to use the first set of results */
|
||||
}
|
||||
|
||||
|
||||
#ifdef NEVER
|
||||
int main()
|
||||
{
|
||||
ub4 i,j;
|
||||
randctx ctx;
|
||||
ctx.randa=ctx.randb=ctx.randc=(ub4)0;
|
||||
for (i=0; i<256; ++i) ctx.randrsl[i]=(ub4)0;
|
||||
randinit(&ctx, TRUE);
|
||||
for (i=0; i<2; ++i)
|
||||
{
|
||||
isaac(&ctx);
|
||||
for (j=0; j<256; ++j)
|
||||
{
|
||||
printf("%.8lx",ctx.randrsl[j]);
|
||||
if ((j&7)==7) printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Standard definitions and types, Bob Jenkins
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef STANDARD
|
||||
# define STANDARD
|
||||
# ifndef STDIO
|
||||
# include <stdio.h>
|
||||
# define STDIO
|
||||
# endif
|
||||
# ifndef STDDEF
|
||||
# include <stddef.h>
|
||||
# define STDDEF
|
||||
# endif
|
||||
# ifndef STDINT
|
||||
# include <stdint.h>
|
||||
# define STDINT
|
||||
# endif
|
||||
|
||||
typedef uint64_t ub8;
|
||||
#define UB8MAXVAL 0xffffffffffffffffLL
|
||||
#define UB8BITS 64
|
||||
typedef int64_t sb8;
|
||||
#define SB8MAXVAL 0x7fffffffffffffffLL
|
||||
typedef uint32_t ub4; /* unsigned 4-byte quantities */
|
||||
#define UB4MAXVAL 0xffffffff
|
||||
typedef int32_t sb4;
|
||||
#define UB4BITS 32
|
||||
#define SB4MAXVAL 0x7fffffff
|
||||
typedef uint16_t ub2;
|
||||
#define UB2MAXVAL 0xffff
|
||||
#define UB2BITS 16
|
||||
typedef int16_t sb2;
|
||||
#define SB2MAXVAL 0x7fff
|
||||
typedef uint8_t ub1;
|
||||
#define UB1MAXVAL 0xff
|
||||
#define UB1BITS 8
|
||||
typedef int8_t sb1; /* signed 1-byte quantities */
|
||||
#define SB1MAXVAL 0x7f
|
||||
typedef int word; /* fastest type available */
|
||||
|
||||
#define bis(target,mask) ((target) |= (mask))
|
||||
#define bic(target,mask) ((target) &= ~(mask))
|
||||
#define bit(target,mask) ((target) & (mask))
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define SUCCESS 0 /* 1 on VAX */
|
||||
|
||||
#endif /* STANDARD */
|
|
@ -69,35 +69,11 @@ rust_env_pairs() {
|
|||
}
|
||||
#endif
|
||||
|
||||
extern "C" CDECL size_t
|
||||
rand_seed_size() {
|
||||
return rng_seed_size();
|
||||
}
|
||||
|
||||
extern "C" CDECL void
|
||||
rand_gen_seed(uint8_t* dest, size_t size) {
|
||||
rng_gen_seed(dest, size);
|
||||
}
|
||||
|
||||
extern "C" CDECL void *
|
||||
rand_new_seeded(uint8_t* seed, size_t seed_size) {
|
||||
assert(seed != NULL);
|
||||
rust_rng *rng = (rust_rng *) malloc(sizeof(rust_rng));
|
||||
assert(rng != NULL && "rng alloc failed");
|
||||
rng_init(rng, NULL, seed, seed_size);
|
||||
return rng;
|
||||
}
|
||||
|
||||
extern "C" CDECL uint32_t
|
||||
rand_next(rust_rng *rng) {
|
||||
return rng_gen_u32(rng);
|
||||
}
|
||||
|
||||
extern "C" CDECL void
|
||||
rand_free(rust_rng *rng) {
|
||||
free(rng);
|
||||
}
|
||||
|
||||
extern "C" CDECL char*
|
||||
#if defined(__WIN32__)
|
||||
rust_list_dir_val(WIN32_FIND_DATA* entry_ptr) {
|
||||
|
|
|
@ -32,14 +32,6 @@ win32_require(LPCTSTR fn, BOOL ok) {
|
|||
}
|
||||
#endif
|
||||
|
||||
size_t
|
||||
rng_seed_size() {
|
||||
randctx rctx;
|
||||
return sizeof(rctx.randrsl);
|
||||
}
|
||||
|
||||
// Initialization helpers for ISAAC RNG
|
||||
|
||||
void
|
||||
rng_gen_seed(uint8_t* dest, size_t size) {
|
||||
#ifdef __WIN32__
|
||||
|
@ -80,59 +72,6 @@ rng_gen_seed(uint8_t* dest, size_t size) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
isaac_init(randctx *rctx, char *env_seed,
|
||||
uint8_t* user_seed, size_t seed_len) {
|
||||
memset(rctx, 0, sizeof(randctx));
|
||||
|
||||
if (user_seed != NULL) {
|
||||
// ignore bytes after the required length
|
||||
if (seed_len > sizeof(rctx->randrsl)) {
|
||||
seed_len = sizeof(rctx->randrsl);
|
||||
}
|
||||
memcpy(&rctx->randrsl, user_seed, seed_len);
|
||||
} else if (env_seed != NULL) {
|
||||
ub4 seed = (ub4) atoi(env_seed);
|
||||
for (size_t i = 0; i < RANDSIZ; i ++) {
|
||||
memcpy(&rctx->randrsl[i], &seed, sizeof(ub4));
|
||||
seed = (seed + 0x7ed55d16) + (seed << 12);
|
||||
}
|
||||
} else {
|
||||
rng_gen_seed((uint8_t*)&rctx->randrsl,
|
||||
sizeof(rctx->randrsl));
|
||||
}
|
||||
|
||||
randinit(rctx, 1);
|
||||
}
|
||||
|
||||
void
|
||||
rng_init(rust_rng* rng, char* env_seed,
|
||||
uint8_t *user_seed, size_t seed_len) {
|
||||
isaac_init(&rng->rctx, env_seed, user_seed, seed_len);
|
||||
rng->reseedable = !user_seed && !env_seed;
|
||||
}
|
||||
|
||||
static void
|
||||
rng_maybe_reseed(rust_rng* rng) {
|
||||
// If this RNG has generated more than 32KB of random data and was not
|
||||
// seeded by the user or RUST_SEED, then we should reseed now.
|
||||
const size_t RESEED_THRESHOLD = 32 * 1024;
|
||||
size_t bytes_generated = rng->rctx.randc * sizeof(ub4);
|
||||
if (bytes_generated < RESEED_THRESHOLD || !rng->reseedable) {
|
||||
return;
|
||||
}
|
||||
rng_gen_seed((uint8_t*)rng->rctx.randrsl,
|
||||
sizeof(rng->rctx.randrsl));
|
||||
randinit(&rng->rctx, 1);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
rng_gen_u32(rust_rng* rng) {
|
||||
uint32_t x = isaac_rand(&rng->rctx);
|
||||
rng_maybe_reseed(rng);
|
||||
return x;
|
||||
}
|
||||
|
||||
//
|
||||
// Local Variables:
|
||||
// mode: C++
|
||||
|
|
|
@ -11,22 +11,7 @@
|
|||
#ifndef RUST_RNG_H
|
||||
#define RUST_RNG_H
|
||||
|
||||
#include "rand.h"
|
||||
|
||||
class rust_kernel;
|
||||
|
||||
// Initialization helpers for ISAAC RNG
|
||||
|
||||
struct rust_rng {
|
||||
randctx rctx;
|
||||
bool reseedable;
|
||||
};
|
||||
|
||||
size_t rng_seed_size();
|
||||
void rng_gen_seed(uint8_t* dest, size_t size);
|
||||
void rng_init(rust_rng *rng, char *env_seed,
|
||||
uint8_t *user_seed, size_t seed_len);
|
||||
uint32_t rng_gen_u32(rust_rng *rng);
|
||||
|
||||
//
|
||||
// Local Variables:
|
||||
|
|
|
@ -9,11 +9,7 @@ rust_localtime
|
|||
rust_timegm
|
||||
rust_mktime
|
||||
precise_time_ns
|
||||
rand_free
|
||||
rand_new_seeded
|
||||
rand_seed_size
|
||||
rand_gen_seed
|
||||
rand_next
|
||||
rust_path_is_dir
|
||||
rust_path_exists
|
||||
rust_get_stdin
|
||||
|
|
Loading…
Reference in New Issue