Skip to content

Commit

Permalink
reseed rust_rng after generating 32KB
Browse files Browse the repository at this point in the history
  • Loading branch information
cpeterso committed Feb 15, 2013
1 parent 665e900 commit 9a78dc9
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 5 deletions.
3 changes: 2 additions & 1 deletion src/rt/rust_builtin.cpp
Expand Up @@ -173,7 +173,8 @@ rand_new_seeded2(rust_vec_box** seed) {

extern "C" CDECL uint32_t
rand_next(rust_rng *rng) {
return rng_gen_u32(rng);
rust_task *task = rust_get_current_task();
return rng_gen_u32(task->kernel, rng);
}

extern "C" CDECL void
Expand Down
28 changes: 26 additions & 2 deletions src/rt/rust_rng.cpp
Expand Up @@ -73,11 +73,35 @@ isaac_init(rust_kernel *kernel, randctx *rctx, rust_vec_box* user_seed) {
void
rng_init(rust_kernel* kernel, rust_rng* rng, rust_vec_box* user_seed) {
isaac_init(kernel, &rng->rctx, user_seed);
rng->reseedable = !user_seed && !kernel->env->rust_seed;
}

static void
rng_maybe_reseed(rust_kernel* kernel, 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;
}

uint32_t new_seed[RANDSIZ];
rng_gen_seed(kernel, (uint8_t*) new_seed, RANDSIZ * sizeof(uint32_t));

// Stir new seed into PRNG's entropy pool.
for (size_t i = 0; i < RANDSIZ; i++) {
rng->rctx.randrsl[i] ^= new_seed[i];
}

randinit(&rng->rctx, 1);
}

uint32_t
rng_gen_u32(rust_rng* rng) {
return isaac_rand(&rng->rctx);
rng_gen_u32(rust_kernel* kernel, rust_rng* rng) {
uint32_t x = isaac_rand(&rng->rctx);
rng_maybe_reseed(kernel, rng);
return x;
}

//
Expand Down
3 changes: 2 additions & 1 deletion src/rt/rust_rng.h
Expand Up @@ -20,11 +20,12 @@ struct rust_vec_box;

struct rust_rng {
randctx rctx;
bool reseedable;
};

void rng_gen_seed(rust_kernel* kernel, uint8_t* dest, size_t size);
void rng_init(rust_kernel *kernel, rust_rng *rng, rust_vec_box* user_seed);
uint32_t rng_gen_u32(rust_rng *rng);
uint32_t rng_gen_u32(rust_kernel *kernel, rust_rng *rng);

//
// Local Variables:
Expand Down
2 changes: 1 addition & 1 deletion src/rt/rust_sched_loop.cpp
Expand Up @@ -151,7 +151,7 @@ rust_task *
rust_sched_loop::schedule_task() {
lock.must_have_lock();
if (running_tasks.length() > 0) {
size_t k = rng_gen_u32(&rng);
size_t k = rng_gen_u32(kernel, &rng);
size_t i = k % running_tasks.length();
return (rust_task *)running_tasks[i];
}
Expand Down

0 comments on commit 9a78dc9

Please sign in to comment.