From 7d11e44e491c5755f8520bb2b5d0f8b5b810e00b Mon Sep 17 00:00:00 2001 From: Aster Seker Date: Thu, 18 Sep 2025 05:33:49 +0300 Subject: [PATCH] feat(config): add task executor drain budget macro Introduce a configuration macro for the TaskExecutor drain loop and update documentation to reference it. --- docs/TaskExecutor.md | 9 +++++---- include/logit_cpp/logit/config.hpp | 8 ++++++++ include/logit_cpp/logit/detail/TaskExecutor.hpp | 3 ++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/docs/TaskExecutor.md b/docs/TaskExecutor.md index fc4e9f4..ba9ef72 100644 --- a/docs/TaskExecutor.md +++ b/docs/TaskExecutor.md @@ -198,10 +198,11 @@ const auto lost = LOGIT_GET_DROPPED_TASKS(); * `QueuePolicy::Block` limits the number of in-flight tasks tracked by `m_active_tasks`. Use it to introduce producer-side backpressure when the downstream sinks are expensive. -* The worker drains up to 2048 tasks per iteration when the ring is enabled. - Increase this "budget" in `TaskExecutor::worker_function()` if your workload - generates extremely large bursts and the worker sleeps too often. Reducing it - can lower per-iteration latency for latency-sensitive applications. +* The worker drains up to `LOGIT_TASK_EXECUTOR_DRAIN_BUDGET` tasks per iteration + when the ring is enabled. Increase this "budget" in + `TaskExecutor::worker_function()` if your workload generates extremely large + bursts and the worker sleeps too often. Reducing it can lower per-iteration + latency for latency-sensitive applications. * Adjust `LOGIT_TASK_EXECUTOR_DEFAULT_RING_CAPACITY` at compile time to select a different default capacity when `LOGIT_USE_MPSC_RING` is active. * Monitor `dropped_tasks()` during load testing to verify that the chosen policy diff --git a/include/logit_cpp/logit/config.hpp b/include/logit_cpp/logit/config.hpp index 758a4d1..2bccd42 100644 --- a/include/logit_cpp/logit/config.hpp +++ b/include/logit_cpp/logit/config.hpp @@ -202,6 +202,14 @@ /// Configuration options for the task executor implementation. /// \{ +/// \brief Maximum number of tasks drained per worker iteration in ring-buffer builds. +/// If `LOGIT_TASK_EXECUTOR_DRAIN_BUDGET` is not defined, the worker drains up to 2048 +/// tasks before yielding. Increase the value to process larger bursts before sleeping, +/// or reduce it to prioritise lower per-iteration latency. +#ifndef LOGIT_TASK_EXECUTOR_DRAIN_BUDGET +#define LOGIT_TASK_EXECUTOR_DRAIN_BUDGET 2048 +#endif + /// \brief Default capacity for the task executor ring buffer when unlimited is requested. #ifndef LOGIT_TASK_EXECUTOR_DEFAULT_RING_CAPACITY #define LOGIT_TASK_EXECUTOR_DEFAULT_RING_CAPACITY 1024 diff --git a/include/logit_cpp/logit/detail/TaskExecutor.hpp b/include/logit_cpp/logit/detail/TaskExecutor.hpp index a033358..27166d0 100644 --- a/include/logit_cpp/logit/detail/TaskExecutor.hpp +++ b/include/logit_cpp/logit/detail/TaskExecutor.hpp @@ -8,6 +8,7 @@ #include #include +#include "logit/config.hpp" #if defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__) #include #include @@ -439,7 +440,7 @@ namespace logit { namespace detail { bool drained_any = false; std::function task; - int budget = 2048; + int budget = LOGIT_TASK_EXECUTOR_DRAIN_BUDGET; while (budget-- && m_mpsc_queue.try_pop(task)) { drained_any = true; m_active_tasks.fetch_add(1, std::memory_order_relaxed);