csv_diff/
thread_scope_strategy.rs1#[cfg(feature = "rayon-threads")]
2use mown::Mown;
3
4pub trait ThreadScoper<S> {
5 fn scope<F>(&self, f: F)
6 where
7 F: FnOnce(&S) + Send;
8}
9#[derive(Debug, Default)]
10#[cfg(feature = "crossbeam-threads")]
11pub struct CrossbeamScope;
12
13#[cfg(feature = "crossbeam-threads")]
14impl<'scope> ThreadScoper<crossbeam_utils::thread::Scope<'scope>> for CrossbeamScope {
15 fn scope<F>(&self, f: F)
16 where
17 F: FnOnce(&crossbeam_utils::thread::Scope<'scope>),
18 {
19 crossbeam_utils::thread::scope(|s| f(s)).unwrap();
20 }
21}
22
23#[cfg(feature = "crossbeam-threads")]
24impl CrossbeamScope {
25 pub fn new() -> Self {
26 Self
27 }
28}
29
30#[derive(Debug)]
31#[cfg(feature = "rayon-threads")]
32pub struct RayonScope<'tp> {
33 thread_pool: Mown<'tp, rayon::ThreadPool>,
34}
35
36#[cfg(feature = "rayon-threads")]
37impl<'scope> ThreadScoper<rayon::Scope<'scope>> for RayonScope<'_> {
38 fn scope<F>(&self, f: F)
39 where
40 F: FnOnce(&rayon::Scope<'scope>) + Send,
41 {
42 self.thread_pool.scope(|s| f(s));
43 }
44}
45
46#[cfg(feature = "rayon-threads")]
47impl<'tp> RayonScope<'tp> {
48 pub fn with_thread_pool_ref(thread_pool: &'tp rayon::ThreadPool) -> Self {
49 Self {
50 thread_pool: Mown::Borrowed(thread_pool),
51 }
52 }
53
54 pub fn with_thread_pool_owned(thread_pool: rayon::ThreadPool) -> Self {
55 Self {
56 thread_pool: Mown::Owned(thread_pool),
57 }
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use std::sync::atomic::{AtomicU64, Ordering};
64
65 #[cfg(feature = "crossbeam-threads")]
66 use super::CrossbeamScope;
67 #[cfg(feature = "rayon-threads")]
68 use super::RayonScope;
69 use super::ThreadScoper;
70 #[test]
71 #[cfg(feature = "crossbeam-threads")]
72 fn crossbeam_scope_add_num() {
73 let num = AtomicU64::new(0);
74 let crossbeam_scope = CrossbeamScope::new();
75 crossbeam_scope.scope(|s| {
76 s.spawn(|_s1| {
77 num.fetch_add(1, Ordering::SeqCst);
78 });
79 s.spawn(|_s2| {
80 num.fetch_add(1, Ordering::SeqCst);
81 });
82 });
83 assert_eq!(2, num.into_inner());
84 }
85
86 #[test]
87 #[cfg(feature = "rayon-threads")]
88 fn rayon_scope_add_num() {
89 let num = AtomicU64::new(0);
90 let tp = rayon::ThreadPoolBuilder::new().build().unwrap();
91 let rayon_scope = RayonScope::with_thread_pool_ref(&tp);
92 rayon_scope.scope(|s| {
93 s.spawn(|_s1| {
94 num.fetch_add(1, Ordering::SeqCst);
95 });
96 s.spawn(|_s2| {
97 num.fetch_add(1, Ordering::SeqCst);
98 });
99 });
100 assert_eq!(2, num.into_inner());
101 }
102}