diff --git a/include/crucible/task.h b/include/crucible/task.h index 142a0fc..7b7d132 100644 --- a/include/crucible/task.h +++ b/include/crucible/task.h @@ -93,6 +93,17 @@ namespace crucible { /// Gets the current number of active workers static size_t get_thread_count(); + /// Gets the current load tracking statistics + struct LoadStats { + /// Current load extracted from last two 5-second load average samples + double current_load; + /// Target thread count computed from previous thread count and current load + double thread_target; + /// Load average for last 60 seconds + double loadavg; + }; + static LoadStats get_current_load(); + /// Drop the current queue and discard new Tasks without /// running them. Currently executing tasks are not /// affected (use set_thread_count(0) to wait for those diff --git a/lib/task.cc b/lib/task.cc index c18ecd8..c33cf87 100644 --- a/lib/task.cc +++ b/lib/task.cc @@ -139,6 +139,7 @@ namespace crucible { double m_thread_target; bool m_cancelled = false; bool m_paused = false; + TaskMaster::LoadStats m_load_stats; friend class TaskConsumer; friend class TaskMaster; @@ -165,6 +166,7 @@ namespace crucible { static void push_front(TaskQueue &queue); size_t get_queue_count(); size_t get_thread_count(); + static TaskMaster::LoadStats get_current_load(); }; class TaskConsumer : public enable_shared_from_this { @@ -348,7 +350,8 @@ namespace crucible { TaskMasterState::TaskMasterState(size_t thread_max) : m_thread_max(thread_max), m_configured_thread_max(thread_max), - m_thread_target(thread_max) + m_thread_target(thread_max), + m_load_stats(TaskMaster::LoadStats { 0 }) { } @@ -422,6 +425,13 @@ namespace crucible { return s_tms->m_threads.size(); } + TaskMaster::LoadStats + TaskMaster::get_current_load() + { + unique_lock lock(s_tms->m_mutex); + return s_tms->m_load_stats; + } + ostream & TaskMaster::print_queue(ostream &os) { @@ -502,6 +512,12 @@ namespace crucible { m_thread_target += m_load_target - current_load; } + m_load_stats = TaskMaster::LoadStats { + .current_load = current_load, + .thread_target = m_thread_target, + .loadavg = loadavg, + }; + // Cannot exceed configured maximum thread count or less than zero m_thread_target = min(max(0.0, m_thread_target), double(m_configured_thread_max));