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::{AtomicUint, ATOMIC_UINT_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: [AtomicUint; MAX_LEN] =
18 // FIXME #5244: AtomicUint is not Copy.
20 ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT,
21 ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT,
22 ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT,
23 ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT,
25 ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT,
26 ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT,
27 ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT,
28 ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT,
31 static creation_count: AtomicUint = ATOMIC_UINT_INIT;
33 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord)]
34 struct DropCounter { x: uint, creation_id: uint }
36 impl Rand for DropCounter {
37 fn rand<R: Rng>(rng: &mut R) -> DropCounter {
38 // (we're not using this concurrently, so Relaxed is fine.)
39 let num = creation_count.fetch_add(1, Ordering::Relaxed);
47 impl Drop for DropCounter {
49 drop_counts[self.creation_id].fetch_add(1, Ordering::Relaxed);
54 assert!(MAX_LEN <= std::uint::BITS);
55 // len can't go above 64.
56 for len in range(2, MAX_LEN) {
57 for _ in range(0, REPEATS) {
58 // reset the count for these new DropCounters, so their
60 creation_count.store(0, Ordering::Relaxed);
62 let main = thread_rng().gen_iter::<DropCounter>()
64 .collect::<Vec<DropCounter>>();
66 // work out the total number of comparisons required to sort
69 main.clone().as_mut_slice().sort_by(|a, b| { count += 1; a.cmp(b) });
71 // ... and then panic on each and every single one.
72 for panic_countdown in range(0i, count) {
73 // refresh the counters.
74 for c in drop_counts.iter() {
75 c.store(0, Ordering::Relaxed);
80 let _ = Thread::spawn(move|| {
82 let mut panic_countdown = panic_countdown;
83 v.as_mut_slice().sort_by(|a, b| {
84 if panic_countdown == 0 {
92 // check that the number of things dropped is exactly
93 // what we expect (i.e. the contents of `v`).
94 for (i, c) in drop_counts.iter().enumerate().take(len) {
95 let count = c.load(Ordering::Relaxed);
97 "found drop count == {} for i == {}, len == {}",