GCC Code Coverage Report


Directory: ./
File: libs/capy/include/boost/capy/ex/thread_pool.hpp
Date: 2026-01-20 10:35:39
Exec Total Coverage
Lines: 16 16 100.0%
Functions: 7 7 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/boostorg/capy
8 //
9
10 #ifndef BOOST_CAPY_EX_THREAD_POOL_HPP
11 #define BOOST_CAPY_EX_THREAD_POOL_HPP
12
13 #include <boost/capy/detail/config.hpp>
14 #include <boost/capy/ex/any_coro.hpp>
15 #include <boost/capy/ex/execution_context.hpp>
16 #include <cstddef>
17
18 namespace boost {
19 namespace capy {
20
21 /** A pool of threads for executing work concurrently.
22
23 Use this when you need to run coroutines on multiple threads
24 without the overhead of creating and destroying threads for
25 each task. Work items are distributed across the pool using
26 a shared queue.
27
28 @par Thread Safety
29 Distinct objects: Safe.
30 Shared objects: Unsafe.
31
32 @par Example
33 @code
34 thread_pool pool(4); // 4 worker threads
35 auto ex = pool.get_executor();
36 ex.post(some_coroutine);
37 // pool destructor waits for all work to complete
38 @endcode
39 */
40 class BOOST_CAPY_DECL
41 thread_pool
42 : public execution_context
43 {
44 class impl;
45 impl* impl_;
46
47 public:
48 class executor_type;
49
50 /** Destroy the thread pool.
51
52 Signals all worker threads to stop, waits for them to
53 finish, and destroys any pending work items.
54 */
55 ~thread_pool();
56
57 /** Construct a thread pool.
58
59 Creates a pool with the specified number of worker threads.
60 If `num_threads` is zero, the number of threads is set to
61 the hardware concurrency, or one if that cannot be determined.
62
63 @param num_threads The number of worker threads, or zero
64 for automatic selection.
65 */
66 explicit
67 thread_pool(std::size_t num_threads = 0);
68
69 thread_pool(thread_pool const&) = delete;
70 thread_pool& operator=(thread_pool const&) = delete;
71
72 /** Request all worker threads to stop.
73
74 Signals all threads to exit via stop token. Threads will
75 finish their current work item before exiting. Does not
76 wait for threads to exit.
77 */
78 void
79 stop() noexcept;
80
81 /** Return an executor for this thread pool.
82
83 @return An executor associated with this thread pool.
84 */
85 executor_type
86 get_executor() const noexcept;
87 };
88
89 //------------------------------------------------------------------------------
90
91 /** An executor that submits work to a thread_pool.
92
93 Executors are lightweight handles that can be copied and stored.
94 All copies refer to the same underlying thread pool.
95
96 @par Thread Safety
97 Distinct objects: Safe.
98 Shared objects: Safe.
99 */
100 class thread_pool::executor_type
101 {
102 friend class thread_pool;
103
104 thread_pool* pool_ = nullptr;
105
106 explicit
107 51 executor_type(thread_pool& pool) noexcept
108 51 : pool_(&pool)
109 {
110 51 }
111
112 public:
113 /// Default construct a null executor.
114 executor_type() = default;
115
116 /// Return the underlying thread pool.
117 thread_pool&
118 27 context() const noexcept
119 {
120 27 return *pool_;
121 }
122
123 /// Notify that work has started (no-op for thread pools).
124 void
125 4 on_work_started() const noexcept
126 {
127 4 }
128
129 /// Notify that work has finished (no-op for thread pools).
130 void
131 4 on_work_finished() const noexcept
132 {
133 4 }
134
135 /** Dispatch a coroutine for execution.
136
137 Posts the coroutine to the thread pool and returns
138 immediately. The caller should suspend after calling
139 this function.
140
141 @param h The coroutine handle to execute.
142
143 @return A noop coroutine handle to resume.
144 */
145 any_coro
146 3 dispatch(any_coro h) const
147 {
148 3 post(h);
149 3 return std::noop_coroutine();
150 }
151
152 /** Post a coroutine to the thread pool.
153
154 The coroutine will be resumed on one of the pool's
155 worker threads.
156
157 @param h The coroutine handle to execute.
158 */
159 BOOST_CAPY_DECL
160 void
161 post(any_coro h) const;
162
163 /// Return true if two executors refer to the same thread pool.
164 bool
165 16 operator==(executor_type const& other) const noexcept
166 {
167 16 return pool_ == other.pool_;
168 }
169 };
170
171 //------------------------------------------------------------------------------
172
173 inline
174 auto
175 51 thread_pool::
176 get_executor() const noexcept ->
177 executor_type
178 {
179 51 return executor_type(const_cast<thread_pool&>(*this));
180 }
181
182 } // capy
183 } // boost
184
185 #endif
186