/// 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
double m_thread_target;
bool m_cancelled = false;
bool m_paused = false;
+ TaskMaster::LoadStats m_load_stats;
friend class TaskConsumer;
friend class TaskMaster;
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<TaskConsumer> {
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 })
{
}
return s_tms->m_threads.size();
}
+ TaskMaster::LoadStats
+ TaskMaster::get_current_load()
+ {
+ unique_lock<mutex> lock(s_tms->m_mutex);
+ return s_tms->m_load_stats;
+ }
+
ostream &
TaskMaster::print_queue(ostream &os)
{
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));