GCC Code Coverage Report


Directory: ./
File: libs/capy/include/boost/capy/ex/thread_pool.hpp
Date: 2026-01-15 23:24:40
Exec Total Coverage
Lines: 19 19 100.0%
Functions: 8 8 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 /** Return an executor for this thread pool.
73
74 @return An executor associated with this thread pool.
75 */
76 executor_type
77 get_executor() const noexcept;
78 };
79
80 //------------------------------------------------------------------------------
81
82 /** An executor that submits work to a thread_pool.
83
84 Executors are lightweight handles that can be copied and stored.
85 All copies refer to the same underlying thread pool.
86
87 @par Thread Safety
88 Distinct objects: Safe.
89 Shared objects: Safe.
90 */
91 class thread_pool::executor_type
92 {
93 friend class thread_pool;
94
95 thread_pool* pool_ = nullptr;
96
97 explicit
98 11 executor_type(thread_pool& pool) noexcept
99 11 : pool_(&pool)
100 {
101 11 }
102
103 public:
104 /// Default construct a null executor.
105 executor_type() = default;
106
107 /// Return the underlying thread pool.
108 thread_pool&
109 1 context() const noexcept
110 {
111 1 return *pool_;
112 }
113
114 /// Notify that work has started (no-op for thread pools).
115 void
116 2 on_work_started() const noexcept
117 {
118 2 }
119
120 /// Notify that work has finished (no-op for thread pools).
121 void
122 2 on_work_finished() const noexcept
123 {
124 2 }
125
126 /** Submit a coroutine for execution.
127
128 Posts the coroutine to the thread pool and returns
129 immediately. The caller should suspend after calling
130 this function.
131
132 @param h The coroutine handle to execute.
133
134 @return A noop coroutine handle to resume.
135 */
136 any_coro
137 1 dispatch(any_coro h) const
138 {
139 1 post(h);
140 1 return std::noop_coroutine();
141 }
142
143 /** Post a coroutine to the thread pool.
144
145 The coroutine will be resumed on one of the pool's
146 worker threads.
147
148 @param h The coroutine handle to execute.
149 */
150 BOOST_CAPY_DECL
151 void
152 post(any_coro h) const;
153
154 /** Defer a coroutine to the thread pool.
155
156 Equivalent to post() for thread pools.
157
158 @param h The coroutine handle to execute.
159 */
160 void
161 1 defer(any_coro h) const
162 {
163 1 post(h);
164 1 }
165
166 /// Return true if two executors refer to the same thread pool.
167 bool
168 3 operator==(executor_type const& other) const noexcept
169 {
170 3 return pool_ == other.pool_;
171 }
172 };
173
174 //------------------------------------------------------------------------------
175
176 inline
177 auto
178 11 thread_pool::
179 get_executor() const noexcept ->
180 executor_type
181 {
182 11 return executor_type(const_cast<thread_pool&>(*this));
183 }
184
185 } // capy
186 } // boost
187
188 #endif
189