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 #[allow(non_camel_case_types)] // runtime type
enum rctx {} enum rust_rng {}
#[abi = "cdecl"] #[abi = "cdecl"]
extern mod rustrt { extern mod rustrt {
unsafe fn rand_seed() -> ~[u8]; unsafe fn rand_seed() -> ~[u8];
unsafe fn rand_new() -> *rctx; unsafe fn rand_new() -> *rust_rng;
unsafe fn rand_new_seeded2(&&seed: ~[u8]) -> *rctx; unsafe fn rand_new_seeded2(&&seed: ~[u8]) -> *rust_rng;
unsafe fn rand_next(c: *rctx) -> u32; unsafe fn rand_next(rng: *rust_rng) -> u32;
unsafe fn rand_free(c: *rctx); unsafe fn rand_free(rng: *rust_rng);
} }
/// A random number generator /// A random number generator
@ -363,24 +363,24 @@ impl Rng {
} }
struct RandRes { struct RandRes {
c: *rctx, rng: *rust_rng,
drop { drop {
unsafe { unsafe {
rustrt::rand_free(self.c); rustrt::rand_free(self.rng);
} }
} }
} }
fn RandRes(c: *rctx) -> RandRes { fn RandRes(rng: *rust_rng) -> RandRes {
RandRes { RandRes {
c: c rng: rng
} }
} }
impl Rng for @RandRes { impl Rng for @RandRes {
fn next() -> u32 { fn next() -> u32 {
unsafe { 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), rust_vec *v = (rust_vec *) task->kernel->malloc(vec_size<uint8_t>(size),
"rand_seed"); "rand_seed");
v->fill = v->alloc = size; 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; return v;
} }
@ -143,27 +143,27 @@ extern "C" CDECL void *
rand_new() { rand_new() {
rust_task *task = rust_get_current_task(); rust_task *task = rust_get_current_task();
rust_sched_loop *thread = task->sched_loop; rust_sched_loop *thread = task->sched_loop;
randctx *rctx = (randctx *) task->malloc(sizeof(randctx), "rand_new"); rust_rng *rng = (rust_rng *) task->malloc(sizeof(rust_rng), "rand_new");
if (!rctx) { if (!rng) {
task->fail(); task->fail();
return NULL; return NULL;
} }
isaac_init(thread->kernel, rctx, NULL); rng_init(thread->kernel, rng, NULL);
return rctx; return rng;
} }
extern "C" CDECL void * extern "C" CDECL void *
rand_new_seeded(rust_vec_box* seed) { rand_new_seeded(rust_vec_box* seed) {
rust_task *task = rust_get_current_task(); rust_task *task = rust_get_current_task();
rust_sched_loop *thread = task->sched_loop; rust_sched_loop *thread = task->sched_loop;
randctx *rctx = (randctx *) task->malloc(sizeof(randctx), rust_rng *rng = (rust_rng *) task->malloc(sizeof(rust_rng),
"rand_new_seeded"); "rand_new_seeded");
if (!rctx) { if (!rng) {
task->fail(); task->fail();
return NULL; return NULL;
} }
isaac_init(thread->kernel, rctx, seed); rng_init(thread->kernel, rng, seed);
return rctx; return rng;
} }
extern "C" CDECL void * extern "C" CDECL void *
@ -172,14 +172,14 @@ rand_new_seeded2(rust_vec_box** seed) {
} }
extern "C" CDECL uint32_t extern "C" CDECL uint32_t
rand_next(randctx *rctx) { rand_next(rust_rng *rng) {
return isaac_rand(rctx); return rng_gen_u32(rng);
} }
extern "C" CDECL void extern "C" CDECL void
rand_free(randctx *rctx) { rand_free(rust_rng *rng) {
rust_task *task = rust_get_current_task(); rust_task *task = rust_get_current_task();
task->free(rctx); task->free(rng);
} }

View file

@ -15,7 +15,7 @@
// Initialization helpers for ISAAC RNG // Initialization helpers for ISAAC RNG
void 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__ #ifdef __WIN32__
HCRYPTPROV hProv; HCRYPTPROV hProv;
kernel->win32_require kernel->win32_require
@ -47,7 +47,7 @@ isaac_seed(rust_kernel* kernel, uint8_t* dest, size_t size) {
#endif #endif
} }
void static void
isaac_init(rust_kernel *kernel, randctx *rctx, rust_vec_box* user_seed) { isaac_init(rust_kernel *kernel, randctx *rctx, rust_vec_box* user_seed) {
memset(rctx, 0, sizeof(randctx)); 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); seed = (seed + 0x7ed55d16) + (seed << 12);
} }
} else { } 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); 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: // Local Variables:
// mode: C++ // mode: C++

View file

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

View file

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

View file

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