• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

STEllAR-GROUP / hpx / #882

31 Aug 2023 07:44PM UTC coverage: 41.798% (-44.7%) from 86.546%
#882

push

19442 of 46514 relevant lines covered (41.8%)

126375.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

26.42
/libs/full/performance_counters/src/threadmanager_counter_types.cpp
1
//  Copyright (c) 2007-2024 Hartmut Kaiser
2
//  Copyright (c)      2011 Bryce Lelbach, Katelyn Kufahl
3
//  Copyright (c) 2008-2009 Chirag Dekate, Anshul Tandon
4
//  Copyright (c) 2015 Patricia Grubel
5
//  Copyright (c) 2017 Shoshana Jakobovits
6
//
7
//  SPDX-License-Identifier: BSL-1.0
8
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
9
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10

11
#include <hpx/config.hpp>
12
#include <hpx/assert.hpp>
13
#include <hpx/modules/errors.hpp>
14
#include <hpx/modules/functional.hpp>
15
#include <hpx/modules/runtime_local.hpp>
16
#include <hpx/modules/threadmanager.hpp>
17
#include <hpx/performance_counters/counter_creators.hpp>
18
#include <hpx/performance_counters/counters.hpp>
19
#include <hpx/performance_counters/manage_counter_type.hpp>
20
#include <hpx/performance_counters/threadmanager_counter_types.hpp>
21
#ifdef HPX_HAVE_THREAD_QUEUE_WAITTIME
22
#include <hpx/modules/schedulers.hpp>
23
#endif
24

25
#include <cstddef>
26
#include <cstdint>
27
#include <utility>
28

29
///////////////////////////////////////////////////////////////////////////////
30
namespace hpx::performance_counters::detail {
31

32
    using threadmanager_counter_func = std::int64_t (threads::threadmanager::*)(
33
        bool reset) const;
34
    using threadpool_counter_func = std::int64_t (threads::thread_pool_base::*)(
35
        std::size_t num_thread, bool reset);
36

37
    naming::gid_type locality_pool_thread_counter_creator(
38
        threads::threadmanager* tm, threadmanager_counter_func total_func,
39
        threadpool_counter_func pool_func, counter_info const& info,
40
        error_code& ec);
41

42
#ifdef HPX_HAVE_THREAD_QUEUE_WAITTIME
43
    naming::gid_type queue_wait_time_counter_creator(threads::threadmanager* tm,
44
        threadmanager_counter_func total_func,
45
        threadpool_counter_func pool_func, counter_info const& info,
46
        error_code& ec)
47
    {
48
        naming::gid_type gid = locality_pool_thread_counter_creator(
49
            tm, total_func, pool_func, info, ec);
50

51
        if (!ec)
52
        {
53
            threads::policies::set_maintain_queue_wait_times_enabled(true);
54
        }
55
        return gid;
56
    }
57
#endif
58

×
59
    naming::gid_type locality_pool_thread_counter_creator(
60
        threads::threadmanager* tm, threadmanager_counter_func total_func,
61
        threadpool_counter_func pool_func, counter_info const& info,
62
        error_code& ec)
63
    {
64
        // verify the validity of the counter instance name
65
        counter_path_elements paths;
×
66
        get_counter_path_elements(info.fullname_, paths, ec);
×
67
        if (ec)
68
        {
69
            return naming::invalid_gid;
70
        }
71

×
72
        if (paths.parentinstance_is_basename_)
73
        {
×
74
            HPX_THROWS_IF(ec, hpx::error::bad_parameter,
75
                "queue_length_counter_creator",
76
                "invalid counter instance parent name: {}",
77
                paths.parentinstancename_);
78
            return naming::invalid_gid;
79
        }
80

×
81
        threads::thread_pool_base& pool = tm->default_pool();
×
82
        if (paths.instancename_ == "total" && paths.instanceindex_ == -1)
83
        {
84
            // overall counter
85
            using detail::create_raw_counter;
86
            hpx::function<std::int64_t(bool)> f =
87
                hpx::bind_front(total_func, tm);
×
88
            return create_raw_counter(info, HPX_MOVE(f), ec);
89
        }
×
90
        else if (paths.instancename_ == "pool")
91
        {
×
92
            if (paths.instanceindex_ >= 0 &&
×
93
                static_cast<std::size_t>(paths.instanceindex_) <
×
94
                    hpx::resource::get_num_thread_pools())
95
            {
96
                // specific for given pool counter
97
                threads::thread_pool_base& pool_instance =
×
98
                    hpx::resource::get_thread_pool(paths.instanceindex_);
99

100
                using detail::create_raw_counter;
101
                hpx::function<std::int64_t(bool)> f =
×
102
                    hpx::bind_front(pool_func, &pool_instance,
×
103
                        static_cast<std::size_t>(paths.subinstanceindex_));
×
104
                return create_raw_counter(info, HPX_MOVE(f), ec);
105
            }
106
        }
×
107
        else if (paths.instancename_ == "worker-thread" &&
×
108
            paths.instanceindex_ >= 0 &&
×
109
            static_cast<std::size_t>(paths.instanceindex_) <
110
                pool.get_os_thread_count())
111
        {
112
            // specific counter from default
×
113
            using detail::create_raw_counter;
×
114
            hpx::function<std::int64_t(bool)> f = hpx::bind_front(pool_func,
×
115
                &pool, static_cast<std::size_t>(paths.instanceindex_));
116
            return create_raw_counter(info, HPX_MOVE(f), ec);
117
        }
×
118

119
        HPX_THROWS_IF(ec, hpx::error::bad_parameter,
120
            "locality_pool_thread_counter_creator",
121
            "invalid counter instance name: {}", paths.instancename_);
×
122
        return naming::invalid_gid;
123
    }
124

×
125
    // scheduler utilization counter creation function
126
    naming::gid_type scheduler_utilization_counter_creator(
127
        threads::threadmanager const* tm, counter_info const& info,
128
        error_code& ec)
129
    {
×
130
        // verify the validity of the counter instance name
×
131
        counter_path_elements paths;
132
        get_counter_path_elements(info.fullname_, paths, ec);
133
        if (ec)
134
        {
135
            return naming::invalid_gid;
136
        }
×
137
        // /scheduler{locality#%d/total}/utilization/instantaneous
138
        // /scheduler{locality#%d/pool#%s/total}/utilization/instantaneous
×
139
        if (paths.parentinstance_is_basename_)
140
        {
141
            HPX_THROWS_IF(ec, hpx::error::bad_parameter,
142
                "scheduler_utilization_creator",
143
                "invalid counter instance parent name: {}",
144
                paths.parentinstancename_);
145
            return naming::invalid_gid;
146
        }
147

×
148
        using detail::create_raw_counter;
×
149

150
        threads::thread_pool_base& pool = tm->default_pool();
151
        if (paths.instancename_ == "total" && paths.instanceindex_ == -1)
152
        {
153
            // counter for default pool
×
154
            hpx::function<std::int64_t()> f = hpx::bind_back(
155
                &threads::thread_pool_base::get_scheduler_utilization, &pool);
×
156
            return create_raw_counter(info, HPX_MOVE(f), ec);
157
        }
×
158
        else if (paths.instancename_ == "pool")
159
        {
160
            if (paths.instanceindex_ < 0)
161
            {
162
                // counter for default pool
163
                hpx::function<std::int64_t()> f = hpx::bind_back(
×
164
                    &threads::thread_pool_base::get_scheduler_utilization,
165
                    &pool);
×
166
                return create_raw_counter(info, HPX_MOVE(f), ec);
×
167
            }
168
            else if (static_cast<std::size_t>(paths.instanceindex_) <
169
                hpx::resource::get_num_thread_pools())
170
            {
×
171
                // counter specific for given pool
172
                threads::thread_pool_base& pool_instance =
173
                    hpx::resource::get_thread_pool(paths.instanceindex_);
174

175
                hpx::function<std::int64_t()> f = hpx::bind_back(
×
176
                    &threads::thread_pool_base::get_scheduler_utilization,
177
                    &pool_instance);
178
                return create_raw_counter(info, HPX_MOVE(f), ec);
179
            }
×
180
        }
181

182
        HPX_THROWS_IF(ec, hpx::error::bad_parameter,
183
            "scheduler_utilization_creator",
×
184
            "invalid counter instance name: {}", paths.instancename_);
185
        return naming::invalid_gid;
186
    }
187

188
    ///////////////////////////////////////////////////////////////////////
189
    // locality/pool/worker-thread counter creation function with no total
×
190
    // /threads{locality#%d/worker-thread#%d}/idle-loop-count/instantaneous
191
    // /threads{locality#%d/pool#%s/worker-thread#%d}/idle-loop-count/instantaneous
192
    naming::gid_type locality_pool_thread_no_total_counter_creator(
193
        threads::threadmanager const* tm, threadpool_counter_func pool_func,
194
        counter_info const& info, error_code& ec)
195
    {
×
196
        // verify the validity of the counter instance name
×
197
        counter_path_elements paths;
198
        get_counter_path_elements(info.fullname_, paths, ec);
199
        if (ec)
200
        {
×
201
            return naming::invalid_gid;
202
        }
×
203
        if (paths.parentinstance_is_basename_)
204
        {
205
            HPX_THROWS_IF(ec, hpx::error::bad_parameter,
206
                "locality_pool_thread_no_total_counter_creator",
207
                "invalid counter instance parent name: {}",
208
                paths.parentinstancename_);
209
            return naming::invalid_gid;
×
210
        }
×
211

212
        threads::thread_pool_base& pool = tm->default_pool();
213
        if (paths.instancename_ == "total" && paths.instanceindex_ == -1)
×
214
        {
215
            // overall counter, not supported
216
            HPX_THROWS_IF(ec, hpx::error::bad_parameter,
217
                "locality_pool_thread_no_total_counter_creator",
218
                "invalid counter instance name: {} 'total' is not supported",
×
219
                paths.instancename_);
220
        }
×
221
        else if (paths.instancename_ == "pool")
×
222
        {
×
223
            if (paths.instanceindex_ >= 0 &&
224
                static_cast<std::size_t>(paths.instanceindex_) <
225
                    hpx::resource::get_num_thread_pools())
226
            {
×
227
                // specific for given pool counter
228
                threads::thread_pool_base& pool_instance =
229
                    hpx::resource::get_thread_pool(paths.instanceindex_);
230

×
231
                using detail::create_raw_counter;
×
232
                hpx::function<std::int64_t(bool)> f =
×
233
                    hpx::bind_front(pool_func, &pool_instance,
234
                        static_cast<std::size_t>(paths.subinstanceindex_));
235
                return create_raw_counter(info, HPX_MOVE(f), ec);
×
236
            }
×
237
        }
×
238
        else if (paths.instancename_ == "worker-thread" &&
239
            paths.instanceindex_ >= 0 &&
240
            static_cast<std::size_t>(paths.instanceindex_) <
241
                pool.get_os_thread_count())
×
242
        {
×
243
            // specific counter
×
244
            using detail::create_raw_counter;
245
            hpx::function<std::int64_t(bool)> f = hpx::bind_front(pool_func,
246
                &pool, static_cast<std::size_t>(paths.instanceindex_));
×
247
            return create_raw_counter(info, HPX_MOVE(f), ec);
248
        }
249

250
        HPX_THROWS_IF(ec, hpx::error::bad_parameter,
×
251
            "locality_pool_thread_no_total_counter_creator",
252
            "invalid counter instance name: {}", paths.instancename_);
253
        return naming::invalid_gid;
×
254
    }
255

256
    ///////////////////////////////////////////////////////////////////////////
257
    naming::gid_type counter_creator(counter_info const& info,
258
        counter_path_elements const& paths,
259
        hpx::function<std::int64_t(bool)> const& total_creator,
260
        hpx::function<std::int64_t(bool)> const& individual_creator,
×
261
        char const* individual_name, std::size_t individual_count,
262
        error_code& ec)
×
263
    {
264
        if (paths.parentinstance_is_basename_)
265
        {
266
            HPX_THROWS_IF(ec, hpx::error::bad_parameter, "counter_creator",
267
                "invalid counter instance parent name: {}",
268
                paths.parentinstancename_);
×
269
            return naming::invalid_gid;
×
270
        }
271

272
        if (!total_creator.empty() && paths.instancename_ == "total" &&
273
            paths.instanceindex_ == -1)
×
274
        {
275
            // overall counter
×
276
            using detail::create_raw_counter;
×
277
            return create_raw_counter(info, total_creator, ec);
×
278
        }
×
279
        else if (!individual_creator.empty() &&
280
            paths.instancename_ == individual_name &&
281
            paths.instanceindex_ >= 0 &&
282
            static_cast<std::size_t>(paths.instanceindex_) < individual_count)
×
283
        {
284
            // specific counter
285
            using detail::create_raw_counter;
×
286
            return create_raw_counter(info, individual_creator, ec);
287
        }
288

289
        HPX_THROWS_IF(ec, hpx::error::bad_parameter, "counter_creator",
290
            "invalid counter instance name: {}", paths.instancename_);
291
        return naming::invalid_gid;
292
    }
293

294
    ///////////////////////////////////////////////////////////////////////
295
    // thread counts counter creation function
296
#if defined(HPX_HAVE_COROUTINE_COUNTERS)
297
    naming::gid_type thread_counts_counter_creator(
298
        counter_info const& info, error_code& ec)
299
    {
300
        // verify the validity of the counter instance name
301
        counter_path_elements paths;
302
        get_counter_path_elements(info.fullname_, paths, ec);
303
        if (ec)
304
        {
305
            return naming::invalid_gid;
306
        }
307

308
        struct creator_data
309
        {
310
            char const* const countername;
311
            hpx::function<std::int64_t(bool)> total_func;
312
            hpx::function<std::int64_t(bool)> individual_func;
313
            char const* const individual_name;
314
            std::size_t individual_count;
315
        };
316

317
        creator_data data[] = {
318
            // /threads{locality#%d/total}/count/stack-recycles
319
            {"count/stack-recycles",
320
                hpx::bind_front(&threads::coroutine_type::impl_type::
321
                        get_stack_recycle_count),
322
                hpx::function<std::uint64_t(bool)>(), "", 0},
323
#if !defined(HPX_WINDOWS) && !defined(HPX_HAVE_GENERIC_CONTEXT_COROUTINES)
324
            // /threads{locality#%d/total}/count/stack-unbinds
325
            {"count/stack-unbinds",
326
                hpx::bind_front(&threads::coroutine_type::impl_type::
327
                        get_stack_unbind_count),
328
                hpx::function<std::uint64_t(bool)>(), "", 0},
329
#endif
330
        };
331
        std::size_t const data_size = sizeof(data) / sizeof(data[0]);
332

333
        for (creator_data const* d = data; d < &d[data_size]; ++d)
334
        {
335
            if (paths.countername_ == d->countername)
336
            {
337
                return counter_creator(info, paths, d->total_func,
338
                    d->individual_func, d->individual_name, d->individual_count,
339
                    ec);
340
            }
341
        }
342

343
        HPX_THROWS_IF(ec, hpx::error::bad_parameter,
344
            "thread_counts_counter_creator",
345
            "invalid counter instance name: {}", paths.instancename_);
346
        return naming::invalid_gid;
347
    }
348
#endif
349
}    // namespace hpx::performance_counters::detail
350

32✔
351
namespace hpx::performance_counters {
352

353
    ///////////////////////////////////////////////////////////////////////////
354
    void register_threadmanager_counter_types(threads::threadmanager& tm)
355
    {
356
#if defined(HPX_HAVE_COROUTINE_COUNTERS)
357
        create_counter_func counts_creator(
358
            hpx::bind_front(&detail::thread_counts_counter_creator));
359
#endif
360

361
        generic_counter_type_data const counter_types[] = {
362
            // length of thread queue(s)
32✔
363
            {"/threadqueue/length", counter_type::raw,
364
                "returns the current queue length for the referenced queue",
365
                HPX_PERFORMANCE_COUNTER_V1,
32✔
366
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
367
                    &tm, &threads::threadmanager::get_queue_length,
368
                    &threads::thread_pool_base::get_queue_length),
369
                &locality_pool_thread_counter_discoverer, ""},
370
#ifdef HPX_HAVE_THREAD_QUEUE_WAITTIME
371
            // average thread wait time for queue(s)
372
            {"/threads/wait-time/pending", counter_type::average_timer,
373
                "returns the average wait time of pending threads for the "
374
                "referenced queue",
375
                HPX_PERFORMANCE_COUNTER_V1,
376
                hpx::bind_front(&detail::queue_wait_time_counter_creator, &tm,
377
                    &threads::threadmanager::get_average_thread_wait_time,
378
                    &threads::thread_pool_base::get_average_thread_wait_time),
379
                &locality_pool_thread_counter_discoverer, "ns"},
380
            // average task wait time for queue(s)
381
            {"/threads/wait-time/staged", counter_type::average_timer,
382
                "returns the average wait time of staged threads (task "
383
                "descriptions) for the referenced queue",
384
                HPX_PERFORMANCE_COUNTER_V1,
385
                hpx::bind_front(&detail::queue_wait_time_counter_creator, &tm,
386
                    &threads::threadmanager::get_average_task_wait_time,
387
                    &threads::thread_pool_base::get_average_task_wait_time),
388
                &locality_pool_thread_counter_discoverer, "ns"},
389
#endif
390
#ifdef HPX_HAVE_THREAD_IDLE_RATES
391
            // idle rate
392
            {"/threads/idle-rate", counter_type::average_count,
393
                "returns the idle rate for the referenced object",
394
                HPX_PERFORMANCE_COUNTER_V1,
395
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
396
                    &tm, &threads::threadmanager::avg_idle_rate,
397
                    &threads::thread_pool_base::avg_idle_rate),
398
                &locality_pool_thread_counter_discoverer, "0.01%"},
399
#ifdef HPX_HAVE_THREAD_CREATION_AND_CLEANUP_RATES
400
            {"/threads/creation-idle-rate", counter_type::average_count,
401
                "returns the % of idle-rate spent creating HPX-threads for the "
402
                "referenced object",
403
                HPX_PERFORMANCE_COUNTER_V1,
404
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
405
                    &tm, &threads::threadmanager::avg_creation_idle_rate,
406
                    &threads::thread_pool_base::avg_creation_idle_rate),
407
                &locality_pool_thread_counter_discoverer, "0.01%"},
408
            {"/threads/cleanup-idle-rate", counter_type::average_count,
409
                "returns the % of time spent cleaning up terminated "
410
                "HPX-threads for the referenced object",
411
                HPX_PERFORMANCE_COUNTER_V1,
412
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
413
                    &tm, &threads::threadmanager::avg_cleanup_idle_rate,
414
                    &threads::thread_pool_base::avg_cleanup_idle_rate),
415
                &locality_pool_thread_counter_discoverer, "0.01%"},
416
#endif
417
#endif
418
#ifdef HPX_HAVE_THREAD_CUMULATIVE_COUNTS
419
            // thread counts
420
            {"/threads/count/cumulative",
421
                counter_type::monotonically_increasing,
32✔
422
                "returns the overall number of executed (retired) HPX-threads "
423
                "for the referenced locality",
424
                HPX_PERFORMANCE_COUNTER_V1,
32✔
425
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
426
                    &tm, &threads::threadmanager::get_executed_threads,
427
                    &threads::thread_pool_base::get_executed_threads),
428
                &locality_pool_thread_counter_discoverer, ""},
429
            {"/threads/count/cumulative-phases",
430
                counter_type::monotonically_increasing,
32✔
431
                "returns the overall number of HPX-thread phases executed for "
432
                "the referenced locality",
433
                HPX_PERFORMANCE_COUNTER_V1,
32✔
434
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
435
                    &tm, &threads::threadmanager::get_executed_thread_phases,
436
                    &threads::thread_pool_base::get_executed_thread_phases),
437
                &locality_pool_thread_counter_discoverer, ""},
438
#ifdef HPX_HAVE_THREAD_IDLE_RATES
439
            {"/threads/time/average", counter_type::average_timer,
440
                "returns the average time spent executing one HPX-thread",
441
                HPX_PERFORMANCE_COUNTER_V1,
442
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
443
                    &tm, &threads::threadmanager::get_thread_duration,
444
                    &threads::thread_pool_base::get_thread_duration),
445
                &locality_pool_thread_counter_discoverer, "ns"},
446
            {"/threads/time/average-phase", counter_type::average_timer,
447
                "returns the average time spent executing one HPX-thread phase",
448
                HPX_PERFORMANCE_COUNTER_V1,
449
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
450
                    &tm, &threads::threadmanager::get_thread_phase_duration,
451
                    &threads::thread_pool_base::get_thread_phase_duration),
452
                &locality_pool_thread_counter_discoverer, "ns"},
453
            {"/threads/time/average-overhead", counter_type::average_timer,
454
                "returns average overhead time executing one HPX-thread",
455
                HPX_PERFORMANCE_COUNTER_V1,
456
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
457
                    &tm, &threads::threadmanager::get_thread_overhead,
458
                    &threads::thread_pool_base::get_thread_overhead),
459
                &locality_pool_thread_counter_discoverer, "ns"},
460
            {"/threads/time/average-phase-overhead",
461
                counter_type::average_timer,
462
                "returns average overhead time executing one HPX-thread phase",
463
                HPX_PERFORMANCE_COUNTER_V1,
464
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
465
                    &tm, &threads::threadmanager::get_thread_phase_overhead,
466
                    &threads::thread_pool_base::get_thread_phase_overhead),
467
                &locality_pool_thread_counter_discoverer, "ns"},
468
            {"/threads/time/cumulative", counter_type::elapsed_time,
469
                "returns the cumulative time spent executing HPX-threads",
470
                HPX_PERFORMANCE_COUNTER_V1,
471
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
472
                    &tm,
473
                    &threads::threadmanager::get_cumulative_thread_duration,
474
                    &threads::thread_pool_base::get_cumulative_thread_duration),
475
                &locality_pool_thread_counter_discoverer, "ns"},
476
            {"/threads/time/cumulative-overhead", counter_type::elapsed_time,
477
                "returns the cumulative overhead time incurred by executing "
478
                "HPX threads",
479
                HPX_PERFORMANCE_COUNTER_V1,
480
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
481
                    &tm,
482
                    &threads::threadmanager::get_cumulative_thread_overhead,
483
                    &threads::thread_pool_base::get_cumulative_thread_overhead),
484
                &locality_pool_thread_counter_discoverer, "ns"},
485
#endif
486
#endif
487

488
#if defined(HPX_HAVE_BACKGROUND_THREAD_COUNTERS) &&                            \
489
    defined(HPX_HAVE_THREAD_IDLE_RATES)
490
            {"/threads/time/background-work-duration",
491
                counter_type::elapsed_time,
492
                "returns the overall time spent running background work",
493
                HPX_PERFORMANCE_COUNTER_V1,
494
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
495
                    &tm, &threads::threadmanager::get_background_work_duration,
496
                    &threads::thread_pool_base::get_background_work_duration),
497
                &locality_pool_thread_counter_discoverer, "ns"},
498
            {"/threads/background-overhead", counter_type::aggregating,
499
                "returns the overall background overhead",
500
                HPX_PERFORMANCE_COUNTER_V1,
501
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
502
                    &tm, &threads::threadmanager::get_background_overhead,
503
                    &threads::thread_pool_base::get_background_overhead),
504
                &locality_pool_thread_counter_discoverer, "0.1%"},
505
            {"/threads/time/background-send-duration",
506
                counter_type::elapsed_time,
507
                "returns the overall time spent running background work "
508
                "related to sending parcels",
509
                HPX_PERFORMANCE_COUNTER_V1,
510
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
511
                    &tm, &threads::threadmanager::get_background_send_duration,
512
                    &threads::thread_pool_base::get_background_send_duration),
513
                &locality_pool_thread_counter_discoverer, "ns"},
514
            {"/threads/background-send-overhead", counter_type::aggregating,
515
                "returns the overall background overhead "
516
                "related to sending parcels",
517
                HPX_PERFORMANCE_COUNTER_V1,
518
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
519
                    &tm, &threads::threadmanager::get_background_send_overhead,
520
                    &threads::thread_pool_base::get_background_send_overhead),
521
                &locality_pool_thread_counter_discoverer, "0.1%"},
522
            {"/threads/time/background-receive-duration",
523
                counter_type::elapsed_time,
524
                "returns the overall time spent running background work "
525
                "related to receiving parcels",
526
                HPX_PERFORMANCE_COUNTER_V1,
527
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
528
                    &tm,
529
                    &threads::threadmanager::get_background_receive_duration,
530
                    &threads::thread_pool_base::
531
                        get_background_receive_duration),
532
                &locality_pool_thread_counter_discoverer, "ns"},
533
            {"/threads/background-receive-overhead", counter_type::aggregating,
534
                "returns the overall background overhead "
535
                "related to receiving parcels",
536
                HPX_PERFORMANCE_COUNTER_V1,
537
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
538
                    &tm,
539
                    &threads::threadmanager::get_background_receive_overhead,
540
                    &threads::thread_pool_base::
541
                        get_background_receive_overhead),
542
                &locality_pool_thread_counter_discoverer, "0.1%"},
543
#endif    // HPX_HAVE_BACKGROUND_THREAD_COUNTERS
544

545
            {"/threads/time/overall", counter_type::elapsed_time,
32✔
546
                "returns the overall time spent running the scheduler on a "
547
                "core",
548
                HPX_PERFORMANCE_COUNTER_V1,
32✔
549
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
550
                    &tm, &threads::threadmanager::get_cumulative_duration,
551
                    &threads::thread_pool_base::get_cumulative_duration),
552
                &locality_pool_thread_counter_discoverer, "ns"},
553
            {"/threads/count/instantaneous/all", counter_type::raw,
32✔
554
                "returns the overall current number of HPX-threads "
555
                "instantiated at the referenced locality",
556
                HPX_PERFORMANCE_COUNTER_V1,
32✔
557
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
558
                    &tm, &threads::threadmanager::get_thread_count_unknown,
559
                    &threads::thread_pool_base::get_thread_count_unknown),
560
                &locality_pool_thread_counter_discoverer, ""},
561
            {"/threads/count/instantaneous/active", counter_type::raw,
32✔
562
                "returns the current number of active HPX-threads "
563
                "at the referenced locality",
564
                HPX_PERFORMANCE_COUNTER_V1,
32✔
565
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
566
                    &tm, &threads::threadmanager::get_thread_count_active,
567
                    &threads::thread_pool_base::get_thread_count_active),
568
                &locality_pool_thread_counter_discoverer, ""},
569
            {"/threads/count/instantaneous/pending", counter_type::raw,
32✔
570
                "returns the current number of pending HPX-threads "
571
                "at the referenced locality",
572
                HPX_PERFORMANCE_COUNTER_V1,
32✔
573
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
574
                    &tm, &threads::threadmanager::get_thread_count_pending,
575
                    &threads::thread_pool_base::get_thread_count_pending),
576
                &locality_pool_thread_counter_discoverer, ""},
577
            {"/threads/count/instantaneous/suspended", counter_type::raw,
32✔
578
                "returns the current number of suspended HPX-threads "
579
                "at the referenced locality",
580
                HPX_PERFORMANCE_COUNTER_V1,
32✔
581
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
582
                    &tm, &threads::threadmanager::get_thread_count_suspended,
583
                    &threads::thread_pool_base::get_thread_count_suspended),
584
                &locality_pool_thread_counter_discoverer, ""},
585
            {"/threads/count/instantaneous/terminated", counter_type::raw,
32✔
586
                "returns the current number of terminated HPX-threads "
587
                "at the referenced locality",
588
                HPX_PERFORMANCE_COUNTER_V1,
32✔
589
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
590
                    &tm, &threads::threadmanager::get_thread_count_terminated,
591
                    &threads::thread_pool_base::get_thread_count_terminated),
592
                &locality_pool_thread_counter_discoverer, ""},
593
            {"/threads/count/instantaneous/staged", counter_type::raw,
594
                "returns the current number of staged HPX-threads (task "
32✔
595
                "descriptions) "
596
                "at the referenced locality",
597
                HPX_PERFORMANCE_COUNTER_V1,
32✔
598
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
599
                    &tm, &threads::threadmanager::get_thread_count_staged,
600
                    &threads::thread_pool_base::get_thread_count_staged),
601
                &locality_pool_thread_counter_discoverer, ""},
602
#if defined(HPX_HAVE_COROUTINE_COUNTERS)
603
            {"/threads/count/stack-recycles",
604
                counter_type::monotonically_increasing,
605
                "returns the total number of HPX-thread recycling operations "
606
                "performed for the referenced locality",
607
                HPX_PERFORMANCE_COUNTER_V1, counts_creator,
608
                &locality_counter_discoverer, ""},
609
#if !defined(HPX_WINDOWS) && !defined(HPX_HAVE_GENERIC_CONTEXT_COROUTINES)
610
            {"/threads/count/stack-unbinds",
611
                counter_type::monotonically_increasing,
612
                "returns the total number of HPX-thread unbind (madvise) "
613
                "operations performed for the referenced locality",
614
                HPX_PERFORMANCE_COUNTER_V1, counts_creator,
615
                &locality_counter_discoverer, ""},
616
#endif
617
#endif
618
#ifdef HPX_HAVE_THREAD_STEALING_COUNTS
619
            {"/threads/count/pending-misses",
620
                counter_type::monotonically_increasing,
621
                "returns the number of times that the referenced worker-thread "
622
                "on the referenced locality failed to find pending HPX-threads "
623
                "in its associated queue",
624
                HPX_PERFORMANCE_COUNTER_V1,
625
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
626
                    &tm, &threads::threadmanager::get_num_pending_misses,
627
                    &threads::thread_pool_base::get_num_pending_misses),
628
                &locality_pool_thread_counter_discoverer, ""},
629
            {"/threads/count/pending-accesses",
630
                counter_type::monotonically_increasing,
631
                "returns the number of times that the referenced worker-thread "
632
                "on the referenced locality looked for pending HPX-threads "
633
                "in its associated queue",
634
                HPX_PERFORMANCE_COUNTER_V1,
635
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
636
                    &tm, &threads::threadmanager::get_num_pending_accesses,
637
                    &threads::thread_pool_base::get_num_pending_accesses),
638
                &locality_pool_thread_counter_discoverer, ""},
639
            {"/threads/count/stolen-from-pending",
640
                counter_type::monotonically_increasing,
641
                "returns the overall number of pending HPX-threads stolen by "
642
                "neighboring"
643
                "schedulers from &tm scheduler for the referenced locality",
644
                HPX_PERFORMANCE_COUNTER_V1,
645
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
646
                    &tm, &threads::threadmanager::get_num_stolen_from_pending,
647
                    &threads::thread_pool_base::get_num_stolen_from_pending),
648
                &locality_pool_thread_counter_discoverer, ""},
649
            {"/threads/count/stolen-from-staged",
650
                counter_type::monotonically_increasing,
651
                "returns the overall number of task descriptions stolen by "
652
                "neighboring"
653
                "schedulers from tm scheduler for the referenced locality",
654
                HPX_PERFORMANCE_COUNTER_V1,
655
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
656
                    &tm, &threads::threadmanager::get_num_stolen_from_staged,
657
                    &threads::thread_pool_base::get_num_stolen_from_staged),
658
                &locality_pool_thread_counter_discoverer, ""},
659
            {"/threads/count/stolen-to-pending",
660
                counter_type::monotonically_increasing,
661
                "returns the overall number of pending HPX-threads stolen from "
662
                "neighboring"
663
                "schedulers for the referenced locality",
664
                HPX_PERFORMANCE_COUNTER_V1,
665
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
666
                    &tm, &threads::threadmanager::get_num_stolen_to_pending,
667
                    &threads::thread_pool_base::get_num_stolen_to_pending),
668
                &locality_pool_thread_counter_discoverer, ""},
669
            {"/threads/count/stolen-to-staged",
670
                counter_type::monotonically_increasing,
671
                "returns the overall number of task descriptions stolen from "
672
                "neighboring"
673
                "schedulers for the referenced locality",
674
                HPX_PERFORMANCE_COUNTER_V1,
675
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
676
                    &tm, &threads::threadmanager::get_num_stolen_to_staged,
677
                    &threads::thread_pool_base::get_num_stolen_to_staged),
678
                &locality_pool_thread_counter_discoverer, ""},
679
#endif
680
            // scheduler utilization
681
            {"/scheduler/utilization/instantaneous", counter_type::raw,
682
                "returns the current scheduler utilization",
32✔
683
                HPX_PERFORMANCE_COUNTER_V1,
684
                hpx::bind_front(
685
                    &detail::scheduler_utilization_counter_creator, &tm),
686
                &locality_pool_counter_discoverer, "%"},
687
            // idle-loop count
32✔
688
            {"/threads/idle-loop-count/instantaneous", counter_type::raw,
689
                "returns the current value of the scheduler idle-loop count",
690
                HPX_PERFORMANCE_COUNTER_V1,
32✔
691
                hpx::bind_front(
692
                    &detail::locality_pool_thread_no_total_counter_creator, &tm,
693
                    &threads::thread_pool_base::get_idle_loop_count),
694
                &locality_pool_thread_no_total_counter_discoverer, ""},
695
            // busy-loop count
×
696
            {"/threads/busy-loop-count/instantaneous", counter_type::raw,
697
                "returns the current value of the scheduler busy-loop count",
698
                HPX_PERFORMANCE_COUNTER_V1,
32✔
699
                hpx::bind_front(
416✔
700
                    &detail::locality_pool_thread_no_total_counter_creator, &tm,
701
                    &threads::thread_pool_base::get_busy_loop_count),
32✔
702
                &locality_pool_thread_no_total_counter_discoverer, ""}};
703

928✔
704
        install_counter_types(
705
            counter_types, sizeof(counter_types) / sizeof(counter_types[0]));
706
    }
707
}    // namespace hpx::performance_counters
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc