about summary refs log tree commit diff
path: root/src/rt
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-10-09 05:11:33 -0700
committerbors <bors@rust-lang.org>2013-10-09 05:11:33 -0700
commitf647ccc79c38c1f80dbdb697900b2ba97e293263 (patch)
treec16836c1c963984b2df8cfebcadc18de45314b8b /src/rt
parente505d4c3535d6e0af1070b1b50ec8db4c2eca827 (diff)
parente678435cab9cc8ddd668d4cb58ab82194c220382 (diff)
downloadrust-f647ccc79c38c1f80dbdb697900b2ba97e293263.tar.gz
rust-f647ccc79c38c1f80dbdb697900b2ba97e293263.zip
auto merge of #9695 : huonw/rust/rand2, r=alexcrichton
A pile of changes to `std::rand`:

- Add the 64-bit variant of the ISAAC Rng. This also splits the `Rng.next() -> u32` method into `Rng.next_u32() -> u32` and `Rng.next_u64() -> u64` to be able to actually take advantage of the wider numbers. They have default implementations in terms of each other. (This is ~2&times; faster than the 32 bit one for generating anything larger than a `u32` on 64-bit computers.)
- Add `ReaderRng` which just wraps a reader as an RNG, useful for `/dev/urandom`, `/dev/random`, `/dev/hwrng`, etc. This also adds the overrideable `fill_bytes` method to `Rng`, since readers can "generate" randomness more than just 8 bytes at a time.
- Add an interface to `/dev/urandom` (and the windows API) that implements `Rng` (`os::OSRng`) so that it is a first-class randomness source. This means that experimenting with things like seeding hashmaps from it will be much easier. It deletes most of the C++ supporting the old form, except for thin wrappers around the Windows API; I don't have access to a windows with Rust other than the try branch. ( **Note:** on unices, this means that `OSRng` requires the runtime, so it's not possible to use it to seed the scheduler RNG; I've replaced it with direct libc calls for reading from `/dev/urandom`.)
- Add the "blessed" `StdRng` which means users who just want a random number generator don't need to worry about the implementation details (which will make changing the underlying implementation from Isaac to something else will be easier, if this every happen). This actually changes between the 32 and 64-bit variants of Isaac depending on the platform at the moment.
- Add a `SeedableRng` trait for random number generators that can be explicitly seeded, 
- Add the `ReseedingRng` wrapper for reseeding a RNG after a certain amount of randomness is emitted. (The method for reseeding is controlled via the `Reseeder` trait from the same module)
- changes to the task rng: 
 - uses `StdRng`
 - it will reseed itself every 32KB, that is, after outputting 32KB of random data it will read new data from the OS (via `OSRng`)
- Implements `Rand` for `char`, and makes the `f32` and `f64` instances more reasonable (and more similar to most other languages I've looked at).
- Documentation, examples and tests


Diffstat (limited to 'src/rt')
-rw-r--r--src/rt/rust_builtin.cpp62
-rw-r--r--src/rt/rust_rng.cpp83
-rw-r--r--src/rt/rust_rng.h26
-rw-r--r--src/rt/rustrt.def.in4
4 files changed, 59 insertions, 116 deletions
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index 34d1efd577d..d1d4286a7c6 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -15,7 +15,6 @@
 #include "sync/lock_and_signal.h"
 #include "memory_region.h"
 #include "boxed_region.h"
-#include "rust_rng.h"
 #include "vg/valgrind.h"
 #include "sp.h"
 
@@ -69,11 +68,6 @@ rust_env_pairs() {
 }
 #endif
 
-extern "C" CDECL void
-rand_gen_seed(uint8_t* dest, size_t size) {
-    rng_gen_seed(dest, size);
-}
-
 extern "C" CDECL char*
 #if defined(__WIN32__)
 rust_list_dir_val(WIN32_FIND_DATA* entry_ptr) {
@@ -654,6 +648,62 @@ rust_unset_sigprocmask() {
 
 #endif
 
+#if defined(__WIN32__)
+void
+win32_require(LPCTSTR fn, BOOL ok) {
+    if (!ok) {
+        LPTSTR buf;
+        DWORD err = GetLastError();
+        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                      FORMAT_MESSAGE_FROM_SYSTEM |
+                      FORMAT_MESSAGE_IGNORE_INSERTS,
+                      NULL, err,
+                      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                      (LPTSTR) &buf, 0, NULL );
+        fprintf(stderr, "%s failed with error %ld: %s", fn, err, buf);
+        LocalFree((HLOCAL)buf);
+        abort();
+    }
+}
+
+extern "C" CDECL void
+rust_win32_rand_acquire(HCRYPTPROV* phProv) {
+    win32_require
+        (_T("CryptAcquireContext"),
+         CryptAcquireContext(phProv, NULL, NULL, PROV_RSA_FULL,
+                             CRYPT_VERIFYCONTEXT|CRYPT_SILENT));
+
+}
+extern "C" CDECL void
+rust_win32_rand_gen(HCRYPTPROV hProv, DWORD dwLen, BYTE* pbBuffer) {
+    win32_require
+        (_T("CryptGenRandom"), CryptGenRandom(hProv, dwLen, pbBuffer));
+}
+extern "C" CDECL void
+rust_win32_rand_release(HCRYPTPROV hProv) {
+    win32_require
+        (_T("CryptReleaseContext"), CryptReleaseContext(hProv, 0));
+}
+
+#else
+
+// these symbols are listed in rustrt.def.in, so they need to exist; but they
+// should never be called.
+
+extern "C" CDECL void
+rust_win32_rand_acquire() {
+    abort();
+}
+extern "C" CDECL void
+rust_win32_rand_gen() {
+    abort();
+}
+extern "C" CDECL void
+rust_win32_rand_release() {
+    abort();
+}
+
+#endif
 //
 // Local Variables:
 // mode: C++
diff --git a/src/rt/rust_rng.cpp b/src/rt/rust_rng.cpp
deleted file mode 100644
index 89754f94b70..00000000000
--- a/src/rt/rust_rng.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#include "rust_globals.h"
-#include "rust_rng.h"
-#include "rust_util.h"
-
-
-#ifdef __WIN32__
-void
-win32_require(LPCTSTR fn, BOOL ok) {
-    if (!ok) {
-        LPTSTR buf;
-        DWORD err = GetLastError();
-        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
-                      FORMAT_MESSAGE_FROM_SYSTEM |
-                      FORMAT_MESSAGE_IGNORE_INSERTS,
-                      NULL, err,
-                      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-                      (LPTSTR) &buf, 0, NULL );
-        fprintf(stderr, "%s failed with error %ld: %s", fn, err, buf);
-        LocalFree((HLOCAL)buf);
-        abort();
-    }
-}
-#endif
-
-void
-rng_gen_seed(uint8_t* dest, size_t size) {
-#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, size, (BYTE*) dest));
-    win32_require
-        (_T("CryptReleaseContext"), CryptReleaseContext(hProv, 0));
-#else
-    int fd = open("/dev/urandom", O_RDONLY);
-    if (fd == -1) {
-        fprintf(stderr, "error opening /dev/urandom: %s", strerror(errno));
-        abort();
-    }
-    size_t amount = 0;
-    do {
-        ssize_t ret = read(fd, dest+amount, size-amount);
-        if (ret < 0) {
-            fprintf(stderr, "error reading /dev/urandom: %s", strerror(errno));
-            abort();
-        }
-        else if (ret == 0) {
-            fprintf(stderr, "somehow hit eof reading from /dev/urandom");
-            abort();
-        }
-        amount += (size_t)ret;
-    } while (amount < size);
-    int ret = close(fd);
-    if (ret != 0) {
-        fprintf(stderr, "error closing /dev/urandom: %s", strerror(errno));
-        // FIXME #3697: Why does this fail sometimes?
-        // abort();
-    }
-#endif
-}
-
-//
-// Local Variables:
-// mode: C++
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// End:
-//
diff --git a/src/rt/rust_rng.h b/src/rt/rust_rng.h
deleted file mode 100644
index 08335a6f73f..00000000000
--- a/src/rt/rust_rng.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#ifndef RUST_RNG_H
-#define RUST_RNG_H
-
-void rng_gen_seed(uint8_t* dest, size_t size);
-
-//
-// Local Variables:
-// mode: C++
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// End:
-//
-
-#endif
diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in
index d0491a9c059..30f60c662e9 100644
--- a/src/rt/rustrt.def.in
+++ b/src/rt/rustrt.def.in
@@ -9,7 +9,6 @@ rust_localtime
 rust_timegm
 rust_mktime
 precise_time_ns
-rand_gen_seed
 rust_path_is_dir
 rust_path_exists
 rust_get_stdin
@@ -23,6 +22,9 @@ rust_log_console_off
 rust_should_log_console
 rust_unset_sigprocmask
 rust_env_pairs
+rust_win32_rand_acquire
+rust_win32_rand_gen
+rust_win32_rand_release
 upcall_rust_personality
 upcall_call_shim_on_c_stack
 upcall_call_shim_on_rust_stack