orx_parallel/runner/implementations/
yastl.rs

1use crate::ParThreadPool;
2use core::num::NonZeroUsize;
3use yastl::{Pool, Scope, ThreadConfig};
4
5/// A wrapper for `yastl::Pool` and number of threads it was built with.
6///
7/// NOTE: The reason why `yastl::Pool` does not directly implement `ParThreadPool`
8/// is simply to be able to provide `max_num_threads` which is the argument used
9/// to create the pool with.
10///
11/// Two constructors of the `yastl::Pool` are made available to `YastlPool`:
12/// * [`YastlPool::new`]
13/// * [`YastlPool::with_config`]
14pub struct YastlPool(Pool, NonZeroUsize);
15
16impl YastlPool {
17    /// Create a new Pool that will execute it's tasks on `num_threads` worker threads.
18    pub fn new(num_threads: usize) -> Self {
19        let num_threads = num_threads.min(1);
20        let pool = Pool::new(num_threads);
21        #[allow(clippy::missing_panics_doc)]
22        Self(pool, NonZeroUsize::new(num_threads).expect(">0"))
23    }
24
25    /// Create a new Pool that will execute it's tasks on `num_threads` worker threads and
26    /// spawn them using the given `config`.
27    pub fn with_config(num_threads: usize, config: ThreadConfig) -> Self {
28        let num_threads = num_threads.min(1);
29        let pool = Pool::with_config(num_threads, config);
30        #[allow(clippy::missing_panics_doc)]
31        Self(pool, NonZeroUsize::new(num_threads).expect(">0"))
32    }
33
34    /// Reference to wrapped `yastl::Pool`.
35    pub fn inner(&self) -> &Pool {
36        &self.0
37    }
38
39    /// Mutable reference to wrapped `yastl::Pool`.
40    pub fn inner_mut(&mut self) -> &mut Pool {
41        &mut self.0
42    }
43
44    /// Returns the wrapped `yastl::Pool`.
45    pub fn into_inner(self) -> Pool {
46        self.0
47    }
48}
49
50impl ParThreadPool for YastlPool {
51    type ScopeRef<'s, 'env, 'scope>
52        = &'s Scope<'scope>
53    where
54        'scope: 's,
55        'env: 'scope + 's;
56
57    fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope>, work: W)
58    where
59        'scope: 's,
60        'env: 'scope + 's,
61        W: Fn() + Send + 'scope + 'env,
62    {
63        s.execute(work);
64    }
65
66    fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
67    where
68        'env: 'scope,
69        for<'s> F: FnOnce(&'s Scope<'scope>) + Send,
70    {
71        self.0.scoped(f)
72    }
73
74    fn max_num_threads(&self) -> NonZeroUsize {
75        self.1
76    }
77}
78
79impl ParThreadPool for &YastlPool {
80    type ScopeRef<'s, 'env, 'scope>
81        = &'s Scope<'scope>
82    where
83        'scope: 's,
84        'env: 'scope + 's;
85
86    fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope>, work: W)
87    where
88        'scope: 's,
89        'env: 'scope + 's,
90        W: Fn() + Send + 'scope + 'env,
91    {
92        s.execute(work);
93    }
94
95    fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
96    where
97        'env: 'scope,
98        for<'s> F: FnOnce(&'s Scope<'scope>) + Send,
99    {
100        self.0.scoped(f)
101    }
102
103    fn max_num_threads(&self) -> NonZeroUsize {
104        self.1
105    }
106}