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.
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.
11 use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
12 use std::rand::{thread_rng, Rng, Rand};
13 use std::thread::Thread;
15 const REPEATS: uint = 5;
16 const MAX_LEN: uint = 32;
17 static drop_counts: [AtomicUsize; MAX_LEN] =
18 // FIXME #5244: AtomicUsize is not Copy.
20 ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT,
21 ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT,
22 ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT,
23 ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT,
24 ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT,
25 ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT,
26 ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT,
27 ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT,
28 ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT,
29 ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT,
30 ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT,
33 static creation_count: AtomicUsize = ATOMIC_USIZE_INIT;
35 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord)]
36 struct DropCounter { x: uint, creation_id: uint }
38 impl Rand for DropCounter {
39 fn rand<R: Rng>(rng: &mut R) -> DropCounter {
40 // (we're not using this concurrently, so Relaxed is fine.)
41 let num = creation_count.fetch_add(1, Ordering::Relaxed);
49 impl Drop for DropCounter {
51 drop_counts[self.creation_id].fetch_add(1, Ordering::Relaxed);
56 assert!(MAX_LEN <= std::uint::BITS);
57 // len can't go above 64.
58 for len in range(2, MAX_LEN) {
59 for _ in range(0, REPEATS) {
60 // reset the count for these new DropCounters, so their
62 creation_count.store(0, Ordering::Relaxed);
64 let main = thread_rng().gen_iter::<DropCounter>()
66 .collect::<Vec<DropCounter>>();
68 // work out the total number of comparisons required to sort
71 main.clone().as_mut_slice().sort_by(|a, b| { count += 1; a.cmp(b) });
73 // ... and then panic on each and every single one.
74 for panic_countdown in range(0i, count) {
75 // refresh the counters.
76 for c in drop_counts.iter() {
77 c.store(0, Ordering::Relaxed);
82 let _ = Thread::scoped(move|| {
84 let mut panic_countdown = panic_countdown;
85 v.as_mut_slice().sort_by(|a, b| {
86 if panic_countdown == 0 {
94 // check that the number of things dropped is exactly
95 // what we expect (i.e. the contents of `v`).
96 for (i, c) in drop_counts.iter().enumerate().take(len) {
97 let count = c.load(Ordering::Relaxed);
99 "found drop count == {} for i == {}, len == {}",