diff --git a/src/test/run-pass/vector-sort-failure-safe.rs b/src/test/run-pass/vector-sort-failure-safe.rs index a8ab0e48ccf8a..46f760722a605 100644 --- a/src/test/run-pass/vector-sort-failure-safe.rs +++ b/src/test/run-pass/vector-sort-failure-safe.rs @@ -9,41 +9,56 @@ // except according to those terms. use std::task; -use std::rand::{task_rng, Rng}; +use std::sync::atomics::{AtomicUint, INIT_ATOMIC_UINT, Relaxed}; +use std::rand::{task_rng, Rng, Rand}; -const MAX_LEN: uint = 20; -static mut drop_counts: [uint, .. MAX_LEN] = [0, .. MAX_LEN]; -static mut clone_count: uint = 0; +const REPEATS: uint = 5; +const MAX_LEN: uint = 32; +static drop_counts: [AtomicUint, .. MAX_LEN] = + // FIXME #5244: AtomicUint is not Copy. + [ + INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, + INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, + INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, + INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, -#[deriving(Rand, PartialEq, PartialOrd, Eq, Ord)] -struct DropCounter { x: uint, clone_num: uint } + INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, + INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, + INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, + INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, + ]; -impl Clone for DropCounter { - fn clone(&self) -> DropCounter { - let num = unsafe { clone_count }; - unsafe { clone_count += 1; } +static creation_count: AtomicUint = INIT_ATOMIC_UINT; + +#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord)] +struct DropCounter { x: uint, creation_id: uint } + +impl Rand for DropCounter { + fn rand(rng: &mut R) -> DropCounter { + // (we're not using this concurrently, so Relaxed is fine.) + let num = creation_count.fetch_add(1, Relaxed); DropCounter { - x: self.x, - clone_num: num + x: rng.gen(), + creation_id: num } } } impl Drop for DropCounter { fn drop(&mut self) { - unsafe { - // Rand creates some with arbitrary clone_nums - if self.clone_num < MAX_LEN { - drop_counts[self.clone_num] += 1; - } - } + drop_counts[self.creation_id].fetch_add(1, Relaxed); } } pub fn main() { + assert!(MAX_LEN <= std::uint::BITS); // len can't go above 64. - for len in range(2u, MAX_LEN) { - for _ in range(0i, 10) { + for len in range(2, MAX_LEN) { + for _ in range(0, REPEATS) { + // reset the count for these new DropCounters, so their + // IDs start from 0. + creation_count.store(0, Relaxed); + let main = task_rng().gen_iter::() .take(len) .collect::>(); @@ -56,14 +71,13 @@ pub fn main() { // ... and then fail on each and every single one. for fail_countdown in range(0i, count) { // refresh the counters. - unsafe { - drop_counts = [0, .. MAX_LEN]; - clone_count = 0; + for c in drop_counts.iter() { + c.store(0, Relaxed); } let v = main.clone(); - task::try(proc() { + let _ = task::try(proc() { let mut v = v; let mut fail_countdown = fail_countdown; v.as_mut_slice().sort_by(|a, b| { @@ -77,13 +91,11 @@ pub fn main() { // check that the number of things dropped is exactly // what we expect (i.e. the contents of `v`). - unsafe { - for (i, &c) in drop_counts.iter().enumerate() { - let expected = if i < len {1} else {0}; - assert!(c == expected, - "found drop count == {} for i == {}, len == {}", - c, i, len); - } + for (i, c) in drop_counts.iter().enumerate().take(len) { + let count = c.load(Relaxed); + assert!(count == 1, + "found drop count == {} for i == {}, len == {}", + count, i, len); } } }