Thread System 0.3.1
High-performance C++20 thread pool with work stealing and DAG scheduling
Loading...
Searching...
No Matches
thread_info.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2024, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
12#pragma once
13
14#include "job_info.h"
15
16#include <chrono>
17#include <cstdint>
18#include <iomanip>
19#include <optional>
20#include <sstream>
21#include <string>
22#include <thread>
23
25{
34 enum class worker_state
35 {
36 idle,
37 active,
38 stopping,
39 stopped
40 };
41
47 [[nodiscard]] inline auto worker_state_to_string(worker_state state) -> std::string
48 {
49 switch (state)
50 {
51 case worker_state::idle: return "IDLE";
52 case worker_state::active: return "ACTIVE";
53 case worker_state::stopping: return "STOPPING";
54 case worker_state::stopped: return "STOPPED";
55 default: return "UNKNOWN";
56 }
57 }
58
88 {
94 std::thread::id thread_id;
95
101 std::string thread_name;
102
108 std::size_t worker_id{0};
109
114
120 std::chrono::steady_clock::time_point state_since;
121
127 std::optional<job_info> current_job;
128
129 // =========================================================================
130 // Statistics
131 // =========================================================================
132
136 std::uint64_t jobs_completed{0};
137
141 std::uint64_t jobs_failed{0};
142
146 std::chrono::nanoseconds total_busy_time{0};
147
151 std::chrono::nanoseconds total_idle_time{0};
152
159 double utilization{0.0};
160
161 // =========================================================================
162 // Computed Properties
163 // =========================================================================
164
169 [[nodiscard]] auto state_duration() const -> std::chrono::nanoseconds
170 {
171 return std::chrono::steady_clock::now() - state_since;
172 }
173
178 [[nodiscard]] auto total_jobs() const -> std::uint64_t
179 {
181 }
182
187 [[nodiscard]] auto success_rate() const -> double
188 {
189 auto total = total_jobs();
190 if (total == 0)
191 {
192 return 1.0;
193 }
194 return static_cast<double>(jobs_completed) / static_cast<double>(total);
195 }
196
201 [[nodiscard]] auto is_busy() const -> bool
202 {
203 return state == worker_state::active;
204 }
205
210 [[nodiscard]] auto is_available() const -> bool
211 {
212 return state == worker_state::idle;
213 }
214
221 auto update_utilization() -> void
222 {
223 auto total_time = total_busy_time + total_idle_time;
224 if (total_time.count() == 0)
225 {
226 utilization = 0.0;
227 }
228 else
229 {
230 utilization = static_cast<double>(total_busy_time.count()) /
231 static_cast<double>(total_time.count());
232 }
233 }
234
239 [[nodiscard]] auto busy_time_ms() const -> double
240 {
241 return std::chrono::duration<double, std::milli>(total_busy_time).count();
242 }
243
248 [[nodiscard]] auto idle_time_ms() const -> double
249 {
250 return std::chrono::duration<double, std::milli>(total_idle_time).count();
251 }
252
275 [[nodiscard]] auto to_json() const -> std::string
276 {
277 std::ostringstream oss;
278 oss << "{\n";
279 oss << " \"worker_id\": " << worker_id << ",\n";
280 oss << " \"thread_name\": \"" << thread_name << "\",\n";
281
282 // Format thread_id as string
283 std::ostringstream tid_oss;
284 tid_oss << thread_id;
285 oss << " \"thread_id\": \"" << tid_oss.str() << "\",\n";
286
287 oss << " \"state\": \"" << worker_state_to_string(state) << "\",\n";
288 oss << std::fixed << std::setprecision(3);
289 oss << " \"state_duration_ms\": "
290 << std::chrono::duration<double, std::milli>(state_duration()).count() << ",\n";
291 oss << " \"jobs_completed\": " << jobs_completed << ",\n";
292 oss << " \"jobs_failed\": " << jobs_failed << ",\n";
293 oss << std::setprecision(4);
294 oss << " \"success_rate\": " << success_rate() << ",\n";
295 oss << " \"utilization\": " << utilization << ",\n";
296 oss << std::setprecision(3);
297 oss << " \"busy_time_ms\": " << busy_time_ms() << ",\n";
298 oss << " \"idle_time_ms\": " << idle_time_ms();
299
300 if (current_job.has_value())
301 {
302 oss << ",\n \"current_job\": " << current_job.value().to_json();
303 }
304 else
305 {
306 oss << ",\n \"current_job\": null";
307 }
308
309 oss << "\n}";
310 return oss.str();
311 }
312
325 [[nodiscard]] auto to_string() const -> std::string
326 {
327 std::ostringstream oss;
328
329 auto duration_sec = std::chrono::duration<double>(state_duration()).count();
330
331 // First line: name, thread id, state, duration
332 oss << thread_name << " [tid:" << thread_id << "] "
334 << " (" << std::fixed << std::setprecision(1) << duration_sec << "s)\n";
335
336 // Current job if present
337 if (current_job.has_value())
338 {
339 const auto& job = current_job.value();
340 auto exec_time_ms_val = std::chrono::duration<double, std::milli>(
341 job.execution_time).count();
342 oss << " Current Job: " << job.job_name << "#" << job.job_id
343 << " (running " << std::setprecision(0) << exec_time_ms_val << "ms)\n";
344 }
345
346 // Job statistics
347 oss << " Jobs: " << jobs_completed << " completed, "
348 << jobs_failed << " failed ("
349 << std::setprecision(1) << (success_rate() * 100.0) << "% success)\n";
350
351 // Utilization
352 oss << " Utilization: " << std::setprecision(1)
353 << (utilization * 100.0) << "%";
354
355 return oss.str();
356 }
357 };
358
359} // namespace kcenon::thread::diagnostics
Represents a unit of work (task) to be executed, typically by a job queue.
Definition job.h:136
worker_state
Current state of a worker thread.
Definition thread_info.h:35
@ stopping
Worker is in the process of stopping.
@ active
Worker is executing a job.
@ idle
Worker is waiting for jobs.
Job information snapshot for diagnostics and monitoring.
auto worker_state_to_string(worker_state state) -> std::string
Converts worker_state to human-readable string.
Definition thread_info.h:47
STL namespace.
Information about a worker thread in the pool.
Definition thread_info.h:88
double utilization
Worker utilization ratio.
worker_state state
Current operational state of the worker.
std::size_t worker_id
Worker ID within the pool.
std::thread::id thread_id
System thread ID.
Definition thread_info.h:94
auto is_busy() const -> bool
Checks if the worker is currently processing a job.
std::uint64_t jobs_completed
Total number of jobs successfully completed by this worker.
auto success_rate() const -> double
Calculates the success rate.
auto total_jobs() const -> std::uint64_t
Gets the total number of jobs processed (completed + failed).
auto to_string() const -> std::string
Converts the thread info to a human-readable string.
auto idle_time_ms() const -> double
Converts idle time to milliseconds.
std::chrono::nanoseconds total_busy_time
Total time spent executing jobs (busy time).
std::uint64_t jobs_failed
Total number of jobs that failed during execution.
std::string thread_name
Human-readable name for this thread.
std::chrono::steady_clock::time_point state_since
Time when the worker entered its current state.
auto busy_time_ms() const -> double
Converts busy time to milliseconds.
auto state_duration() const -> std::chrono::nanoseconds
Calculates the duration in the current state.
std::chrono::nanoseconds total_idle_time
Total time spent waiting for jobs (idle time).
auto is_available() const -> bool
Checks if the worker is available to process jobs.
auto update_utilization() -> void
Recalculates utilization based on busy and idle times.
auto to_json() const -> std::string
Converts the thread info to a JSON string.
std::optional< job_info > current_job
Information about the currently executing job.