![]() |
Autonomy Software C++ 24.5.1
Welcome to the Autonomy Software repository of the Mars Rover Design Team (MRDT) at Missouri University of Science and Technology (Missouri S&T)! API reference contains the source code and other resources for the development of the autonomy software for our Mars rover. The Autonomy Software project aims to compete in the University Rover Challenge (URC) by demonstrating advanced autonomous capabilities and robust navigation algorithms.
|
A fast, lightweight, modern, and easy-to-use C++17/C++20/C++23 thread pool class. More...
#include <BS_thread_pool.hpp>

Public Member Functions | |
| thread_pool () | |
Construct a new thread pool. The number of threads will be the total number of hardware threads available, as reported by the implementation. This is usually determined by the number of cores in the CPU. If a core is hyperthreaded, it will count as two threads. If the native extensions are enabled, the pool will instead use the number of threads available to the process, as obtained from BS::get_os_process_affinity(), which can be less than the number of hardware threads. | |
| thread_pool (const std::size_t num_threads) | |
| Construct a new thread pool with the specified number of threads. | |
| template<BS_THREAD_POOL_INIT_FUNC_CONCEPT(F) > | |
| thread_pool (F &&init) | |
| Construct a new thread pool with the specified initialization function and the default number of threads. | |
| template<BS_THREAD_POOL_INIT_FUNC_CONCEPT(F) > | |
| thread_pool (const std::size_t num_threads, F &&init) | |
| Construct a new thread pool with the specified number of threads and initialization function. | |
| thread_pool (const thread_pool &)=delete | |
| thread_pool (thread_pool &&)=delete | |
| thread_pool & | operator= (const thread_pool &)=delete |
| thread_pool & | operator= (thread_pool &&)=delete |
| ~thread_pool () noexcept | |
| Destruct the thread pool. Waits for all tasks to complete, then destroys all threads. If a cleanup function was set, it will run in each thread right before it is destroyed. Note that if the pool is paused, then any tasks still in the queue will never be executed. | |
| template<typename T1 , typename T2 , typename T = common_index_type_t<T1, T2>, typename F > | |
| void | detach_blocks (const T1 first_index, const T2 index_after_last, F &&block, const std::size_t num_blocks=0, const priority_t priority=0) |
Parallelize a loop by automatically splitting it into blocks and submitting each block separately to the queue, with the specified priority. The block function takes two arguments, the start and end of the block, so that it is only called once per block, but it is up to the user to make sure the block function correctly deals with all the indices in each block. Does not return a BS::multi_future, so the user must use wait() or some other method to ensure that the loop finishes executing, otherwise bad things will happen. | |
| template<typename I > | |
| void | detach_bulk (const I first, const I last, const priority_t priority=0) |
Submit an iterator range containing functions with no arguments and no return values into the task queue, with the specified priority. To submit functions with arguments, enclose them in lambda expressions. Does not return a BS::multi_future, so the user must use wait() or some other method to ensure that the loop finishes executing, otherwise bad things will happen. | |
| template<typename C > | |
| void | detach_bulk (C &container, const priority_t priority=0) |
Submit a container of functions with no arguments and no return values into the task queue, with the specified priority. To submit functions with arguments, enclose them in lambda expressions. Does not return a BS::multi_future, so the user must use wait() or some other method to ensure that the loop finishes executing, otherwise bad things will happen. | |
| template<typename T1 , typename T2 , typename T = common_index_type_t<T1, T2>, typename F > | |
| void | detach_loop (const T1 first_index, const T2 index_after_last, F &&loop, const std::size_t num_blocks=0, const priority_t priority=0) |
Parallelize a loop by automatically splitting it into blocks and submitting each block separately to the queue, with the specified priority. The loop function takes one argument, the loop index, and it is called exactly once per index, but many times per block. Does not return a BS::multi_future, so the user must use wait() or some other method to ensure that the loop finishes executing, otherwise bad things will happen. | |
| template<typename T1 , typename T2 , typename T = common_index_type_t<T1, T2>, typename F > | |
| void | detach_sequence (const T1 first_index, const T2 index_after_last, F &&sequence, const priority_t priority=0) |
Submit a sequence of tasks enumerated by indices to the queue, with the specified priority. The sequence function takes one argument, the task index, and will be called once per index. Does not return a BS::multi_future, so the user must use wait() or some other method to ensure that the sequence finishes executing, otherwise bad things will happen. | |
| template<typename F > | |
| void | detach_task (F &&task, const priority_t priority=0) |
Submit a function with no arguments and no return value into the task queue, with the specified priority. To submit a function with arguments, enclose it in a lambda expression. Does not return a future, so the user must use wait() or some other method to ensure that the task finishes executing, otherwise bad things will happen. | |
| std::size_t | get_tasks_queued () const |
| Get the number of tasks currently waiting in the queue to be executed by the threads. | |
| std::size_t | get_tasks_running () const |
| Get the number of tasks currently being executed by the threads. | |
| std::size_t | get_tasks_total () const |
Get the total number of unfinished tasks: either still waiting in the queue, or running in a thread. Note that get_tasks_total() == get_tasks_queued() + get_tasks_running(). | |
| std::size_t | get_thread_count () const noexcept |
| Get the number of threads in the pool. | |
| std::vector< thread_t::id > | get_thread_ids () const |
Get a vector containing the unique identifiers for each of the pool's threads, as obtained by std::thread::get_id() (or std::jthread::get_id() in C++20 and later). | |
| BS_THREAD_POOL_IF_PAUSE_ENABLED bool | is_paused () const |
Check whether the pool is currently paused. Only enabled if the flag BS::tp::pause is enabled in the template parameter. | |
| BS_THREAD_POOL_IF_PAUSE_ENABLED void | pause () |
Pause the pool. The workers will temporarily stop retrieving new tasks out of the queue, although any tasks already executing will keep running until they are finished. Only enabled if the flag BS::tp::pause is enabled in the template parameter. | |
| void | purge () |
| Purge all the tasks waiting in the queue. Tasks that are currently running will not be affected, but any tasks still waiting in the queue will be discarded, and will never be executed by the threads. Please note that there is no way to restore the purged tasks. | |
| void | reset () |
| Reset the pool with the default number of threads (as if constructed with the default constructor). Waits for all tasks to be completed, both running and queued, then destroys the thread pool and creates a new one with an empty task queue. If pausing is enabled, only waits for tasks that are currently running before destroying the pool; once the pool is reset, it will then resume executing the tasks that remained in the queue and any newly submitted tasks. If the pool was paused before resetting it, the new pool will be paused as well. | |
| void | reset (const std::size_t num_threads) |
| Reset the pool with a new number of threads. Waits for all tasks to be completed, both running and queued, then destroys the thread pool and creates a new one with an empty task queue. If pausing is enabled, only waits for tasks that are currently running before destroying the pool; once the pool is reset, it will then resume executing the tasks that remained in the queue and any newly submitted tasks. If the pool was paused before resetting it, the new pool will be paused as well. | |
| template<BS_THREAD_POOL_INIT_FUNC_CONCEPT(F) > | |
| void | reset (F &&init) |
| Reset the pool with the default number of threads and a new initialization function. Waits for all tasks to be completed, both running and queued, then destroys the thread pool and creates a new one with an empty task queue. If pausing is enabled, only waits for tasks that are currently running before destroying the pool; once the pool is reset, it will then resume executing the tasks that remained in the queue and any newly submitted tasks. If the pool was paused before resetting it, the new pool will be paused as well. | |
| template<BS_THREAD_POOL_INIT_FUNC_CONCEPT(F) > | |
| void | reset (const std::size_t num_threads, F &&init) |
| Reset the pool with a new number of threads and a new initialization function. Waits for all tasks to be completed, both running and queued, then destroys the thread pool and creates a new one with an empty task queue. If pausing is enabled, only waits for tasks that are currently running before destroying the pool; once the pool is reset, it will then resume executing the tasks that remained in the queue and any newly submitted tasks. If the pool was paused before resetting it, the new pool will be paused as well. | |
| template<BS_THREAD_POOL_INIT_FUNC_CONCEPT(F) > | |
| void | set_cleanup_func (F &&cleanup) |
| Set the thread pool's cleanup function. | |
| template<typename T1 , typename T2 , typename T = common_index_type_t<T1, T2>, typename F , typename R = std::invoke_result_t<std::decay_t<F>, T, T>> | |
| multi_future< R > | submit_blocks (const T1 first_index, const T2 index_after_last, F &&block, const std::size_t num_blocks=0, const priority_t priority=0) |
Parallelize a loop by automatically splitting it into blocks and submitting each block separately to the queue, with the specified priority. The block function takes two arguments, the start and end of the block, so that it is only called once per block, but it is up to the user to make sure the block function correctly deals with all the indices in each block. If the block function has a return value, get a BS::multi_future for the eventual returned values. If the block function has no return value, get a BS::multi_future<void> which can be used to wait until all the tasks finish. | |
| template<typename I , typename F = decltype(*std::declval<I>()), typename R = std::invoke_result_t<std::decay_t<F>>> | |
| multi_future< R > | submit_bulk (const I first, const I last, const priority_t priority=0) |
Submit an iterator range containing functions with no arguments into the task queue, with the specified priority. To submit functions with arguments, enclose them in lambda expressions. If the functions have return values, get a BS::multi_future for the eventual returned values. If the functions have no return values, get a BS::multi_future<void> which can be used to wait until all the tasks finish. | |
| template<typename C , typename F = decltype(*std::declval<C&>().begin()), typename R = std::invoke_result_t<std::decay_t<F>>> | |
| multi_future< R > | submit_bulk (C &container, const priority_t priority=0) |
Submit a container of functions with no arguments into the task queue, with the specified priority. To submit functions with arguments, enclose them in lambda expressions. If the functions have return values, get a BS::multi_future for the eventual returned values. If the functions have no return values, get a BS::multi_future<void> which can be used to wait until all the tasks finish. | |
| template<typename T1 , typename T2 , typename T = common_index_type_t<T1, T2>, typename F > | |
| multi_future< void > | submit_loop (const T1 first_index, const T2 index_after_last, F &&loop, const std::size_t num_blocks=0, const priority_t priority=0) |
Parallelize a loop by automatically splitting it into blocks and submitting each block separately to the queue, with the specified priority. The loop function takes one argument, the loop index, and it is called exactly once per index, but many times per block. Returns a BS::multi_future which can be used to wait until all the tasks finish. | |
| template<typename T1 , typename T2 , typename T = common_index_type_t<T1, T2>, typename F , typename R = std::invoke_result_t<std::decay_t<F>, T>> | |
| multi_future< R > | submit_sequence (const T1 first_index, const T2 index_after_last, F &&sequence, const priority_t priority=0) |
Submit a sequence of tasks enumerated by indices to the queue, with the specified priority. The sequence function takes one argument, the task index, and will be called once per index. If the sequence function has a return value, get a BS::multi_future for the eventual returned values. If the sequence function has no return value, get a BS::multi_future<void> which can be used to wait until all the tasks finish. | |
| template<typename F , typename R = std::invoke_result_t<std::decay_t<F>>> | |
| std::future< R > | submit_task (F &&task, const priority_t priority=0) |
Submit a function with no arguments into the task queue, with the specified priority. To submit a function with arguments, enclose it in a lambda expression. If the function has a return value, get a future for the eventual returned value. If the function has no return value, get an std::future<void> which can be used to wait until the task finishes. | |
| BS_THREAD_POOL_IF_PAUSE_ENABLED void | unpause () |
Unpause the pool. The workers will resume retrieving new tasks out of the queue. Only enabled if the flag BS::tp::pause is enabled in the template parameter. | |
| void | wait () |
Wait for tasks to be completed. Normally, this function waits for all tasks, both those that are currently running in the threads and those that are still waiting in the queue. However, if the pool is paused, this function only waits for the currently running tasks (otherwise it would wait forever). Note: To wait for just one specific task, use submit_task() instead, and call the wait() member function of the generated future. | |
| template<typename R , typename P > | |
| bool | wait_for (const std::chrono::duration< R, P > &duration) |
| Wait for tasks to be completed, but stop waiting after the specified duration has passed. | |
| template<typename C , typename D > | |
| bool | wait_until (const std::chrono::time_point< C, D > &timeout_time) |
| Wait for tasks to be completed, but stop waiting after the specified time point has been reached. | |
Static Public Attributes | |
| static constexpr bool | priority_enabled = (OptFlags & tp::priority) != tp::none |
| A flag indicating whether task priority is enabled. | |
| static constexpr bool | pause_enabled = (OptFlags & tp::pause) != tp::none |
| A flag indicating whether pausing is enabled. | |
| static constexpr bool | wait_deadlock_checks_enabled = (OptFlags & tp::wait_deadlock_checks) != tp::none |
| A flag indicating whether wait deadlock checks are enabled. | |
Private Member Functions | |
| template<typename F > | |
| void | create_threads (const std::size_t num_threads, F &&init) |
| Create the threads in the pool and assign a worker to each thread. | |
| void | destroy_threads () |
| Destroy the threads in the pool. | |
| template<typename T , typename F , typename R , bool submit, typename N = std::conditional_t<submit, multi_future<R>, void>> | |
| N | enqueue_blocks (const T first_index, const T index_after_last, F &&block, std::size_t num_blocks, const priority_t priority=0) |
A helper function for detach_blocks() and submit_blocks(). | |
| template<typename T , typename F , bool submit, typename N = std::conditional_t<submit, multi_future<void>, void>> | |
| N | enqueue_loop (const T first_index, const T index_after_last, F &&loop, std::size_t num_blocks, const priority_t priority=0) |
A helper function for detach_loop() and submit_loop(). | |
| template<typename T , typename F , typename R , bool submit, typename N = std::conditional_t<submit, multi_future<R>, void>> | |
| N | enqueue_sequence (const T first_index, const T index_after_last, F &&sequence, const priority_t priority=0) |
A helper function for detach_sequence() and submit_sequence(). | |
| task_t | pop_task () |
| Pop a task from the queue. | |
| template<typename F > | |
| void | reset_pool (const std::size_t num_threads, F &&init) |
Reset the pool with a new number of threads and a new initialization function. This member function implements the actual reset, while the public member function reset() also handles the case where the pool is paused. | |
| void | worker (BS_THREAD_POOL_WORKER_TOKEN const std::size_t idx) |
A worker function to be assigned to each thread in the pool. Waits until it is notified by detach_task() that a task is available, and then retrieves the task from the queue and executes it. Once the task finishes, the worker notifies wait() in case it is waiting. | |
Static Private Member Functions | |
| static std::size_t | determine_thread_count (const std::size_t num_threads) noexcept(!thread_pool_native_extensions) |
| Determine how many threads the pool should have, based on the parameter passed to the constructor or reset(). | |
Private Attributes | |
| std::mutex | tasks_mutex |
| A mutex to synchronize access to the task queue by different threads. | |
| std::condition_variable | task_available_cv |
A condition variable to notify worker() that a new task has become available. | |
| std::condition_variable | tasks_done_cv |
A condition variable to notify wait() that the tasks are done. | |
| move_only_function< void(std::size_t)> | cleanup_func = [](std::size_t) {} |
A cleanup function to run in each thread right before it is destroyed, which will happen when the pool is destructed or reset. The function must have no return value, and can either take one argument, the thread index of type std::size_t, or zero arguments. The cleanup function must not throw any exceptions, as that will result in program termination. Any exceptions must be handled explicitly within the function. The default is an empty function, i.e., no cleanup will be performed. | |
| move_only_function< void(std::size_t)> | init_func = [](std::size_t) {} |
An initialization function to run in each thread before it starts executing any submitted tasks. The function must have no return value, and can either take one argument, the thread index of type std::size_t, or zero arguments. It will be executed exactly once per thread, when the thread is first constructed. The initialization function must not throw any exceptions, as that will result in program termination. Any exceptions must be handled explicitly within the function. The default is an empty function, i.e., no initialization will be performed. | |
| std::conditional_t< priority_enabled, std::priority_queue< pr_task >, std::queue< task_t > > | tasks |
| A queue of tasks to be executed by the threads. | |
| std::size_t | tasks_running = 0 |
| A counter for the total number of currently running tasks. | |
| std::size_t | thread_count = 0 |
| The number of threads in the pool. | |
| std::unique_ptr< thread_t[]> | threads = nullptr |
| A smart pointer to manage the memory allocated for the threads. | |
| std::conditional_t< pause_enabled, bool, std::monostate > | paused = {} |
A flag indicating whether the workers should pause. When set to true, the workers temporarily stop retrieving new tasks out of the queue, although any tasks already executing will keep running until they are finished. When set to false again, the workers resume retrieving tasks. Only enabled if the flag BS::tp::pause is enabled in the template parameter. | |
| bool | waiting = false |
A flag indicating that wait() is active and expects to be notified whenever a task is done. | |
| bool | workers_running = false |
A flag indicating to the workers to keep running. When set to false, the workers terminate permanently. | |
A fast, lightweight, modern, and easy-to-use C++17/C++20/C++23 thread pool class.
| OptFlags | A bitmask of flags which can be used to enable optional features. The flags are members of the BS::tp enumeration: BS::tp::priority, BS::tp::pause, and BS::tp::wait_deadlock_checks. The default is BS::tp::none, which disables all optional features. To enable multiple features, use the bitwise OR operator |, e.g. BS::tp::priority | BS::tp::pause. |
|
inline |
Construct a new thread pool. The number of threads will be the total number of hardware threads available, as reported by the implementation. This is usually determined by the number of cores in the CPU. If a core is hyperthreaded, it will count as two threads. If the native extensions are enabled, the pool will instead use the number of threads available to the process, as obtained from BS::get_os_process_affinity(), which can be less than the number of hardware threads.
|
inlineexplicit |
Construct a new thread pool with the specified number of threads.
| num_threads | The number of threads to use. |
|
inlineexplicit |
Construct a new thread pool with the specified initialization function and the default number of threads.
| init | An initialization function to run in each thread before it starts executing any submitted tasks. The function must have no return value, and can either take one argument, the thread index of type std::size_t, or zero arguments. It will be executed exactly once per thread, when the thread is first constructed. The initialization function must not throw any exceptions, as that will result in program termination. Any exceptions must be handled explicitly within the function. |
|
inline |
Construct a new thread pool with the specified number of threads and initialization function.
| num_threads | The number of threads to use. |
| init | An initialization function to run in each thread before it starts executing any submitted tasks. The function must have no return value, and can either take one argument, the thread index of type std::size_t, or zero arguments. It will be executed exactly once per thread, when the thread is first constructed. The initialization function must not throw any exceptions, as that will result in program termination. Any exceptions must be handled explicitly within the function. |
|
inlinenoexcept |
Destruct the thread pool. Waits for all tasks to complete, then destroys all threads. If a cleanup function was set, it will run in each thread right before it is destroyed. Note that if the pool is paused, then any tasks still in the queue will never be executed.
|
inline |
Parallelize a loop by automatically splitting it into blocks and submitting each block separately to the queue, with the specified priority. The block function takes two arguments, the start and end of the block, so that it is only called once per block, but it is up to the user to make sure the block function correctly deals with all the indices in each block. Does not return a BS::multi_future, so the user must use wait() or some other method to ensure that the loop finishes executing, otherwise bad things will happen.
| T1 | The type of the first index. Should be a signed or unsigned integer. |
| T2 | The type of the index after the last index. Should be a signed or unsigned integer. |
| T | The common type of the indices, as determined by BS::common_index_type_t<T1, T2>. |
| F | The type of the block function. |
| first_index | The first index in the loop. |
| index_after_last | The index after the last index in the loop. The loop will iterate from first_index to (index_after_last - 1) inclusive. In other words, it will be equivalent to for (T i = first_index; i < index_after_last; ++i). Note that if index_after_last <= first_index, no tasks will be submitted. |
| block | A function that will be called once per block. Should take exactly two arguments: the first index in the block and the index after the last index in the block. block(start, end) should typically involve a loop of the form for (T i = start; i < end; ++i). Must not return a value. |
| num_blocks | The maximum number of blocks to split the loop into. The default is 0, which means the number of blocks will be equal to the number of threads in the pool. |
| priority | The priority of the tasks. Should be between -128 and +127 (a signed 8-bit integer). The default is 0. Only taken into account if the flag BS::tp::priority is enabled in the template parameter, otherwise has no effect. |

|
inline |
Submit an iterator range containing functions with no arguments and no return values into the task queue, with the specified priority. To submit functions with arguments, enclose them in lambda expressions. Does not return a BS::multi_future, so the user must use wait() or some other method to ensure that the loop finishes executing, otherwise bad things will happen.
| I | The type of the iterators. |
| first | An iterator to the first function. |
| last | An iterator to one past the last function. |
| priority | The priority of the tasks. Should be between -128 and +127 (a signed 8-bit integer). The default is 0. Only taken into account if the flag BS::tp::priority is enabled in the template parameter, otherwise has no effect. |
|
inline |
Submit a container of functions with no arguments and no return values into the task queue, with the specified priority. To submit functions with arguments, enclose them in lambda expressions. Does not return a BS::multi_future, so the user must use wait() or some other method to ensure that the loop finishes executing, otherwise bad things will happen.
| C | The type of the container. Must either be an array or have begin() and end() member functions. |
| container | The container. |
| priority | The priority of the tasks. Should be between -128 and +127 (a signed 8-bit integer). The default is 0. Only taken into account if the flag BS::tp::priority is enabled in the template parameter, otherwise has no effect. |
|
inline |
Parallelize a loop by automatically splitting it into blocks and submitting each block separately to the queue, with the specified priority. The loop function takes one argument, the loop index, and it is called exactly once per index, but many times per block. Does not return a BS::multi_future, so the user must use wait() or some other method to ensure that the loop finishes executing, otherwise bad things will happen.
| T1 | The type of the first index. Should be a signed or unsigned integer. |
| T2 | The type of the index after the last index. Should be a signed or unsigned integer. |
| T | The common type of the indices, as determined by BS::common_index_type_t<T1, T2>. |
| F | The type of the loop function. |
| first_index | The first index in the loop. |
| index_after_last | The index after the last index in the loop. The loop will iterate from first_index to (index_after_last - 1) inclusive. In other words, it will be equivalent to for (T i = first_index; i < index_after_last; ++i). Note that if index_after_last <= first_index, no tasks will be submitted. |
| loop | A function that will be called once per index, many times per block. Should take exactly one argument: the loop index. Must not return a value. |
| num_blocks | The maximum number of blocks to split the loop into. The default is 0, which means the number of blocks will be equal to the number of threads in the pool. |
| priority | The priority of the tasks. Should be between -128 and +127 (a signed 8-bit integer). The default is 0. Only taken into account if the flag BS::tp::priority is enabled in the template parameter, otherwise has no effect. |
|
inline |
Submit a sequence of tasks enumerated by indices to the queue, with the specified priority. The sequence function takes one argument, the task index, and will be called once per index. Does not return a BS::multi_future, so the user must use wait() or some other method to ensure that the sequence finishes executing, otherwise bad things will happen.
| T1 | The type of the first index. Should be a signed or unsigned integer. |
| T2 | The type of the index after the last index. Should be a signed or unsigned integer. |
| T | The common type of the indices, as determined by BS::common_index_type_t<T1, T2>. |
| F | The type of the sequence function. |
| first_index | The first index in the sequence. |
| index_after_last | The index after the last index in the sequence. The sequence will iterate from first_index to (index_after_last - 1) inclusive. In other words, it will be equivalent to for (T i = first_index; i < index_after_last; ++i). Note that if index_after_last <= first_index, no tasks will be submitted. |
| sequence | A function that will be called once per index. Should take exactly one argument, the index. Must not return a value. |
| priority | The priority of the tasks. Should be between -128 and +127 (a signed 8-bit integer). The default is 0. Only taken into account if the flag BS::tp::priority is enabled in the template parameter, otherwise has no effect. |
|
inline |
Submit a function with no arguments and no return value into the task queue, with the specified priority. To submit a function with arguments, enclose it in a lambda expression. Does not return a future, so the user must use wait() or some other method to ensure that the task finishes executing, otherwise bad things will happen.
| F | The type of the function. |
| task | The function to submit. |
| priority | The priority of the task. Should be between -128 and +127 (a signed 8-bit integer). The default is 0. Only taken into account if the flag BS::tp::priority is enabled in the template parameter, otherwise has no effect. |

|
inline |
Get the number of tasks currently waiting in the queue to be executed by the threads.

|
inline |
Get the number of tasks currently being executed by the threads.
|
inline |
Get the total number of unfinished tasks: either still waiting in the queue, or running in a thread. Note that get_tasks_total() == get_tasks_queued() + get_tasks_running().

|
inlinenoexcept |
Get the number of threads in the pool.

|
inline |
Get a vector containing the unique identifiers for each of the pool's threads, as obtained by std::thread::get_id() (or std::jthread::get_id() in C++20 and later).
|
inline |
Check whether the pool is currently paused. Only enabled if the flag BS::tp::pause is enabled in the template parameter.
true if the pool is paused, false if it is not paused.
|
inline |
Pause the pool. The workers will temporarily stop retrieving new tasks out of the queue, although any tasks already executing will keep running until they are finished. Only enabled if the flag BS::tp::pause is enabled in the template parameter.

|
inline |
Purge all the tasks waiting in the queue. Tasks that are currently running will not be affected, but any tasks still waiting in the queue will be discarded, and will never be executed by the threads. Please note that there is no way to restore the purged tasks.

|
inline |
Reset the pool with the default number of threads (as if constructed with the default constructor). Waits for all tasks to be completed, both running and queued, then destroys the thread pool and creates a new one with an empty task queue. If pausing is enabled, only waits for tasks that are currently running before destroying the pool; once the pool is reset, it will then resume executing the tasks that remained in the queue and any newly submitted tasks. If the pool was paused before resetting it, the new pool will be paused as well.

|
inline |
Reset the pool with a new number of threads. Waits for all tasks to be completed, both running and queued, then destroys the thread pool and creates a new one with an empty task queue. If pausing is enabled, only waits for tasks that are currently running before destroying the pool; once the pool is reset, it will then resume executing the tasks that remained in the queue and any newly submitted tasks. If the pool was paused before resetting it, the new pool will be paused as well.
| num_threads | The number of threads to use. |
|
inline |
Reset the pool with the default number of threads and a new initialization function. Waits for all tasks to be completed, both running and queued, then destroys the thread pool and creates a new one with an empty task queue. If pausing is enabled, only waits for tasks that are currently running before destroying the pool; once the pool is reset, it will then resume executing the tasks that remained in the queue and any newly submitted tasks. If the pool was paused before resetting it, the new pool will be paused as well.
| init | An initialization function to run in each thread before it starts executing any submitted tasks. The function must have no return value, and can either take one argument, the thread index of type std::size_t, or zero arguments. It will be executed exactly once per thread, when the thread is first constructed. The initialization function must not throw any exceptions, as that will result in program termination. Any exceptions must be handled explicitly within the function. |
|
inline |
Reset the pool with a new number of threads and a new initialization function. Waits for all tasks to be completed, both running and queued, then destroys the thread pool and creates a new one with an empty task queue. If pausing is enabled, only waits for tasks that are currently running before destroying the pool; once the pool is reset, it will then resume executing the tasks that remained in the queue and any newly submitted tasks. If the pool was paused before resetting it, the new pool will be paused as well.
| num_threads | The number of threads to use. |
| init | An initialization function to run in each thread before it starts executing any submitted tasks. The function must have no return value, and can either take one argument, the thread index of type std::size_t, or zero arguments. It will be executed exactly once per thread, when the thread is first constructed. The initialization function must not throw any exceptions, as that will result in program termination. Any exceptions must be handled explicitly within the function. |
|
inline |
Set the thread pool's cleanup function.
| cleanup | A cleanup function to run in each thread right before it is destroyed, which will happen when the pool is destructed or reset. The function must have no return value, and can either take one argument, the thread index of type std::size_t, or zero arguments. The cleanup function must not throw any exceptions, as that will result in program termination. Any exceptions must be handled explicitly within the function. |
|
inline |
Parallelize a loop by automatically splitting it into blocks and submitting each block separately to the queue, with the specified priority. The block function takes two arguments, the start and end of the block, so that it is only called once per block, but it is up to the user to make sure the block function correctly deals with all the indices in each block. If the block function has a return value, get a BS::multi_future for the eventual returned values. If the block function has no return value, get a BS::multi_future<void> which can be used to wait until all the tasks finish.
| T1 | The type of the first index. Should be a signed or unsigned integer. |
| T2 | The type of the index after the last index. Should be a signed or unsigned integer. |
| T | The common type of the indices, as determined by BS::common_index_type_t<T1, T2>. |
| F | The type of the block function. |
| R | The return type of the block function (can be void). |
| first_index | The first index in the loop. |
| index_after_last | The index after the last index in the loop. The loop will iterate from first_index to (index_after_last - 1) inclusive. In other words, it will be equivalent to for (T i = first_index; i < index_after_last; ++i). Note that if index_after_last <= first_index, no tasks will be submitted, and an empty BS::multi_future will be returned. |
| block | A function that will be called once per block. Should take exactly two arguments: the first index in the block and the index after the last index in the block. block(start, end) should typically involve a loop of the form for (T i = start; i < end; ++i). Can return a value. |
| num_blocks | The maximum number of blocks to split the loop into. The default is 0, which means the number of blocks will be equal to the number of threads in the pool. |
| priority | The priority of the tasks. Should be between -128 and +127 (a signed 8-bit integer). The default is 0. Only taken into account if the flag BS::tp::priority is enabled in the template parameter, otherwise has no effect. |
BS::multi_future that can be used to wait for all the tasks to finish. If the block function returns a value, the BS::multi_future can also be used to obtain the values returned by each block.
|
inline |
Submit an iterator range containing functions with no arguments into the task queue, with the specified priority. To submit functions with arguments, enclose them in lambda expressions. If the functions have return values, get a BS::multi_future for the eventual returned values. If the functions have no return values, get a BS::multi_future<void> which can be used to wait until all the tasks finish.
| I | The type of the iterators. |
| F | The type of the functions. |
| R | The return type of the functions (can be void, but must be the same for all the functions). |
| first | An iterator to the first function. |
| last | An iterator to one past the last function. |
| priority | The priority of the tasks. Should be between -128 and +127 (a signed 8-bit integer). The default is 0. Only taken into account if the flag BS::tp::priority is enabled in the template parameter, otherwise has no effect. |
BS::multi_future that can be used to wait for all the tasks to finish. If the functions return values, the BS::multi_future can also be used to obtain the values returned by each task.
|
inline |
Submit a container of functions with no arguments into the task queue, with the specified priority. To submit functions with arguments, enclose them in lambda expressions. If the functions have return values, get a BS::multi_future for the eventual returned values. If the functions have no return values, get a BS::multi_future<void> which can be used to wait until all the tasks finish.
| C | The type of the container. Must either be an array or have begin() and end() member functions. |
| F | The type of the functions. |
| R | The return type of the functions (can be void, but must be the same for all the functions). |
| container | The container. |
| priority | The priority of the tasks. Should be between -128 and +127 (a signed 8-bit integer). The default is 0. Only taken into account if the flag BS::tp::priority is enabled in the template parameter, otherwise has no effect. |
BS::multi_future that can be used to wait for all the tasks to finish. If the functions return values, the BS::multi_future can also be used to obtain the values returned by each task.
|
inline |
Parallelize a loop by automatically splitting it into blocks and submitting each block separately to the queue, with the specified priority. The loop function takes one argument, the loop index, and it is called exactly once per index, but many times per block. Returns a BS::multi_future which can be used to wait until all the tasks finish.
| T1 | The type of the first index. Should be a signed or unsigned integer. |
| T2 | The type of the index after the last index. Should be a signed or unsigned integer. |
| T | The common type of the indices, as determined by BS::common_index_type_t<T1, T2>. |
| F | The type of the loop function. |
| first_index | The first index in the loop. |
| index_after_last | The index after the last index in the loop. The loop will iterate from first_index to (index_after_last - 1) inclusive. In other words, it will be equivalent to for (T i = first_index; i < index_after_last; ++i). Note that if index_after_last <= first_index, no tasks will be submitted, and an empty BS::multi_future will be returned. |
| loop | A function that will be called once per index, many times per block. Should take exactly one argument: the loop index. Must not return a value. |
| num_blocks | The maximum number of blocks to split the loop into. The default is 0, which means the number of blocks will be equal to the number of threads in the pool. |
| priority | The priority of the tasks. Should be between -128 and +127 (a signed 8-bit integer). The default is 0. Only taken into account if the flag BS::tp::priority is enabled in the template parameter, otherwise has no effect. |
BS::multi_future that can be used to wait for all the tasks to finish.
|
inline |
Submit a sequence of tasks enumerated by indices to the queue, with the specified priority. The sequence function takes one argument, the task index, and will be called once per index. If the sequence function has a return value, get a BS::multi_future for the eventual returned values. If the sequence function has no return value, get a BS::multi_future<void> which can be used to wait until all the tasks finish.
| T1 | The type of the first index. Should be a signed or unsigned integer. |
| T2 | The type of the index after the last index. Should be a signed or unsigned integer. |
| T | The common type of the indices, as determined by BS::common_index_type_t<T1, T2>. |
| F | The type of the sequence function. |
| R | The return type of the sequence function (can be void). |
| first_index | The first index in the sequence. |
| index_after_last | The index after the last index in the sequence. The sequence will iterate from first_index to (index_after_last - 1) inclusive. In other words, it will be equivalent to for (T i = first_index; i < index_after_last; ++i). Note that if index_after_last <= first_index, no tasks will be submitted, and an empty BS::multi_future will be returned. |
| sequence | A function that will be called once per index. Should take exactly one argument, the index. Can return a value. |
| priority | The priority of the tasks. Should be between -128 and +127 (a signed 8-bit integer). The default is 0. Only taken into account if the flag BS::tp::priority is enabled in the template parameter, otherwise has no effect. |
BS::multi_future that can be used to wait for all the tasks to finish. If the sequence function returns a value, the BS::multi_future can also be used to obtain the values returned by each task.
|
inline |
Submit a function with no arguments into the task queue, with the specified priority. To submit a function with arguments, enclose it in a lambda expression. If the function has a return value, get a future for the eventual returned value. If the function has no return value, get an std::future<void> which can be used to wait until the task finishes.
| F | The type of the function. |
| R | The return type of the function (can be void). |
| task | The function to submit. |
| priority | The priority of the task. Should be between -128 and +127 (a signed 8-bit integer). The default is 0. Only taken into account if the flag BS::tp::priority is enabled in the template parameter, otherwise has no effect. |

|
inline |
Unpause the pool. The workers will resume retrieving new tasks out of the queue. Only enabled if the flag BS::tp::pause is enabled in the template parameter.

|
inline |
Wait for tasks to be completed. Normally, this function waits for all tasks, both those that are currently running in the threads and those that are still waiting in the queue. However, if the pool is paused, this function only waits for the currently running tasks (otherwise it would wait forever). Note: To wait for just one specific task, use submit_task() instead, and call the wait() member function of the generated future.
| `wait_deadlock` | if called from within a thread of the same pool, which would result in a deadlock. Only enabled if the flag BS::tp::wait_deadlock_checks is enabled in the template parameter. |

|
inline |
Wait for tasks to be completed, but stop waiting after the specified duration has passed.
| R | An arithmetic type representing the number of ticks to wait. |
| P | An std::ratio representing the length of each tick in seconds. |
| duration | The amount of time to wait. |
true if all tasks finished running, false if the duration expired but some tasks are still running. | `wait_deadlock` | if called from within a thread of the same pool, which would result in a deadlock. Only enabled if the flag BS::tp::wait_deadlock_checks is enabled in the template parameter. |
|
inline |
Wait for tasks to be completed, but stop waiting after the specified time point has been reached.
| C | The type of the clock used to measure time. |
| D | An std::chrono::duration type used to indicate the time point. |
| timeout_time | The time point at which to stop waiting. |
true if all tasks finished running, false if the time point was reached but some tasks are still running. | `wait_deadlock` | if called from within a thread of the same pool, which would result in a deadlock. Only enabled if the flag BS::tp::wait_deadlock_checks is enabled in the template parameter. |
|
inlineprivate |
Create the threads in the pool and assign a worker to each thread.
| num_threads | The number of threads to use. |
| init | An initialization function to run in each thread before it starts executing any submitted tasks. |
|
inlineprivate |
Destroy the threads in the pool.

|
inlinestaticprivatenoexcept |
Determine how many threads the pool should have, based on the parameter passed to the constructor or reset().
| num_threads | The parameter passed to the constructor or reset(). If the parameter is a positive number, then the pool will be created with this number of threads. If the parameter is zero, or a parameter was not supplied (in which case it will have the default value of 0), then the pool will be created with the total number of hardware threads available, as obtained from thread_t::hardware_concurrency(). If the latter returns zero for some reason, then the pool will be created with just one thread. If the native extensions are enabled, the pool will instead use the number of threads available to the process, as obtained from BS::get_os_process_affinity(), which can be less than the number of hardware threads. |
|
inlineprivate |
A helper function for detach_blocks() and submit_blocks().
| T | The type of the indices. |
| F | The type of the block function. |
| R | The return type of the block function (can be void). |
| submit | true if called from submit_blocks(), false if called from detach_blocks(). |
| N | The return type of this helper function. |
| first_index | The first index in the loop. |
| index_after_last | The index after the last index in the loop. |
| block | A function that will be called once per block. |
| num_blocks | The maximum number of blocks to split the loop into. |
| priority | The priority of the tasks. |
BS::multi_future if submit is true, or void if submit is false. 
|
inlineprivate |
A helper function for detach_loop() and submit_loop().
| T | The type of the indices. |
| F | The type of the loop function. |
| submit | true if called from submit_loop(), false if called from detach_loop(). |
| N | The return type of this helper function. |
| first_index | The first index in the loop. |
| index_after_last | The index after the last index in the loop. |
| loop | A function that will be called once per index, many times per block. |
| num_blocks | The maximum number of blocks to split the loop into. |
| priority | The priority of the tasks. |
BS::multi_future if submit is true, or void if submit is false. 
|
inlineprivate |
A helper function for detach_sequence() and submit_sequence().
| T | The type of the indices. |
| F | The type of the sequence function. |
| R | The return type of the sequence function (can be void). |
| submit | true if called from submit_sequence(), false if called from detach_sequence(). |
| N | The return type of this helper function. |
| first_index | The first index in the sequence. |
| index_after_last | The index after the last index in the sequence. |
| sequence | A function that will be called once per index. |
| priority | The priority of the tasks. |
BS::multi_future if submit is true, or void if submit is false.
|
inlineprivate |
Pop a task from the queue.
|
inlineprivate |
Reset the pool with a new number of threads and a new initialization function. This member function implements the actual reset, while the public member function reset() also handles the case where the pool is paused.
| num_threads | The number of threads to use. |
| init | An initialization function to run in each thread before it starts executing any submitted tasks. |
|
inlineprivate |
A worker function to be assigned to each thread in the pool. Waits until it is notified by detach_task() that a task is available, and then retrieves the task from the queue and executes it. Once the task finishes, the worker notifies wait() in case it is waiting.
| idx | The index of this thread. |
|
private |
A cleanup function to run in each thread right before it is destroyed, which will happen when the pool is destructed or reset. The function must have no return value, and can either take one argument, the thread index of type std::size_t, or zero arguments. The cleanup function must not throw any exceptions, as that will result in program termination. Any exceptions must be handled explicitly within the function. The default is an empty function, i.e., no cleanup will be performed.
|
private |
An initialization function to run in each thread before it starts executing any submitted tasks. The function must have no return value, and can either take one argument, the thread index of type std::size_t, or zero arguments. It will be executed exactly once per thread, when the thread is first constructed. The initialization function must not throw any exceptions, as that will result in program termination. Any exceptions must be handled explicitly within the function. The default is an empty function, i.e., no initialization will be performed.
|
private |
A flag indicating whether the workers should pause. When set to true, the workers temporarily stop retrieving new tasks out of the queue, although any tasks already executing will keep running until they are finished. When set to false again, the workers resume retrieving tasks. Only enabled if the flag BS::tp::pause is enabled in the template parameter.