3131#include < type_traits>
3232#include < vector>
3333
34+ #ifdef _WIN32
35+
36+ #include < folly/portability/Windows.h>
37+
38+ #else
39+
3440#include < sys/time.h>
3541#include < unistd.h>
3642
3743#include < pthread.h>
3844
45+ #endif
46+
3947#include < folly/Conv.h>
4048#include < folly/system/ThreadName.h>
4149
@@ -48,6 +56,28 @@ namespace dwarfs {
4856
4957namespace {
5058
59+ #ifdef _WIN32
60+
61+ double get_thread_cpu_time (std::thread const & t) {
62+ static_assert (sizeof (std::thread::id) == sizeof (DWORD),
63+ " Win32 thread id type mismatch" );
64+ auto tid = t.get_id ();
65+ DWORD id;
66+ std::memcpy (&id, &tid, sizeof (id));
67+ HANDLE h = ::OpenThread (THREAD_QUERY_LIMITED_INFORMATION, FALSE , id);
68+ FILETIME t_create, t_exit, t_sys, t_user;
69+ if (::GetThreadTimes (h, &t_create, &t_exit, &t_sys, &t_user)) {
70+ uint64_t sys = (static_cast <uint64_t >(t_sys.dwHighDateTime ) << 32 ) +
71+ t_sys.dwLowDateTime ;
72+ uint64_t user = (static_cast <uint64_t >(t_user.dwHighDateTime ) << 32 ) +
73+ t_user.dwLowDateTime ;
74+ return 1e-7 * (sys + user);
75+ }
76+ throw std::runtime_error (" get_thread_cpu_time" );
77+ }
78+
79+ #else
80+
5181pthread_t std_to_pthread_id (std::thread::id tid) {
5282 static_assert (std::is_same_v<pthread_t , std::thread::native_handle_type>);
5383 static_assert (sizeof (std::thread::id) ==
@@ -57,6 +87,18 @@ pthread_t std_to_pthread_id(std::thread::id tid) {
5787 return id;
5888}
5989
90+ double get_thread_cpu_time (std::thread const & t) {
91+ ::clockid_t cid;
92+ struct ::timespec ts;
93+ if (::pthread_getcpuclockid (std_to_pthread_id (t.get_id ()), &cid) == 0 &&
94+ ::clock_gettime (cid, &ts) == 0) {
95+ return ts.tv_sec + 1e-9 * ts.tv_nsec ;
96+ }
97+ throw std::runtime_error (" get_thread_cpu_time" );
98+ }
99+
100+ #endif
101+
60102} // namespace
61103
62104template <typename Policy>
@@ -175,13 +217,11 @@ class basic_worker_group final : public worker_group::impl, private Policy {
175217 std::lock_guard lock (mx_);
176218 double t = 0.0 ;
177219
220+ // TODO:
221+ // return workers_ | std::views::transform(get_thread_cpu_time) |
222+ // std::ranges::accumulate;
178223 for (auto const & w : workers_) {
179- ::clockid_t cid;
180- struct ::timespec ts;
181- if (::pthread_getcpuclockid (std_to_pthread_id (w.get_id ()), &cid) == 0 &&
182- ::clock_gettime (cid, &ts) == 0) {
183- t += ts.tv_sec + 1e-9 * ts.tv_nsec ;
184- }
224+ t += get_thread_cpu_time (w);
185225 }
186226
187227 return t;
0 commit comments