encapsulate isaac RNG in rust_rng struct

This commit is contained in:
Chris Peterson 2013-02-14 00:48:40 -08:00
parent f4320b6195
commit 665e900ede
6 changed files with 47 additions and 33 deletions

View File

@ -116,15 +116,15 @@ impl<T: Rand> Rand for Option<T> {
}
#[allow(non_camel_case_types)] // runtime type
enum rctx {}
enum rust_rng {}
#[abi = "cdecl"]
extern mod rustrt {
unsafe fn rand_seed() -> ~[u8];
unsafe fn rand_new() -> *rctx;
unsafe fn rand_new_seeded2(&&seed: ~[u8]) -> *rctx;
unsafe fn rand_next(c: *rctx) -> u32;
unsafe fn rand_free(c: *rctx);
unsafe fn rand_new() -> *rust_rng;
unsafe fn rand_new_seeded2(&&seed: ~[u8]) -> *rust_rng;
unsafe fn rand_next(rng: *rust_rng) -> u32;
unsafe fn rand_free(rng: *rust_rng);
}
/// A random number generator
@ -363,24 +363,24 @@ impl Rng {
}
struct RandRes {
c: *rctx,
rng: *rust_rng,
drop {
unsafe {
rustrt::rand_free(self.c);
rustrt::rand_free(self.rng);
}
}
}
fn RandRes(c: *rctx) -> RandRes {
fn RandRes(rng: *rust_rng) -> RandRes {
RandRes {
c: c
rng: rng
}
}
impl Rng for @RandRes {
fn next() -> u32 {
unsafe {
return rustrt::rand_next((*self).c);
return rustrt::rand_next((*self).rng);
}
}
}

View File

@ -135,7 +135,7 @@ rand_seed() {
rust_vec *v = (rust_vec *) task->kernel->malloc(vec_size<uint8_t>(size),
"rand_seed");
v->fill = v->alloc = size;
isaac_seed(task->kernel, (uint8_t*) &v->data, size);
rng_gen_seed(task->kernel, (uint8_t*) &v->data, size);
return v;
}
@ -143,27 +143,27 @@ extern "C" CDECL void *
rand_new() {
rust_task *task = rust_get_current_task();
rust_sched_loop *thread = task->sched_loop;
randctx *rctx = (randctx *) task->malloc(sizeof(randctx), "rand_new");
if (!rctx) {
rust_rng *rng = (rust_rng *) task->malloc(sizeof(rust_rng), "rand_new");
if (!rng) {
task->fail();
return NULL;
}
isaac_init(thread->kernel, rctx, NULL);
return rctx;
rng_init(thread->kernel, rng, NULL);
return rng;
}
extern "C" CDECL void *
rand_new_seeded(rust_vec_box* seed) {
rust_task *task = rust_get_current_task();
rust_sched_loop *thread = task->sched_loop;
randctx *rctx = (randctx *) task->malloc(sizeof(randctx),
"rand_new_seeded");
if (!rctx) {
rust_rng *rng = (rust_rng *) task->malloc(sizeof(rust_rng),
"rand_new_seeded");
if (!rng) {
task->fail();
return NULL;
}
isaac_init(thread->kernel, rctx, seed);
return rctx;
rng_init(thread->kernel, rng, seed);
return rng;
}
extern "C" CDECL void *
@ -172,14 +172,14 @@ rand_new_seeded2(rust_vec_box** seed) {
}
extern "C" CDECL uint32_t
rand_next(randctx *rctx) {
return isaac_rand(rctx);
rand_next(rust_rng *rng) {
return rng_gen_u32(rng);
}
extern "C" CDECL void
rand_free(randctx *rctx) {
rand_free(rust_rng *rng) {
rust_task *task = rust_get_current_task();
task->free(rctx);
task->free(rng);
}

View File

@ -15,7 +15,7 @@
// Initialization helpers for ISAAC RNG
void
isaac_seed(rust_kernel* kernel, uint8_t* dest, size_t size) {
rng_gen_seed(rust_kernel* kernel, uint8_t* dest, size_t size) {
#ifdef __WIN32__
HCRYPTPROV hProv;
kernel->win32_require
@ -47,7 +47,7 @@ isaac_seed(rust_kernel* kernel, uint8_t* dest, size_t size) {
#endif
}
void
static void
isaac_init(rust_kernel *kernel, randctx *rctx, rust_vec_box* user_seed) {
memset(rctx, 0, sizeof(randctx));
@ -64,12 +64,22 @@ isaac_init(rust_kernel *kernel, randctx *rctx, rust_vec_box* user_seed) {
seed = (seed + 0x7ed55d16) + (seed << 12);
}
} else {
isaac_seed(kernel, (uint8_t*) &rctx->randrsl, sizeof(rctx->randrsl));
rng_gen_seed(kernel, (uint8_t*)&rctx->randrsl, sizeof(rctx->randrsl));
}
randinit(rctx, 1);
}
void
rng_init(rust_kernel* kernel, rust_rng* rng, rust_vec_box* user_seed) {
isaac_init(kernel, &rng->rctx, user_seed);
}
uint32_t
rng_gen_u32(rust_rng* rng) {
return isaac_rand(&rng->rctx);
}
//
// Local Variables:
// mode: C++

View File

@ -18,8 +18,13 @@ struct rust_vec_box;
// Initialization helpers for ISAAC RNG
void isaac_seed(rust_kernel* kernel, uint8_t* dest, size_t size);
void isaac_init(rust_kernel *kernel, randctx *rctx, rust_vec_box* user_seed);
struct rust_rng {
randctx rctx;
};
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);
//
// Local Variables:

View File

@ -41,7 +41,7 @@ rust_sched_loop::rust_sched_loop(rust_scheduler *sched, int id, bool killed) :
name("main")
{
LOGPTR(this, "new dom", (uintptr_t)this);
isaac_init(kernel, &rctx, NULL);
rng_init(kernel, &rng, NULL);
if (!tls_initialized)
init_tls();
@ -151,7 +151,7 @@ rust_task *
rust_sched_loop::schedule_task() {
lock.must_have_lock();
if (running_tasks.length() > 0) {
size_t k = isaac_rand(&rctx);
size_t k = rng_gen_u32(&rng);
size_t i = k % running_tasks.length();
return (rust_task *)running_tasks[i];
}

View File

@ -62,7 +62,7 @@ private:
#endif
context c_context;
rust_rng rng;
bool should_exit;
stk_seg *cached_c_stack;
@ -103,7 +103,6 @@ public:
size_t min_stack_size;
memory_region local_region;
randctx rctx;
const char *const name; // Used for debugging
// Only a pointer to 'name' is kept, so it must live as long as this