Skip to content

Commit 20d857f

Browse files
committed
---
yaml --- r: 96216 b: refs/heads/dist-snap c: a9b1dcf h: refs/heads/master v: v3
1 parent 2e99a17 commit 20d857f

File tree

6 files changed

+132
-33
lines changed

6 files changed

+132
-33
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ refs/heads/try: c274a6888410ce3e357e014568b43310ed787d36
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c
9-
refs/heads/dist-snap: 971d306fe255df7f60fe2b605cd6b6d760866320
9+
refs/heads/dist-snap: a9b1dcf24a28a11b33e796a94098226711bb2716
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1212
refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0

branches/dist-snap/src/libstd/rand/distributions/mod.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -444,17 +444,17 @@ mod tests {
444444
fn test_rand_sample() {
445445
let mut rand_sample = RandSample::<ConstRand>;
446446

447-
assert_eq!(*rand_sample.sample(task_rng()), 0);
448-
assert_eq!(*rand_sample.ind_sample(task_rng()), 0);
447+
assert_eq!(*rand_sample.sample(&mut task_rng()), 0);
448+
assert_eq!(*rand_sample.ind_sample(&mut task_rng()), 0);
449449
}
450450

451451
#[test]
452452
fn test_normal() {
453453
let mut norm = Normal::new(10.0, 10.0);
454-
let rng = task_rng();
454+
let mut rng = task_rng();
455455
for _ in range(0, 1000) {
456-
norm.sample(rng);
457-
norm.ind_sample(rng);
456+
norm.sample(&mut rng);
457+
norm.ind_sample(&mut rng);
458458
}
459459
}
460460
#[test]
@@ -466,10 +466,10 @@ mod tests {
466466
#[test]
467467
fn test_exp() {
468468
let mut exp = Exp::new(10.0);
469-
let rng = task_rng();
469+
let mut rng = task_rng();
470470
for _ in range(0, 1000) {
471-
assert!(exp.sample(rng) >= 0.0);
472-
assert!(exp.ind_sample(rng) >= 0.0);
471+
assert!(exp.sample(&mut rng) >= 0.0);
472+
assert!(exp.ind_sample(&mut rng) >= 0.0);
473473
}
474474
}
475475
#[test]

branches/dist-snap/src/libstd/rand/distributions/range.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ mod tests {
183183

184184
#[test]
185185
fn test_integers() {
186-
let rng = task_rng();
186+
let mut rng = task_rng();
187187
macro_rules! t (
188188
($($ty:ty),*) => {{
189189
$(
@@ -193,9 +193,9 @@ mod tests {
193193
for &(low, high) in v.iter() {
194194
let mut sampler: Range<$ty> = Range::new(low, high);
195195
for _ in range(0, 1000) {
196-
let v = sampler.sample(rng);
196+
let v = sampler.sample(&mut rng);
197197
assert!(low <= v && v < high);
198-
let v = sampler.ind_sample(rng);
198+
let v = sampler.ind_sample(&mut rng);
199199
assert!(low <= v && v < high);
200200
}
201201
}
@@ -208,7 +208,7 @@ mod tests {
208208

209209
#[test]
210210
fn test_floats() {
211-
let rng = task_rng();
211+
let mut rng = task_rng();
212212
macro_rules! t (
213213
($($ty:ty),*) => {{
214214
$(
@@ -219,9 +219,9 @@ mod tests {
219219
for &(low, high) in v.iter() {
220220
let mut sampler: Range<$ty> = Range::new(low, high);
221221
for _ in range(0, 1000) {
222-
let v = sampler.sample(rng);
222+
let v = sampler.sample(&mut rng);
223223
assert!(low <= v && v < high);
224-
let v = sampler.ind_sample(rng);
224+
let v = sampler.ind_sample(&mut rng);
225225
assert!(low <= v && v < high);
226226
}
227227
}

branches/dist-snap/src/libstd/rand/mod.rs

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -577,11 +577,24 @@ impl reseeding::Reseeder<StdRng> for TaskRngReseeder {
577577
}
578578
}
579579
static TASK_RNG_RESEED_THRESHOLD: uint = 32_768;
580+
type TaskRngInner = reseeding::ReseedingRng<StdRng, TaskRngReseeder>;
580581
/// The task-local RNG.
581-
pub type TaskRng = reseeding::ReseedingRng<StdRng, TaskRngReseeder>;
582+
#[no_send]
583+
pub struct TaskRng {
584+
// This points into TLS (specifically, it points to the endpoint
585+
// of a ~ stored in TLS, to make it robust against TLS moving
586+
// things internally) and so this struct cannot be legally
587+
// transferred between tasks *and* it's unsafe to deallocate the
588+
// RNG other than when a task is finished.
589+
//
590+
// The use of unsafe code here is OK if the invariants above are
591+
// satisfied; and it allows us to avoid (unnecessarily) using a
592+
// GC'd or RC'd pointer.
593+
priv rng: *mut TaskRngInner
594+
}
582595

583596
// used to make space in TLS for a random number generator
584-
local_data_key!(TASK_RNG_KEY: @mut TaskRng)
597+
local_data_key!(TASK_RNG_KEY: ~TaskRngInner)
585598

586599
/// Retrieve the lazily-initialized task-local random number
587600
/// generator, seeded by the system. Intended to be used in method
@@ -594,34 +607,34 @@ local_data_key!(TASK_RNG_KEY: @mut TaskRng)
594607
/// if the operating system random number generator is rigged to give
595608
/// the same sequence always. If absolute consistency is required,
596609
/// explicitly select an RNG, e.g. `IsaacRng` or `Isaac64Rng`.
597-
pub fn task_rng() -> @mut TaskRng {
598-
let r = local_data::get(TASK_RNG_KEY, |k| k.map(|k| *k));
599-
match r {
610+
pub fn task_rng() -> TaskRng {
611+
local_data::get_mut(TASK_RNG_KEY, |rng| match rng {
600612
None => {
601-
let rng = @mut reseeding::ReseedingRng::new(StdRng::new(),
613+
let mut rng = ~reseeding::ReseedingRng::new(StdRng::new(),
602614
TASK_RNG_RESEED_THRESHOLD,
603615
TaskRngReseeder);
616+
let ptr = &mut *rng as *mut TaskRngInner;
617+
604618
local_data::set(TASK_RNG_KEY, rng);
605-
rng
619+
620+
TaskRng { rng: ptr }
606621
}
607-
Some(rng) => rng
608-
}
622+
Some(rng) => TaskRng { rng: &mut **rng }
623+
})
609624
}
610625

611-
// Allow direct chaining with `task_rng`
612-
impl<R: Rng> Rng for @mut R {
613-
#[inline]
626+
impl Rng for TaskRng {
614627
fn next_u32(&mut self) -> u32 {
615-
(**self).next_u32()
628+
unsafe { (*self.rng).next_u32() }
616629
}
617-
#[inline]
630+
618631
fn next_u64(&mut self) -> u64 {
619-
(**self).next_u64()
632+
unsafe { (*self.rng).next_u64() }
620633
}
621634

622635
#[inline]
623636
fn fill_bytes(&mut self, bytes: &mut [u8]) {
624-
(**self).fill_bytes(bytes);
637+
unsafe { (*self.rng).fill_bytes(bytes) }
625638
}
626639
}
627640

branches/dist-snap/src/libstd/vec.rs

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3862,10 +3862,10 @@ mod bench {
38623862
}
38633863

38643864
#[bench]
3865-
fn add(b: &mut BenchHarness) {
3865+
fn add(bh: &mut BenchHarness) {
38663866
let xs: &[int] = [5, ..10];
38673867
let ys: &[int] = [5, ..10];
3868-
do b.iter() {
3868+
do bh.iter() {
38693869
xs + ys;
38703870
}
38713871
}
@@ -3885,4 +3885,72 @@ mod bench {
38853885
xss.connect_vec(&0);
38863886
}
38873887
}
3888+
3889+
#[bench]
3890+
fn push(bh: &mut BenchHarness) {
3891+
let mut vec: ~[uint] = ~[0u];
3892+
do bh.iter() {
3893+
vec.push(0);
3894+
}
3895+
}
3896+
3897+
#[bench]
3898+
fn starts_with_same_vector(bh: &mut BenchHarness) {
3899+
let vec: ~[uint] = vec::from_fn(100, |i| i);
3900+
do bh.iter() {
3901+
vec.starts_with(vec);
3902+
}
3903+
}
3904+
3905+
#[bench]
3906+
fn starts_with_single_element(bh: &mut BenchHarness) {
3907+
let vec: ~[uint] = ~[0u];
3908+
do bh.iter() {
3909+
vec.starts_with(vec);
3910+
}
3911+
}
3912+
3913+
#[bench]
3914+
fn starts_with_diff_one_element_at_end(bh: &mut BenchHarness) {
3915+
let vec: ~[uint] = vec::from_fn(100, |i| i);
3916+
let mut match_vec: ~[uint] = vec::from_fn(99, |i| i);
3917+
match_vec.push(0);
3918+
do bh.iter() {
3919+
vec.starts_with(match_vec);
3920+
}
3921+
}
3922+
3923+
#[bench]
3924+
fn ends_with_same_vector(bh: &mut BenchHarness) {
3925+
let vec: ~[uint] = vec::from_fn(100, |i| i);
3926+
do bh.iter() {
3927+
vec.ends_with(vec);
3928+
}
3929+
}
3930+
3931+
#[bench]
3932+
fn ends_with_single_element(bh: &mut BenchHarness) {
3933+
let vec: ~[uint] = ~[0u];
3934+
do bh.iter() {
3935+
vec.ends_with(vec);
3936+
}
3937+
}
3938+
3939+
#[bench]
3940+
fn ends_with_diff_one_element_at_beginning(bh: &mut BenchHarness) {
3941+
let vec: ~[uint] = vec::from_fn(100, |i| i);
3942+
let mut match_vec: ~[uint] = vec::from_fn(100, |i| i);
3943+
match_vec[0] = 200;
3944+
do bh.iter() {
3945+
vec.starts_with(match_vec);
3946+
}
3947+
}
3948+
3949+
#[bench]
3950+
fn contains_last_element(bh: &mut BenchHarness) {
3951+
let vec: ~[uint] = vec::from_fn(100, |i| i);
3952+
do bh.iter() {
3953+
vec.contains(&99u);
3954+
}
3955+
}
38883956
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// ensure that the TaskRng isn't/doesn't become accidentally sendable.
12+
13+
fn test_send<S: Send>() {}
14+
15+
pub fn main() {
16+
test_send::<::std::rand::TaskRng>();
17+
//~^ ERROR: incompatible type `std::rand::TaskRng`, which does not fulfill `Send`
18+
}

0 commit comments

Comments
 (0)