9
9
// except according to those terms.
10
10
11
11
use std:: task;
12
- use std:: rand:: { task_rng, Rng } ;
12
+ use std:: sync:: atomics:: { AtomicUint , INIT_ATOMIC_UINT , Relaxed } ;
13
+ use std:: rand:: { task_rng, Rng , Rand } ;
13
14
14
- const MAX_LEN : uint = 20 ;
15
- static mut drop_counts: [ uint , .. MAX_LEN ] = [ 0 , .. MAX_LEN ] ;
16
- static mut clone_count: uint = 0 ;
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.
19
+ [
20
+ INIT_ATOMIC_UINT , INIT_ATOMIC_UINT , INIT_ATOMIC_UINT , INIT_ATOMIC_UINT ,
21
+ INIT_ATOMIC_UINT , INIT_ATOMIC_UINT , INIT_ATOMIC_UINT , INIT_ATOMIC_UINT ,
22
+ INIT_ATOMIC_UINT , INIT_ATOMIC_UINT , INIT_ATOMIC_UINT , INIT_ATOMIC_UINT ,
23
+ INIT_ATOMIC_UINT , INIT_ATOMIC_UINT , INIT_ATOMIC_UINT , INIT_ATOMIC_UINT ,
17
24
18
- #[ deriving( Rand , PartialEq , PartialOrd , Eq , Ord ) ]
19
- struct DropCounter { x : uint , clone_num : uint }
25
+ INIT_ATOMIC_UINT , INIT_ATOMIC_UINT , INIT_ATOMIC_UINT , INIT_ATOMIC_UINT ,
26
+ INIT_ATOMIC_UINT , INIT_ATOMIC_UINT , INIT_ATOMIC_UINT , INIT_ATOMIC_UINT ,
27
+ INIT_ATOMIC_UINT , INIT_ATOMIC_UINT , INIT_ATOMIC_UINT , INIT_ATOMIC_UINT ,
28
+ INIT_ATOMIC_UINT , INIT_ATOMIC_UINT , INIT_ATOMIC_UINT , INIT_ATOMIC_UINT ,
29
+ ] ;
20
30
21
- impl Clone for DropCounter {
22
- fn clone ( & self ) -> DropCounter {
23
- let num = unsafe { clone_count } ;
24
- unsafe { clone_count += 1 ; }
31
+ static creation_count: AtomicUint = INIT_ATOMIC_UINT ;
32
+
33
+ #[ deriving( Clone , PartialEq , PartialOrd , Eq , Ord ) ]
34
+ struct DropCounter { x : uint , creation_id : uint }
35
+
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 , Relaxed ) ;
25
40
DropCounter {
26
- x : self . x ,
27
- clone_num : num
41
+ x : rng . gen ( ) ,
42
+ creation_id : num
28
43
}
29
44
}
30
45
}
31
46
32
47
impl Drop for DropCounter {
33
48
fn drop ( & mut self ) {
34
- unsafe {
35
- // Rand creates some with arbitrary clone_nums
36
- if self . clone_num < MAX_LEN {
37
- drop_counts[ self . clone_num ] += 1 ;
38
- }
39
- }
49
+ drop_counts[ self . creation_id ] . fetch_add ( 1 , Relaxed ) ;
40
50
}
41
51
}
42
52
43
53
pub fn main ( ) {
54
+ assert ! ( MAX_LEN <= std:: uint:: BITS ) ;
44
55
// len can't go above 64.
45
- for len in range ( 2 u, MAX_LEN ) {
46
- for _ in range ( 0 i, 10 ) {
56
+ for len in range ( 2 , MAX_LEN ) {
57
+ for _ in range ( 0 , REPEATS ) {
58
+ // reset the count for these new DropCounters, so their
59
+ // IDs start from 0.
60
+ creation_count. store ( 0 , Relaxed ) ;
61
+
47
62
let main = task_rng ( ) . gen_iter :: < DropCounter > ( )
48
63
. take ( len)
49
64
. collect :: < Vec < DropCounter > > ( ) ;
@@ -56,14 +71,13 @@ pub fn main() {
56
71
// ... and then fail on each and every single one.
57
72
for fail_countdown in range ( 0 i, count) {
58
73
// refresh the counters.
59
- unsafe {
60
- drop_counts = [ 0 , .. MAX_LEN ] ;
61
- clone_count = 0 ;
74
+ for c in drop_counts. iter ( ) {
75
+ c. store ( 0 , Relaxed ) ;
62
76
}
63
77
64
78
let v = main. clone ( ) ;
65
79
66
- task:: try ( proc ( ) {
80
+ let _ = task:: try ( proc ( ) {
67
81
let mut v = v;
68
82
let mut fail_countdown = fail_countdown;
69
83
v. as_mut_slice ( ) . sort_by ( |a, b| {
@@ -77,13 +91,11 @@ pub fn main() {
77
91
78
92
// check that the number of things dropped is exactly
79
93
// what we expect (i.e. the contents of `v`).
80
- unsafe {
81
- for ( i, & c) in drop_counts. iter ( ) . enumerate ( ) {
82
- let expected = if i < len { 1 } else { 0 } ;
83
- assert ! ( c == expected,
84
- "found drop count == {} for i == {}, len == {}" ,
85
- c, i, len) ;
86
- }
94
+ for ( i, c) in drop_counts. iter ( ) . enumerate ( ) . take ( len) {
95
+ let count = c. load ( Relaxed ) ;
96
+ assert ! ( count == 1 ,
97
+ "found drop count == {} for i == {}, len == {}" ,
98
+ count, i, len) ;
87
99
}
88
100
}
89
101
}
0 commit comments