aboutsummaryrefslogtreecommitdiff
path: root/src/rt
diff options
context:
space:
mode:
authorRoy Frostig <[email protected]>2010-07-25 21:45:09 -0700
committerRoy Frostig <[email protected]>2010-07-25 21:45:09 -0700
commit5b6e714d05a0c96ade618256a67a9cb7f337f196 (patch)
tree45406973ea3c0ffb1a9e070588f4ca5fc8c7744c /src/rt
parentDon't write to NULL after calling C natives returning void. (diff)
downloadrust-5b6e714d05a0c96ade618256a67a9cb7f337f196.tar.xz
rust-5b6e714d05a0c96ade618256a67a9cb7f337f196.zip
Expose an RNG (the one used by our runtime) to Rust via std.
Diffstat (limited to 'src/rt')
-rw-r--r--src/rt/rust_builtin.cpp25
-rw-r--r--src/rt/rust_dom.cpp27
-rw-r--r--src/rt/rust_util.h32
3 files changed, 59 insertions, 25 deletions
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index 99fa9535..e8d2d67d 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -127,6 +127,31 @@ vec_len(rust_task *task, type_desc *ty, rust_vec *v)
return v->fill / ty->size;
}
+extern "C" CDECL void *
+rand_new(rust_task *task)
+{
+ rust_dom *dom = task->dom;
+ randctx *rctx = (randctx *) task->malloc(sizeof(randctx));
+ if (!rctx) {
+ task->fail(1);
+ return NULL;
+ }
+ isaac_init(dom, rctx);
+ return rctx;
+}
+
+extern "C" CDECL size_t
+rand_next(rust_task *task, randctx *rctx)
+{
+ return rand(rctx);
+}
+
+extern "C" CDECL void
+rand_free(rust_task *task, randctx *rctx)
+{
+ task->free(rctx);
+}
+
//
// Local Variables:
// mode: C++
diff --git a/src/rt/rust_dom.cpp b/src/rt/rust_dom.cpp
index ac1e7d0c..205084ff 100644
--- a/src/rt/rust_dom.cpp
+++ b/src/rt/rust_dom.cpp
@@ -36,35 +36,12 @@ rust_dom::rust_dom(rust_srv *srv, rust_crate const *root_crate) :
rval(0)
{
logptr("new dom", (uintptr_t)this);
- memset(&rctx, 0, sizeof(rctx));
-
-#ifdef __WIN32__
- {
- HCRYPTPROV hProv;
- win32_require
- (_T("CryptAcquireContext"),
- CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT|CRYPT_SILENT));
- win32_require
- (_T("CryptGenRandom"),
- CryptGenRandom(hProv, sizeof(rctx.randrsl),
- (BYTE*)(&rctx.randrsl)));
- win32_require
- (_T("CryptReleaseContext"),
- CryptReleaseContext(hProv, 0));
- }
-#else
- int fd = open("/dev/urandom", O_RDONLY);
- I(this, fd > 0);
- I(this, read(fd, (void*) &rctx.randrsl, sizeof(rctx.randrsl))
- == sizeof(rctx.randrsl));
- I(this, close(fd) == 0);
+ isaac_init(this, &rctx);
+#ifndef __WIN32__
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 1024 * 1024);
pthread_attr_setdetachstate(&attr, true);
#endif
- randinit(&rctx, 1);
-
root_task = new (this) rust_task(this, NULL);
}
diff --git a/src/rt/rust_util.h b/src/rt/rust_util.h
index 62ac7de2..95010f17 100644
--- a/src/rt/rust_util.h
+++ b/src/rt/rust_util.h
@@ -117,6 +117,38 @@ next_power_of_two(size_t s)
return tmp + 1;
}
+// Initialization helper for ISAAC RNG
+
+static inline void
+isaac_init(rust_dom *dom, randctx *rctx)
+{
+ memset(rctx, 0, sizeof(randctx));
+
+#ifdef __WIN32__
+ {
+ HCRYPTPROV hProv;
+ win32_require
+ (_T("CryptAcquireContext"),
+ CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT|CRYPT_SILENT));
+ win32_require
+ (_T("CryptGenRandom"),
+ CryptGenRandom(hProv, sizeof(rctx->randrsl),
+ (BYTE*)(&rctx->randrsl)));
+ win32_require
+ (_T("CryptReleaseContext"),
+ CryptReleaseContext(hProv, 0));
+ }
+#else
+ int fd = open("/dev/urandom", O_RDONLY);
+ I(dom, fd > 0);
+ I(dom, read(fd, (void*) &rctx->randrsl, sizeof(rctx->randrsl))
+ == sizeof(rctx->randrsl));
+ I(dom, close(fd) == 0);
+#endif
+ randinit(rctx, 1);
+}
+
// Vectors (rust-user-code level).
struct