]> git.proxmox.com Git - rustc.git/blame - vendor/crossbeam-queue/tests/seg_queue.rs
New upstream version 1.64.0+dfsg1
[rustc.git] / vendor / crossbeam-queue / tests / seg_queue.rs
CommitLineData
064997fb
FG
1use std::sync::atomic::{AtomicUsize, Ordering};
2
3use crossbeam_queue::SegQueue;
4use crossbeam_utils::thread::scope;
5use rand::{thread_rng, Rng};
6
7#[test]
8fn smoke() {
9 let q = SegQueue::new();
10 q.push(7);
11 assert_eq!(q.pop(), Some(7));
12
13 q.push(8);
14 assert_eq!(q.pop(), Some(8));
15 assert!(q.pop().is_none());
16}
17
18#[test]
19fn len_empty_full() {
20 let q = SegQueue::new();
21
22 assert_eq!(q.len(), 0);
23 assert!(q.is_empty());
24
25 q.push(());
26
27 assert_eq!(q.len(), 1);
28 assert!(!q.is_empty());
29
30 q.pop().unwrap();
31
32 assert_eq!(q.len(), 0);
33 assert!(q.is_empty());
34}
35
36#[test]
37fn len() {
38 let q = SegQueue::new();
39
40 assert_eq!(q.len(), 0);
41
42 for i in 0..50 {
43 q.push(i);
44 assert_eq!(q.len(), i + 1);
45 }
46
47 for i in 0..50 {
48 q.pop().unwrap();
49 assert_eq!(q.len(), 50 - i - 1);
50 }
51
52 assert_eq!(q.len(), 0);
53}
54
55#[cfg_attr(miri, ignore)] // Miri is too slow
56#[test]
57fn spsc() {
58 const COUNT: usize = 100_000;
59
60 let q = SegQueue::new();
61
62 scope(|scope| {
63 scope.spawn(|_| {
64 for i in 0..COUNT {
65 loop {
66 if let Some(x) = q.pop() {
67 assert_eq!(x, i);
68 break;
69 }
70 }
71 }
72 assert!(q.pop().is_none());
73 });
74 scope.spawn(|_| {
75 for i in 0..COUNT {
76 q.push(i);
77 }
78 });
79 })
80 .unwrap();
81}
82
83#[cfg_attr(miri, ignore)] // Miri is too slow
84#[test]
85fn mpmc() {
86 const COUNT: usize = 25_000;
87 const THREADS: usize = 4;
88
89 let q = SegQueue::<usize>::new();
90 let v = (0..COUNT).map(|_| AtomicUsize::new(0)).collect::<Vec<_>>();
91
92 scope(|scope| {
93 for _ in 0..THREADS {
94 scope.spawn(|_| {
95 for _ in 0..COUNT {
96 let n = loop {
97 if let Some(x) = q.pop() {
98 break x;
99 }
100 };
101 v[n].fetch_add(1, Ordering::SeqCst);
102 }
103 });
104 }
105 for _ in 0..THREADS {
106 scope.spawn(|_| {
107 for i in 0..COUNT {
108 q.push(i);
109 }
110 });
111 }
112 })
113 .unwrap();
114
115 for c in v {
116 assert_eq!(c.load(Ordering::SeqCst), THREADS);
117 }
118}
119
120#[cfg_attr(miri, ignore)] // Miri is too slow
121#[test]
122fn drops() {
123 const RUNS: usize = 100;
124
125 static DROPS: AtomicUsize = AtomicUsize::new(0);
126
127 #[derive(Debug, PartialEq)]
128 struct DropCounter;
129
130 impl Drop for DropCounter {
131 fn drop(&mut self) {
132 DROPS.fetch_add(1, Ordering::SeqCst);
133 }
134 }
135
136 let mut rng = thread_rng();
137
138 for _ in 0..RUNS {
139 let steps = rng.gen_range(0..10_000);
140 let additional = rng.gen_range(0..1000);
141
142 DROPS.store(0, Ordering::SeqCst);
143 let q = SegQueue::new();
144
145 scope(|scope| {
146 scope.spawn(|_| {
147 for _ in 0..steps {
148 while q.pop().is_none() {}
149 }
150 });
151
152 scope.spawn(|_| {
153 for _ in 0..steps {
154 q.push(DropCounter);
155 }
156 });
157 })
158 .unwrap();
159
160 for _ in 0..additional {
161 q.push(DropCounter);
162 }
163
164 assert_eq!(DROPS.load(Ordering::SeqCst), steps);
165 drop(q);
166 assert_eq!(DROPS.load(Ordering::SeqCst), steps + additional);
167 }
168}
169
170#[test]
171fn into_iter() {
172 let q = SegQueue::new();
173 for i in 0..100 {
174 q.push(i);
175 }
176 for (i, j) in q.into_iter().enumerate() {
177 assert_eq!(i, j);
178 }
179}
180
181#[test]
182fn into_iter_drop() {
183 let q = SegQueue::new();
184 for i in 0..100 {
185 q.push(i);
186 }
187 for (i, j) in q.into_iter().enumerate().take(50) {
188 assert_eq!(i, j);
189 }
190}