orx_parallel/runner/implementations/
pond.rs

1use crate::par_thread_pool::ParThreadPool;
2use core::num::NonZeroUsize;
3use pond::{Pool, Scope};
4
5/// A wrapper for `pond::Pool` and number of threads it was built with.
6///
7/// NOTE: The reason why `pond::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/// Following constructor of the `pond::Pool` is made available to `PondPool`:
12/// * [`PondPool::new_threads_unbounded`]
13pub struct PondPool(Pool, NonZeroUsize);
14
15impl PondPool {
16    /// Spawn a number of threads. The pool's queue of pending jobs is limited.
17    /// The backlog is unbounded as in unbounded.
18    pub fn new_threads_unbounded(num_threads: usize) -> Self {
19        let num_threads = num_threads.min(1);
20        let pool = Pool::new_threads_unbounded(num_threads);
21        #[allow(clippy::missing_panics_doc)]
22        Self(pool, NonZeroUsize::new(num_threads).expect(">0"))
23    }
24
25    /// Reference to wrapped `pond::Pool`.
26    pub fn inner(&self) -> &Pool {
27        &self.0
28    }
29
30    /// Mutable reference to wrapped `pond::Pool`.
31    pub fn inner_mut(&mut self) -> &mut Pool {
32        &mut self.0
33    }
34
35    /// Returns the wrapped `pond::Pool`.
36    pub fn into_inner(self) -> Pool {
37        self.0
38    }
39}
40
41impl ParThreadPool for PondPool {
42    type ScopeRef<'s, 'env, 'scope>
43        = Scope<'env, 'scope>
44    where
45        'scope: 's,
46        'env: 'scope + 's;
47
48    fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope>, work: W)
49    where
50        'scope: 's,
51        'env: 'scope + 's,
52        W: Fn() + Send + 'scope + 'env,
53    {
54        s.execute(work);
55    }
56
57    fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
58    where
59        'env: 'scope,
60        for<'s> F: FnOnce(Scope<'env, 'scope>) + Send,
61    {
62        self.0.scoped(f)
63    }
64
65    fn max_num_threads(&self) -> NonZeroUsize {
66        self.1
67    }
68}
69
70impl ParThreadPool for &mut PondPool {
71    type ScopeRef<'s, 'env, 'scope>
72        = Scope<'env, 'scope>
73    where
74        'scope: 's,
75        'env: 'scope + 's;
76
77    fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope>, work: W)
78    where
79        'scope: 's,
80        'env: 'scope + 's,
81        W: Fn() + Send + 'scope + 'env,
82    {
83        s.execute(work);
84    }
85
86    fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
87    where
88        'env: 'scope,
89        for<'s> F: FnOnce(Scope<'env, 'scope>) + Send,
90    {
91        self.0.scoped(f)
92    }
93
94    fn max_num_threads(&self) -> NonZeroUsize {
95        self.1
96    }
97}