Skip to content

Commit aa173b8

Browse files
committed
auto merge of #6288 : brson/rust/rng, r=graydon
Closes #6280
2 parents 19d2ba3 + 33c40b9 commit aa173b8

File tree

7 files changed

+68
-60
lines changed

7 files changed

+68
-60
lines changed

src/libcore/rt/local_services.rs

+9
Original file line numberDiff line numberDiff line change
@@ -220,4 +220,13 @@ mod test {
220220
assert!(result.is_err());
221221
}
222222
}
223+
224+
#[test]
225+
fn rng() {
226+
do run_in_newsched_task() {
227+
use rand::{rng, Rng};
228+
let r = rng();
229+
let _ = r.next();
230+
}
231+
}
223232
}

src/rt/rust_builtin.cpp

+4-5
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,7 @@ rand_seed_size() {
8888

8989
extern "C" CDECL void
9090
rand_gen_seed(uint8_t* dest, size_t size) {
91-
rust_task *task = rust_get_current_task();
92-
rng_gen_seed(task->kernel, dest, size);
91+
rng_gen_seed(dest, size);
9392
}
9493

9594
extern "C" CDECL void *
@@ -101,14 +100,14 @@ rand_new_seeded(uint8_t* seed, size_t seed_size) {
101100
task->fail();
102101
return NULL;
103102
}
104-
rng_init(task->kernel, rng, seed, seed_size);
103+
char *env_seed = task->kernel->env->rust_seed;
104+
rng_init(rng, env_seed, seed, seed_size);
105105
return rng;
106106
}
107107

108108
extern "C" CDECL uint32_t
109109
rand_next(rust_rng *rng) {
110-
rust_task *task = rust_get_current_task();
111-
return rng_gen_u32(task->kernel, rng);
110+
return rng_gen_u32(rng);
112111
}
113112

114113
extern "C" CDECL void

src/rt/rust_kernel.cpp

-19
Original file line numberDiff line numberDiff line change
@@ -257,25 +257,6 @@ rust_kernel::generate_task_id() {
257257
return id;
258258
}
259259

260-
#ifdef __WIN32__
261-
void
262-
rust_kernel::win32_require(LPCTSTR fn, BOOL ok) {
263-
if (!ok) {
264-
LPTSTR buf;
265-
DWORD err = GetLastError();
266-
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
267-
FORMAT_MESSAGE_FROM_SYSTEM |
268-
FORMAT_MESSAGE_IGNORE_INSERTS,
269-
NULL, err,
270-
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
271-
(LPTSTR) &buf, 0, NULL );
272-
KLOG_ERR_(dom, "%s failed with error %ld: %s", fn, err, buf);
273-
LocalFree((HLOCAL)buf);
274-
assert(ok);
275-
}
276-
}
277-
#endif
278-
279260
void
280261
rust_kernel::set_exit_status(int code) {
281262
scoped_lock with(rval_lock);

src/rt/rust_kernel.h

-4
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,6 @@ class rust_kernel {
147147
void wait_for_schedulers();
148148
int run();
149149

150-
#ifdef __WIN32__
151-
void win32_require(LPCTSTR fn, BOOL ok);
152-
#endif
153-
154150
rust_task_id generate_task_id();
155151

156152
void set_exit_status(int code);

src/rt/rust_rng.cpp

+50-26
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,26 @@
1212
#include "rust_rng.h"
1313
#include "rust_util.h"
1414

15+
16+
#ifdef __WIN32__
17+
void
18+
win32_require(LPCTSTR fn, BOOL ok) {
19+
if (!ok) {
20+
LPTSTR buf;
21+
DWORD err = GetLastError();
22+
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
23+
FORMAT_MESSAGE_FROM_SYSTEM |
24+
FORMAT_MESSAGE_IGNORE_INSERTS,
25+
NULL, err,
26+
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
27+
(LPTSTR) &buf, 0, NULL );
28+
KLOG_ERR_(dom, "%s failed with error %ld: %s", fn, err, buf);
29+
LocalFree((HLOCAL)buf);
30+
assert(ok);
31+
}
32+
}
33+
#endif
34+
1535
size_t
1636
rng_seed_size() {
1737
randctx rctx;
@@ -21,44 +41,50 @@ rng_seed_size() {
2141
// Initialization helpers for ISAAC RNG
2242

2343
void
24-
rng_gen_seed(rust_kernel* kernel, uint8_t* dest, size_t size) {
44+
rng_gen_seed(uint8_t* dest, size_t size) {
2545
#ifdef __WIN32__
2646
HCRYPTPROV hProv;
27-
kernel->win32_require
47+
win32_require
2848
(_T("CryptAcquireContext"),
2949
CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
3050
CRYPT_VERIFYCONTEXT|CRYPT_SILENT));
31-
kernel->win32_require
51+
win32_require
3252
(_T("CryptGenRandom"), CryptGenRandom(hProv, size, (BYTE*) dest));
33-
kernel->win32_require
53+
win32_require
3454
(_T("CryptReleaseContext"), CryptReleaseContext(hProv, 0));
3555
#else
3656
int fd = open("/dev/urandom", O_RDONLY);
37-
if (fd == -1)
38-
kernel->fatal("error opening /dev/urandom: %s", strerror(errno));
57+
if (fd == -1) {
58+
fprintf(stderr, "error opening /dev/urandom: %s", strerror(errno));
59+
abort();
60+
}
3961
size_t amount = 0;
4062
do {
4163
ssize_t ret = read(fd, dest+amount, size-amount);
42-
if (ret < 0)
43-
kernel->fatal("error reading /dev/urandom: %s", strerror(errno));
44-
else if (ret == 0)
45-
kernel->fatal("somehow hit eof reading from /dev/urandom");
64+
if (ret < 0) {
65+
fprintf(stderr, "error reading /dev/urandom: %s", strerror(errno));
66+
abort();
67+
}
68+
else if (ret == 0) {
69+
fprintf(stderr, "somehow hit eof reading from /dev/urandom");
70+
abort();
71+
}
4672
amount += (size_t)ret;
4773
} while (amount < size);
4874
int ret = close(fd);
49-
// FIXME #3697: Why does this fail sometimes?
50-
if (ret != 0)
51-
kernel->log(log_warn, "error closing /dev/urandom: %s",
52-
strerror(errno));
75+
if (ret != 0) {
76+
fprintf(stderr, "error closing /dev/urandom: %s", strerror(errno));
77+
// FIXME #3697: Why does this fail sometimes?
78+
// abort();
79+
}
5380
#endif
5481
}
5582

5683
static void
57-
isaac_init(rust_kernel *kernel, randctx *rctx,
84+
isaac_init(randctx *rctx, char *env_seed,
5885
uint8_t* user_seed, size_t seed_len) {
5986
memset(rctx, 0, sizeof(randctx));
6087

61-
char *env_seed = kernel->env->rust_seed;
6288
if (user_seed != NULL) {
6389
// ignore bytes after the required length
6490
if (seed_len > sizeof(rctx->randrsl)) {
@@ -72,40 +98,38 @@ isaac_init(rust_kernel *kernel, randctx *rctx,
7298
seed = (seed + 0x7ed55d16) + (seed << 12);
7399
}
74100
} else {
75-
rng_gen_seed(kernel,
76-
(uint8_t*)&rctx->randrsl,
101+
rng_gen_seed((uint8_t*)&rctx->randrsl,
77102
sizeof(rctx->randrsl));
78103
}
79104

80105
randinit(rctx, 1);
81106
}
82107

83108
void
84-
rng_init(rust_kernel* kernel, rust_rng* rng,
109+
rng_init(rust_rng* rng, char* env_seed,
85110
uint8_t *user_seed, size_t seed_len) {
86-
isaac_init(kernel, &rng->rctx, user_seed, seed_len);
87-
rng->reseedable = !user_seed && !kernel->env->rust_seed;
111+
isaac_init(&rng->rctx, env_seed, user_seed, seed_len);
112+
rng->reseedable = !user_seed && !env_seed;
88113
}
89114

90115
static void
91-
rng_maybe_reseed(rust_kernel* kernel, rust_rng* rng) {
116+
rng_maybe_reseed(rust_rng* rng) {
92117
// If this RNG has generated more than 32KB of random data and was not
93118
// seeded by the user or RUST_SEED, then we should reseed now.
94119
const size_t RESEED_THRESHOLD = 32 * 1024;
95120
size_t bytes_generated = rng->rctx.randc * sizeof(ub4);
96121
if (bytes_generated < RESEED_THRESHOLD || !rng->reseedable) {
97122
return;
98123
}
99-
rng_gen_seed(kernel,
100-
(uint8_t*)rng->rctx.randrsl,
124+
rng_gen_seed((uint8_t*)rng->rctx.randrsl,
101125
sizeof(rng->rctx.randrsl));
102126
randinit(&rng->rctx, 1);
103127
}
104128

105129
uint32_t
106-
rng_gen_u32(rust_kernel* kernel, rust_rng* rng) {
130+
rng_gen_u32(rust_rng* rng) {
107131
uint32_t x = isaac_rand(&rng->rctx);
108-
rng_maybe_reseed(kernel, rng);
132+
rng_maybe_reseed(rng);
109133
return x;
110134
}
111135

src/rt/rust_rng.h

+3-4
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,10 @@ struct rust_rng {
2323
};
2424

2525
size_t rng_seed_size();
26-
void rng_gen_seed(rust_kernel* kernel,
27-
uint8_t* dest, size_t size);
28-
void rng_init(rust_kernel *kernel, rust_rng *rng,
26+
void rng_gen_seed(uint8_t* dest, size_t size);
27+
void rng_init(rust_rng *rng, char *env_seed,
2928
uint8_t *user_seed, size_t seed_len);
30-
uint32_t rng_gen_u32(rust_kernel *kernel, rust_rng *rng);
29+
uint32_t rng_gen_u32(rust_rng *rng);
3130

3231
//
3332
// Local Variables:

src/rt/rust_sched_loop.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ rust_sched_loop::rust_sched_loop(rust_scheduler *sched, int id, bool killed) :
4343
name("main")
4444
{
4545
LOGPTR(this, "new dom", (uintptr_t)this);
46-
rng_init(kernel, &rng, NULL, 0);
46+
rng_init(&rng, kernel->env->rust_seed, NULL, 0);
4747

4848
if (!tls_initialized)
4949
init_tls();
@@ -154,7 +154,7 @@ rust_sched_loop::schedule_task() {
154154
lock.must_have_lock();
155155
size_t tasks = running_tasks.length();
156156
if (tasks > 0) {
157-
size_t i = (tasks > 1) ? (rng_gen_u32(kernel, &rng) % tasks) : 0;
157+
size_t i = (tasks > 1) ? (rng_gen_u32(&rng) % tasks) : 0;
158158
return running_tasks[i];
159159
}
160160
return NULL;

0 commit comments

Comments
 (0)