2013-12-18 16:24:26 -06:00
|
|
|
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2016-02-11 05:34:41 -06:00
|
|
|
// ignore-emscripten no threads support
|
2015-03-22 15:13:15 -05:00
|
|
|
|
2016-03-07 17:42:29 -06:00
|
|
|
#![feature(rand)]
|
2015-05-29 08:42:32 -05:00
|
|
|
#![feature(const_fn)]
|
2015-03-05 20:33:58 -06:00
|
|
|
|
2015-05-27 03:18:36 -05:00
|
|
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
2015-04-10 13:12:43 -05:00
|
|
|
use std::__rand::{thread_rng, Rng};
|
2015-02-17 17:10:25 -06:00
|
|
|
use std::thread;
|
2013-12-18 16:24:26 -06:00
|
|
|
|
2015-01-25 15:05:03 -06:00
|
|
|
const REPEATS: usize = 5;
|
|
|
|
const MAX_LEN: usize = 32;
|
2015-01-10 15:42:48 -06:00
|
|
|
static drop_counts: [AtomicUsize; MAX_LEN] =
|
|
|
|
// FIXME #5244: AtomicUsize is not Copy.
|
2014-10-14 06:20:59 -05:00
|
|
|
[
|
2015-05-27 03:18:36 -05:00
|
|
|
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
|
|
|
|
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
|
|
|
|
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
|
|
|
|
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
|
|
|
|
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
|
|
|
|
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
|
|
|
|
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
|
|
|
|
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
|
|
|
|
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
|
|
|
|
AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0),
|
|
|
|
AtomicUsize::new(0), AtomicUsize::new(0),
|
2014-10-14 06:20:59 -05:00
|
|
|
];
|
2013-12-18 16:24:26 -06:00
|
|
|
|
2015-05-27 03:18:36 -05:00
|
|
|
static creation_count: AtomicUsize = AtomicUsize::new(0);
|
2014-10-14 06:20:59 -05:00
|
|
|
|
2014-12-30 22:32:49 -06:00
|
|
|
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord)]
|
2015-04-10 13:12:43 -05:00
|
|
|
struct DropCounter { x: u32, creation_id: usize }
|
2013-12-18 16:24:26 -06:00
|
|
|
|
|
|
|
impl Drop for DropCounter {
|
|
|
|
fn drop(&mut self) {
|
2015-01-02 01:53:35 -06:00
|
|
|
drop_counts[self.creation_id].fetch_add(1, Ordering::Relaxed);
|
2013-12-18 16:24:26 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn main() {
|
|
|
|
// len can't go above 64.
|
2015-01-26 14:46:12 -06:00
|
|
|
for len in 2..MAX_LEN {
|
|
|
|
for _ in 0..REPEATS {
|
2014-10-14 06:20:59 -05:00
|
|
|
// reset the count for these new DropCounters, so their
|
|
|
|
// IDs start from 0.
|
2015-01-02 01:53:35 -06:00
|
|
|
creation_count.store(0, Ordering::Relaxed);
|
2014-10-14 06:20:59 -05:00
|
|
|
|
2015-04-10 13:12:43 -05:00
|
|
|
let mut rng = thread_rng();
|
|
|
|
let main = (0..len).map(|_| {
|
|
|
|
DropCounter {
|
|
|
|
x: rng.next_u32(),
|
|
|
|
creation_id: creation_count.fetch_add(1, Ordering::Relaxed),
|
|
|
|
}
|
|
|
|
}).collect::<Vec<_>>();
|
2013-12-18 16:24:26 -06:00
|
|
|
|
|
|
|
// work out the total number of comparisons required to sort
|
|
|
|
// this array...
|
2015-02-18 04:42:01 -06:00
|
|
|
let mut count = 0_usize;
|
2015-02-01 20:53:25 -06:00
|
|
|
main.clone().sort_by(|a, b| { count += 1; a.cmp(b) });
|
2013-12-18 16:24:26 -06:00
|
|
|
|
2014-10-09 14:17:22 -05:00
|
|
|
// ... and then panic on each and every single one.
|
2015-01-25 15:05:03 -06:00
|
|
|
for panic_countdown in 0..count {
|
2013-12-18 16:24:26 -06:00
|
|
|
// refresh the counters.
|
2015-01-31 11:20:46 -06:00
|
|
|
for c in &drop_counts {
|
2015-01-02 01:53:35 -06:00
|
|
|
c.store(0, Ordering::Relaxed);
|
2013-12-18 16:24:26 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
let v = main.clone();
|
|
|
|
|
2015-02-17 17:10:25 -06:00
|
|
|
let _ = thread::spawn(move|| {
|
2015-01-02 01:53:35 -06:00
|
|
|
let mut v = v;
|
|
|
|
let mut panic_countdown = panic_countdown;
|
2015-02-01 20:53:25 -06:00
|
|
|
v.sort_by(|a, b| {
|
2015-01-02 01:53:35 -06:00
|
|
|
if panic_countdown == 0 {
|
|
|
|
panic!()
|
|
|
|
}
|
|
|
|
panic_countdown -= 1;
|
|
|
|
a.cmp(b)
|
|
|
|
})
|
|
|
|
}).join();
|
2013-12-18 16:24:26 -06:00
|
|
|
|
|
|
|
// check that the number of things dropped is exactly
|
|
|
|
// what we expect (i.e. the contents of `v`).
|
2014-10-14 06:20:59 -05:00
|
|
|
for (i, c) in drop_counts.iter().enumerate().take(len) {
|
2015-01-02 01:53:35 -06:00
|
|
|
let count = c.load(Ordering::Relaxed);
|
2014-10-14 06:20:59 -05:00
|
|
|
assert!(count == 1,
|
|
|
|
"found drop count == {} for i == {}, len == {}",
|
|
|
|
count, i, len);
|
2013-12-18 16:24:26 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|