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`]
14#[derive(Clone)]
15pub struct YastlPool(Pool, NonZeroUsize);
16
17impl YastlPool {
18    /// Create a new Pool that will execute it's tasks on `num_threads` worker threads.
19    pub fn new(num_threads: usize) -> Self {
20        let num_threads = num_threads.min(1);
21        let pool = Pool::new(num_threads);
22        #[allow(clippy::missing_panics_doc)]
23        Self(pool, NonZeroUsize::new(num_threads).expect(">0"))
24    }
25
26    /// Create a new Pool that will execute it's tasks on `num_threads` worker threads and
27    /// spawn them using the given `config`.
28    pub fn with_config(num_threads: usize, config: ThreadConfig) -> Self {
29        let num_threads = num_threads.min(1);
30        let pool = Pool::with_config(num_threads, config);
31        #[allow(clippy::missing_panics_doc)]
32        Self(pool, NonZeroUsize::new(num_threads).expect(">0"))
33    }
34
35    /// Reference to wrapped `yastl::Pool`.
36    pub fn inner(&self) -> &Pool {
37        &self.0
38    }
39
40    /// Mutable reference to wrapped `yastl::Pool`.
41    pub fn inner_mut(&mut self) -> &mut Pool {
42        &mut self.0
43    }
44
45    /// Returns the wrapped `yastl::Pool`.
46    pub fn into_inner(self) -> Pool {
47        self.0
48    }
49}
50
51impl ParThreadPool for YastlPool {
52    type ScopeRef<'s, 'env, 'scope>
53        = &'s Scope<'scope>
54    where
55        'scope: 's,
56        'env: 'scope + 's;
57
58    fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope>, work: W)
59    where
60        'scope: 's,
61        'env: 'scope + 's,
62        W: Fn() + Send + 'scope + 'env,
63    {
64        s.execute(work);
65    }
66
67    fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
68    where
69        'env: 'scope,
70        for<'s> F: FnOnce(&'s Scope<'scope>) + Send,
71    {
72        self.0.scoped(f)
73    }
74
75    fn max_num_threads(&self) -> NonZeroUsize {
76        self.1
77    }
78}
79
80impl ParThreadPool for &YastlPool {
81    type ScopeRef<'s, 'env, 'scope>
82        = &'s Scope<'scope>
83    where
84        'scope: 's,
85        'env: 'scope + 's;
86
87    fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope>, work: W)
88    where
89        'scope: 's,
90        'env: 'scope + 's,
91        W: Fn() + Send + 'scope + 'env,
92    {
93        s.execute(work);
94    }
95
96    fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
97    where
98        'env: 'scope,
99        for<'s> F: FnOnce(&'s Scope<'scope>) + Send,
100    {
101        self.0.scoped(f)
102    }
103
104    fn max_num_threads(&self) -> NonZeroUsize {
105        self.1
106    }
107}