Skip to content

Commit 8d8925b

Browse files
committed
Make ThreadPool::spawn_fifo() actually FIFO
1 parent 1b8f79a commit 8d8925b

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

rayon-core/src/thread_pool/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ impl ThreadPool {
276276
OP: FnOnce() + Send + 'static,
277277
{
278278
// We assert that `self.registry` has not terminated.
279-
unsafe { spawn::spawn_in(op, &self.registry) }
279+
unsafe { spawn::spawn_fifo_in(op, &self.registry) }
280280
}
281281
}
282282

rayon-core/src/thread_pool/test.rs

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#![cfg(test)]
22

33
use std::sync::atomic::{AtomicUsize, Ordering};
4-
use std::sync::Arc;
4+
use std::sync::mpsc::channel;
5+
use std::sync::{Arc, Mutex};
56

67
use join;
78
use thread_pool::ThreadPool;
@@ -205,3 +206,67 @@ fn check_thread_pool_new() {
205206
let pool = ThreadPool::new(Configuration::new().num_threads(22)).unwrap();
206207
assert_eq!(pool.current_num_threads(), 22);
207208
}
209+
210+
macro_rules! test_scope_order {
211+
($scope:ident) => {{
212+
let builder = ThreadPoolBuilder::new().num_threads(1);
213+
let pool = builder.build().unwrap();
214+
pool.install(|| {
215+
let vec = Mutex::new(vec![]);
216+
pool.$scope(|scope| {
217+
let vec = &vec;
218+
for i in 0..10 {
219+
scope.spawn(move |_| {
220+
vec.lock().unwrap().push(i);
221+
});
222+
}
223+
});
224+
vec.into_inner().unwrap()
225+
})
226+
}};
227+
}
228+
229+
#[test]
230+
fn scope_lifo_order() {
231+
let vec = test_scope_order!(scope);
232+
let expected: Vec<i32> = (0..10).rev().collect(); // LIFO -> reversed
233+
assert_eq!(vec, expected);
234+
}
235+
236+
#[test]
237+
fn scope_fifo_order() {
238+
let vec = test_scope_order!(scope_fifo);
239+
let expected: Vec<i32> = (0..10).collect(); // FIFO -> natural order
240+
assert_eq!(vec, expected);
241+
}
242+
243+
macro_rules! test_spawn_order {
244+
($spawn:ident) => {{
245+
let builder = ThreadPoolBuilder::new().num_threads(1);
246+
let pool = &builder.build().unwrap();
247+
let (tx, rx) = channel();
248+
pool.install(move || {
249+
for i in 0..10 {
250+
let tx = tx.clone();
251+
pool.$spawn(move || {
252+
tx.send(i).unwrap();
253+
});
254+
}
255+
});
256+
rx.iter().collect::<Vec<i32>>()
257+
}};
258+
}
259+
260+
#[test]
261+
fn spawn_lifo_order() {
262+
let vec = test_spawn_order!(spawn);
263+
let expected: Vec<i32> = (0..10).rev().collect(); // LIFO -> reversed
264+
assert_eq!(vec, expected);
265+
}
266+
267+
#[test]
268+
fn spawn_fifo_order() {
269+
let vec = test_spawn_order!(spawn_fifo);
270+
let expected: Vec<i32> = (0..10).collect(); // FIFO -> natural order
271+
assert_eq!(vec, expected);
272+
}

0 commit comments

Comments
 (0)