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:
Huon Wilson 2013-09-22 21:57:31 +10:00
parent fb923c7d3f
commit 0951313c1e
9 changed files with 2 additions and 391 deletions

View File

@ -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 \

View File

@ -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;

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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) {

View File

@ -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++

View File

@ -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:

View File

@ -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