ThreadSchedule 3.0.0
Modern C++ thread management library
Loading...
Searching...
No Matches
threadschedule::detail::lightweight_pool_backend_base< TaskSize > Class Template Reference

Ultra-lightweight fire-and-forget thread pool. More...

#include <lightweight_pool_backend_base.hpp>

Public Member Functions

 lightweight_pool_backend_base (size_t num_threads=default_worker_count(), bool register_workers=false)
 Construct a lightweight pool with num_threads workers.
 
 lightweight_pool_backend_base (lightweight_pool_backend_base const &)=delete
 
auto operator= (lightweight_pool_backend_base const &) -> lightweight_pool_backend_base &=delete
 
 ~lightweight_pool_backend_base ()
 
Task submission
template<typename F , typename... Args>
void post (F &&f, Args &&... args)
 Post a fire-and-forget task (throwing variant).
 
template<typename F , typename... Args>
auto try_post (F &&f, Args &&... args) -> expected< void, std::error_code >
 Post a fire-and-forget task (non-throwing variant).
 
template<typename Iterator >
void post_batch (Iterator begin, Iterator end)
 Post a range of callables under a single lock acquisition.
 
template<typename Iterator >
auto try_post_batch (Iterator begin, Iterator end) -> expected< void, std::error_code >
 Batch post (non-throwing).
 
Lifecycle
void shutdown (shutdown_policy_backend policy=shutdown_policy_backend::drain)
 Shut the pool down.
 
auto shutdown_for (std::chrono::milliseconds timeout) -> bool
 Attempt a timed drain.
 
Observers
auto size () const noexcept -> size_t
 Number of worker threads.
 
auto is_current_worker () const noexcept -> bool
 
Thread configuration
auto configure_threads (std::string const &name_prefix, native_scheduling_policy policy=native_scheduling_policy::other, native_thread_priority priority=native_thread_priority::normal()) -> expected< void, std::error_code >
 Name, schedule and prioritize all worker threads.
 
auto configure_threads (native_thread_config const &config) -> expected< void, std::error_code >
 
auto set_affinity (native_thread_affinity const &affinity) -> expected< void, std::error_code >
 Pin all workers to the same CPU set.
 
auto distribute_across_cpus () -> expected< void, std::error_code >
 Pin each worker to a distinct CPU core (round-robin).
 

Detailed Description

template<size_t TaskSize = 64>
class threadschedule::detail::lightweight_pool_backend_base< TaskSize >

Ultra-lightweight fire-and-forget thread pool.

Designed for maximum throughput on tasks whose return value is not needed. Typical measured throughput is 3x higher than submit() on e.g. work_stealing_pool_backend on the same hardware, because lightweight_pool_backend_base avoids the overhead of std::packaged_task, std::future, and std::shared_ptr entirely.

Internal architecture
Producer(s) Single Queue Worker Threads
+---------+ +------------------+ +----------------+
+---------+ +------------------+ +----------------+
mutex + cond_var
void post(F &&f, Args &&... args)
Post a fire-and-forget task (throwing variant).
Owning wrapper around std::thread with RAII join-on-destroy semantics.
  • Queue: Single queue of library-owned small-buffer callables protected by one mutex + condition_variable.
  • Workers: detail::thread_backend instances so that thread naming, CPU affinity, and scheduling policy can be configured after construction.
  • SBO: Callables up to TaskSize - sizeof(void*) bytes with pointer alignment are stored inline (no heap allocation). Larger or over-aligned callables fall back to the heap.
What is not included (by design)
Execution guarantees
  • Every successfully posted task is guaranteed to execute (unless shutdown(shutdown_policy_backend::drop_pending) is called).
  • Tasks are dequeued in FIFO order. Because multiple workers pop concurrently, the completion order is non-deterministic.
  • Exceptions thrown by tasks are silently caught; the worker continues.
Thread safety
post(), try_post(), post_batch(), and try_post_batch() may be called from any number of threads concurrently. shutdown() is internally guarded and safe to call more than once.
Lifetime
The destructor calls shutdown(shutdown_policy_backend::drain) and joins all workers. It blocks until every queued task has been executed.
Choosing TaskSize
The default callable slot is exactly 64 bytes (one x86 cache line) and works well for lambdas capturing up to ~7 pointers. If your tasks capture more state, increase TaskSize to avoid the heap fallback:
lightweight_pool_backend_base<128> pool(4); // 120 inline bytes on 64-bit
Copyability / movability
Not copyable, not movable.
Template Parameters
TaskSizeExact total size in bytes of each callable slot (default 64). Usable inline buffer = TaskSize - sizeof(void*).
See also
lightweight_pool_backend (alias for lightweight_pool_backend_base<64>), scheduled_lightweight_pool_backend (scheduled variant).

Definition at line 113 of file lightweight_pool_backend_base.hpp.

Constructor & Destructor Documentation

◆ lightweight_pool_backend_base() [1/2]

template<size_t TaskSize = 64>
threadschedule::detail::lightweight_pool_backend_base< TaskSize >::lightweight_pool_backend_base ( size_t  num_threads = default_worker_count(),
bool  register_workers = false 
)
inlineexplicit

Construct a lightweight pool with num_threads workers.

Parameters
num_threadsNumber of worker threads (clamped to at least 1). Defaults to std::thread::hardware_concurrency().
register_workersWhen true, worker threads register in the global registry for discovery and control.

Definition at line 129 of file lightweight_pool_backend_base.hpp.

References threadschedule::detail::worker_startup_latch::wait().

◆ lightweight_pool_backend_base() [2/2]

template<size_t TaskSize = 64>
threadschedule::detail::lightweight_pool_backend_base< TaskSize >::lightweight_pool_backend_base ( lightweight_pool_backend_base< TaskSize > const &  )
delete

◆ ~lightweight_pool_backend_base()

Member Function Documentation

◆ configure_threads() [1/2]

template<size_t TaskSize = 64>
auto threadschedule::detail::lightweight_pool_backend_base< TaskSize >::configure_threads ( native_thread_config const &  config) -> expected<void, std::error_code>
inline

◆ configure_threads() [2/2]

template<size_t TaskSize = 64>
auto threadschedule::detail::lightweight_pool_backend_base< TaskSize >::configure_threads ( std::string const &  name_prefix,
native_scheduling_policy  policy = native_scheduling_policy::other,
native_thread_priority  priority = native_thread_priority::normal() 
) -> expected<void, std::error_code>
inline

Name, schedule and prioritize all worker threads.

Workers are named name_prefix + "_0", "_1", etc.

Definition at line 385 of file lightweight_pool_backend_base.hpp.

References threadschedule::detail::configure_worker_threads(), and threadschedule::detail::runtime_registry().

◆ distribute_across_cpus()

template<size_t TaskSize = 64>
auto threadschedule::detail::lightweight_pool_backend_base< TaskSize >::distribute_across_cpus ( ) -> expected<void, std::error_code>
inline

Pin each worker to a distinct CPU core (round-robin).

Definition at line 408 of file lightweight_pool_backend_base.hpp.

References threadschedule::detail::distribute_workers_across_cpus().

◆ is_current_worker()

◆ operator=()

template<size_t TaskSize = 64>
auto threadschedule::detail::lightweight_pool_backend_base< TaskSize >::operator= ( lightweight_pool_backend_base< TaskSize > const &  ) -> lightweight_pool_backend_base &=delete
delete

◆ post()

template<size_t TaskSize = 64>
template<typename F , typename... Args>
void threadschedule::detail::lightweight_pool_backend_base< TaskSize >::post ( F &&  f,
Args &&...  args 
)
inline

Post a fire-and-forget task (throwing variant).

The callable and its arguments are bound into a move_only_function and pushed into the shared queue.

Template Parameters
FCallable type.
ArgsArgument types forwarded to F.
Exceptions
std::runtime_errorIf the pool is shutting down.
See also
try_post() for the non-throwing variant.

Definition at line 174 of file lightweight_pool_backend_base.hpp.

References threadschedule::detail::lightweight_pool_backend_base< TaskSize >::try_post().

◆ post_batch()

template<size_t TaskSize = 64>
template<typename Iterator >
void threadschedule::detail::lightweight_pool_backend_base< TaskSize >::post_batch ( Iterator  begin,
Iterator  end 
)
inline

Post a range of callables under a single lock acquisition.

More efficient than calling post() in a loop because the mutex is acquired only once and all workers are woken via notify_all().

Template Parameters
IteratorInput iterator whose value_type is callable as void().
Exceptions
std::runtime_errorIf the pool is shutting down.

Definition at line 214 of file lightweight_pool_backend_base.hpp.

References threadschedule::detail::lightweight_pool_backend_base< TaskSize >::try_post_batch().

◆ set_affinity()

template<size_t TaskSize = 64>
auto threadschedule::detail::lightweight_pool_backend_base< TaskSize >::set_affinity ( native_thread_affinity const &  affinity) -> expected<void, std::error_code>
inline

Pin all workers to the same CPU set.

Definition at line 401 of file lightweight_pool_backend_base.hpp.

References threadschedule::detail::set_worker_affinity().

◆ shutdown()

template<size_t TaskSize = 64>
void threadschedule::detail::lightweight_pool_backend_base< TaskSize >::shutdown ( shutdown_policy_backend  policy = shutdown_policy_backend::drain)
inline

Shut the pool down.

Parameters
policydrain (default) - workers finish all queued tasks before exiting. drop_pending - the queue is cleared and only the currently executing tasks are allowed to finish.

Safe to call more than once (subsequent calls are no-ops).

Definition at line 272 of file lightweight_pool_backend_base.hpp.

References threadschedule::detail::drop_pending, threadschedule::detail::lightweight_pool_backend_base< TaskSize >::is_current_worker(), and threadschedule::detail::throw_worker_deadlock().

Referenced by threadschedule::detail::lightweight_pool_backend_base< TaskSize >::~lightweight_pool_backend_base().

◆ shutdown_for()

template<size_t TaskSize = 64>
auto threadschedule::detail::lightweight_pool_backend_base< TaskSize >::shutdown_for ( std::chrono::milliseconds  timeout) -> bool
inline

Attempt a timed drain.

Waits up to timeout for all tasks to complete, then discards queued work. Already-running tasks finish asynchronously and are joined by a later blocking shutdown or by destruction.

New submissions are rejected before the timed wait begins.

Returns
true if all tasks completed within the deadline, false if the timeout expired (pool is still shut down).

Definition at line 315 of file lightweight_pool_backend_base.hpp.

References threadschedule::detail::lightweight_pool_backend_base< TaskSize >::is_current_worker(), threadschedule::detail::shutdown_deadline_after(), and threadschedule::detail::throw_worker_deadlock().

◆ size()

template<size_t TaskSize = 64>
auto threadschedule::detail::lightweight_pool_backend_base< TaskSize >::size ( ) const -> size_t
inlinenoexcept

Number of worker threads.

Definition at line 363 of file lightweight_pool_backend_base.hpp.

◆ try_post()

template<size_t TaskSize = 64>
template<typename F , typename... Args>
auto threadschedule::detail::lightweight_pool_backend_base< TaskSize >::try_post ( F &&  f,
Args &&...  args 
) -> expected<void, std::error_code>
inline

Post a fire-and-forget task (non-throwing variant).

Returns
expected<void, std::error_code>std::errc::operation_canceled on shutdown.

Definition at line 189 of file lightweight_pool_backend_base.hpp.

References threadschedule::detail::bind_args().

Referenced by threadschedule::detail::lightweight_pool_backend_base< TaskSize >::post().

◆ try_post_batch()

template<size_t TaskSize = 64>
template<typename Iterator >
auto threadschedule::detail::lightweight_pool_backend_base< TaskSize >::try_post_batch ( Iterator  begin,
Iterator  end 
) -> expected<void, std::error_code>
inline

Batch post (non-throwing).

Returns
expected<void, std::error_code>.

Definition at line 227 of file lightweight_pool_backend_base.hpp.

References threadschedule::detail::multipass_range_size().

Referenced by threadschedule::detail::lightweight_pool_backend_base< TaskSize >::post_batch().


The documentation for this class was generated from the following file: