LCOV - code coverage report
Current view: top level - boost/capy/ex - thread_pool.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 16 16
Test Date: 2026-01-23 22:12:31 Functions: 100.0 % 7 7

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

Generated by: LCOV version 2.3