5#ifndef BITCOIN_UTIL_THREADPOOL_H
6#define BITCOIN_UTIL_THREADPOOL_H
15#include <condition_variable>
53 std::condition_variable
m_cv;
109 if (m_interrupt)
throw std::runtime_error(
"Thread pool has been interrupted or is stopping");
110 if (!
m_workers.empty())
throw std::runtime_error(
"Thread pool already started");
136 auto id = std::this_thread::get_id();
161 using Future = std::future<std::invoke_result_t<F>>;
196 return {std::move(
future)};
218 template <std::ranges::sized_range R>
219 requires(!std::is_lvalue_reference_v<R>)
222 std::vector<RangeFuture<R>>
futures;
229 for (
auto&& fn :
fns) {
288 return "No active workers";
290 return "Interrupted";
293 return "Unknown error";
#define Assume(val)
Assume is the identity function.
Fixed-size thread pool for running arbitrary tasks concurrently.
void Start(int num_workers) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Start worker threads.
size_t WorkersCount() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
std::vector< std::thread > m_workers GUARDED_BY(m_mutex)
bool ProcessTask() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Execute a single queued task synchronously.
std::condition_variable m_cv
util::Expected< std::vector< RangeFuture< R > >, SubmitError > Submit(R &&fns) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Enqueues a range of tasks for asynchronous execution.
util::Expected< Future< F >, SubmitError > Submit(F &&fn) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Enqueues a new task for asynchronous execution.
void Stop() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Stop all worker threads and wait for them to exit.
std::queue< std::packaged_task< void()> > m_work_queue GUARDED_BY(m_mutex)
std::packaged_task< std::invoke_result_t< F >()> PackagedTask
ThreadPool(const std::string &name)
void Interrupt() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Stop accepting new tasks and begin asynchronous shutdown.
void WorkerThread() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
std::future< std::invoke_result_t< F > > Future
size_t WorkQueueSize() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
bool m_interrupt GUARDED_BY(m_mutex)
Future< std::ranges::range_reference_t< R > > RangeFuture
The util::Expected class provides a standard way for low-level functions to return either error value...
The util::Unexpected class represents an unexpected value stored in util::Expected.
void TraceThread(std::string_view thread_name, std::function< void()> thread_func)
A wrapper for do-something-once thread functions.
#define WAIT_LOCK(cs, name)
#define REVERSE_LOCK(g, cs)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
constexpr std::string_view SubmitErrorString(const ThreadPool::SubmitError err) noexcept
#define EXCLUSIVE_LOCKS_REQUIRED(...)
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.