]> git.proxmox.com Git - rustc.git/blame - src/test/run-pass/vector-sort-panic-safe.rs
Imported Upstream version 1.0.0~beta
[rustc.git] / src / test / run-pass / vector-sort-panic-safe.rs
CommitLineData
1a4d82fc
JJ
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
c34b1796
AL
11// pretty-expanded FIXME #23616
12
13#![feature(rand, core)]
14
85aaf69f 15use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
1a4d82fc 16use std::rand::{thread_rng, Rng, Rand};
85aaf69f 17use std::thread;
1a4d82fc 18
85aaf69f
SL
19const REPEATS: usize = 5;
20const MAX_LEN: usize = 32;
21static drop_counts: [AtomicUsize; MAX_LEN] =
22 // FIXME #5244: AtomicUsize is not Copy.
1a4d82fc 23 [
85aaf69f
SL
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, ATOMIC_USIZE_INIT,
31 ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT,
32 ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT,
33 ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT,
34 ATOMIC_USIZE_INIT, ATOMIC_USIZE_INIT,
1a4d82fc
JJ
35 ];
36
85aaf69f 37static creation_count: AtomicUsize = ATOMIC_USIZE_INIT;
1a4d82fc
JJ
38
39#[derive(Clone, PartialEq, PartialOrd, Eq, Ord)]
85aaf69f 40struct DropCounter { x: usize, creation_id: usize }
1a4d82fc
JJ
41
42impl Rand for DropCounter {
43 fn rand<R: Rng>(rng: &mut R) -> DropCounter {
44 // (we're not using this concurrently, so Relaxed is fine.)
45 let num = creation_count.fetch_add(1, Ordering::Relaxed);
46 DropCounter {
47 x: rng.gen(),
48 creation_id: num
49 }
50 }
51}
52
53impl Drop for DropCounter {
54 fn drop(&mut self) {
55 drop_counts[self.creation_id].fetch_add(1, Ordering::Relaxed);
56 }
57}
58
59pub fn main() {
c34b1796 60 assert!(MAX_LEN <= std::usize::BITS as usize);
1a4d82fc 61 // len can't go above 64.
85aaf69f
SL
62 for len in 2..MAX_LEN {
63 for _ in 0..REPEATS {
1a4d82fc
JJ
64 // reset the count for these new DropCounters, so their
65 // IDs start from 0.
66 creation_count.store(0, Ordering::Relaxed);
67
68 let main = thread_rng().gen_iter::<DropCounter>()
69 .take(len)
70 .collect::<Vec<DropCounter>>();
71
72 // work out the total number of comparisons required to sort
73 // this array...
85aaf69f
SL
74 let mut count = 0_usize;
75 main.clone().sort_by(|a, b| { count += 1; a.cmp(b) });
1a4d82fc
JJ
76
77 // ... and then panic on each and every single one.
85aaf69f 78 for panic_countdown in 0..count {
1a4d82fc 79 // refresh the counters.
85aaf69f 80 for c in &drop_counts {
1a4d82fc
JJ
81 c.store(0, Ordering::Relaxed);
82 }
83
84 let v = main.clone();
85
85aaf69f 86 let _ = thread::spawn(move|| {
1a4d82fc
JJ
87 let mut v = v;
88 let mut panic_countdown = panic_countdown;
85aaf69f 89 v.sort_by(|a, b| {
1a4d82fc
JJ
90 if panic_countdown == 0 {
91 panic!()
92 }
93 panic_countdown -= 1;
94 a.cmp(b)
95 })
96 }).join();
97
98 // check that the number of things dropped is exactly
99 // what we expect (i.e. the contents of `v`).
100 for (i, c) in drop_counts.iter().enumerate().take(len) {
101 let count = c.load(Ordering::Relaxed);
102 assert!(count == 1,
103 "found drop count == {} for i == {}, len == {}",
104 count, i, len);
105 }
106 }
107 }
108 }
109}