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

STEllAR-GROUP / hpx / #853

19 Dec 2022 01:01AM UTC coverage: 86.287% (+0.4%) from 85.912%
#853

push

StellarBot
Merge #6109

6109: Modernize serialization module r=hkaiser a=hkaiser

- flyby separate serialization of Boost types

working towards https://github.com/STEllAR-GROUP/hpx/issues/5497

Co-authored-by: Hartmut Kaiser <hartmut.kaiser@gmail.com>

53 of 53 new or added lines in 6 files covered. (100.0%)

173939 of 201582 relevant lines covered (86.29%)

1931657.12 hits per line

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

55.12
/libs/full/performance_counters/src/threadmanager_counter_types.cpp
1
//  Copyright (c) 2007-2022 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/functional/bind_back.hpp>
14
#include <hpx/functional/bind_front.hpp>
15
#include <hpx/modules/errors.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
#include <hpx/runtime_local/thread_pool_helpers.hpp>
22
#include <hpx/schedulers/maintain_queue_wait_times.hpp>
23

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

28
///////////////////////////////////////////////////////////////////////////////
29
namespace hpx { namespace performance_counters { namespace detail {
30

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

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

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

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

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

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

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

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

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

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

145
        using detail::create_raw_counter;
146

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

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

179
        HPX_THROWS_IF(ec, hpx::error::bad_parameter,
×
180
            "scheduler_utilization_creator",
181
            "invalid counter instance name: {}", paths.instancename_);
182
        return naming::invalid_gid;
×
183
    }
1✔
184

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

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

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

246
        HPX_THROWS_IF(ec, hpx::error::bad_parameter,
×
247
            "locality_pool_thread_no_total_counter_creator",
248
            "invalid counter instance name: {}", paths.instancename_);
249
        return naming::invalid_gid;
×
250
    }
2✔
251

252
    ///////////////////////////////////////////////////////////////////////
253
    bool locality_allocator_counter_discoverer(counter_info const& info,
×
254
        discover_counter_func const& f, discover_counters_mode mode,
255
        error_code& ec)
256
    {
257
        counter_info i = info;
×
258

259
        // compose the counter name templates
260
        counter_path_elements p;
×
261
        counter_status status =
×
262
            get_counter_path_elements(info.fullname_, p, ec);
×
263
        if (!status_is_valid(status))
×
264
        {
265
            return false;
×
266
        }
267

268
        if (mode == discover_counters_mode::minimal ||
×
269
            p.parentinstancename_.empty() || p.instancename_.empty())
×
270
        {
271
            if (p.parentinstancename_.empty())
×
272
            {
273
                p.parentinstancename_ = "locality#*";
×
274
                p.parentinstanceindex_ = -1;
×
275
            }
×
276

277
            if (p.instancename_.empty())
×
278
            {
279
                p.instancename_ = "total";
×
280
                p.instanceindex_ = -1;
×
281
            }
×
282

283
            status = get_counter_name(p, i.fullname_, ec);
×
284
            if (!status_is_valid(status) || !f(i, ec) || ec)
×
285
            {
286
                return false;
×
287
            }
288

289
            p.instancename_ = "allocator#*";
×
290
            p.instanceindex_ = -1;
×
291

292
            if (mode == discover_counters_mode::full)
×
293
            {
294
                for (std::size_t t = 0; t != HPX_COROUTINE_NUM_ALL_HEAPS; ++t)
×
295
                {
296
                    p.instancename_ = "allocator";
×
297
                    p.instanceindex_ = static_cast<std::int32_t>(t);
×
298
                    status = get_counter_name(p, i.fullname_, ec);
×
299
                    if (!status_is_valid(status) || !f(i, ec) || ec)
×
300
                        return false;
×
301
                }
×
302
            }
×
303
            else
304
            {
305
                status = get_counter_name(p, i.fullname_, ec);
×
306
                if (!status_is_valid(status) || !f(i, ec) || ec)
×
307
                    return false;
×
308
            }
309
        }
×
310
        else if (p.instancename_ == "total" && p.instanceindex_ == -1)
×
311
        {
312
            // overall counter
313
            status = get_counter_name(p, i.fullname_, ec);
×
314
            if (!status_is_valid(status) || !f(i, ec) || ec)
×
315
            {
316
                return false;
×
317
            }
318
        }
×
319
        else if (p.instancename_ == "allocator#*")
×
320
        {
321
            for (std::size_t t = 0; t != HPX_COROUTINE_NUM_ALL_HEAPS; ++t)
×
322
            {
323
                p.instancename_ = "allocator";
×
324
                p.instanceindex_ = static_cast<std::int32_t>(t);
×
325
                status = get_counter_name(p, i.fullname_, ec);
×
326
                if (!status_is_valid(status) || !f(i, ec) || ec)
×
327
                {
328
                    return false;
×
329
                }
330
            }
×
331
        }
×
332
        else if (!f(i, ec) || ec)
×
333
        {
334
            return false;
×
335
        }
336

337
        if (&ec != &throws)
×
338
        {
339
            ec = make_success_code();
×
340
        }
×
341

342
        return true;
×
343
    }
×
344

345
    ///////////////////////////////////////////////////////////////////////////
346
    naming::gid_type counter_creator(counter_info const& info,
×
347
        counter_path_elements const& paths,
348
        hpx::function<std::int64_t(bool)> const& total_creator,
349
        hpx::function<std::int64_t(bool)> const& individual_creator,
350
        char const* individual_name, std::size_t individual_count,
351
        error_code& ec)
352
    {
353
        if (paths.parentinstance_is_basename_)
×
354
        {
355
            HPX_THROWS_IF(ec, hpx::error::bad_parameter, "counter_creator",
×
356
                "invalid counter instance parent name: {}",
357
                paths.parentinstancename_);
358
            return naming::invalid_gid;
×
359
        }
360

361
        if (!total_creator.empty() && paths.instancename_ == "total" &&
×
362
            paths.instanceindex_ == -1)
×
363
        {
364
            // overall counter
365
            using detail::create_raw_counter;
366
            return create_raw_counter(info, total_creator, ec);
×
367
        }
368
        else if (!individual_creator.empty() &&
×
369
            paths.instancename_ == individual_name &&
×
370
            paths.instanceindex_ >= 0 &&
×
371
            std::size_t(paths.instanceindex_) < individual_count)
×
372
        {
373
            // specific counter
374
            using detail::create_raw_counter;
375
            return create_raw_counter(info, individual_creator, ec);
×
376
        }
377

378
        HPX_THROWS_IF(ec, hpx::error::bad_parameter, "counter_creator",
×
379
            "invalid counter instance name: {}", paths.instancename_);
380
        return naming::invalid_gid;
×
381
    }
×
382

383
    ///////////////////////////////////////////////////////////////////////
384
    // thread counts counter creation function
385
#if defined(HPX_HAVE_COROUTINE_COUNTERS)
386
    naming::gid_type thread_counts_counter_creator(
387
        counter_info const& info, error_code& ec)
388
    {
389
        // verify the validity of the counter instance name
390
        counter_path_elements paths;
391
        get_counter_path_elements(info.fullname_, paths, ec);
392
        if (ec)
393
        {
394
            return naming::invalid_gid;
395
        }
396

397
        struct creator_data
398
        {
399
            char const* const countername;
400
            hpx::function<std::int64_t(bool)> total_func;
401
            hpx::function<std::int64_t(bool)> individual_func;
402
            char const* const individual_name;
403
            std::size_t individual_count;
404
        };
405

406
        creator_data data[] = {
407
            // /threads{locality#%d/total}/count/stack-recycles
408
            {"count/stack-recycles",
409
                hpx::bind_front(&threads::coroutine_type::impl_type::
410
                                    get_stack_recycle_count),
411
                hpx::function<std::uint64_t(bool)>(), "", 0},
412
#if !defined(HPX_WINDOWS) && !defined(HPX_HAVE_GENERIC_CONTEXT_COROUTINES)
413
            // /threads{locality#%d/total}/count/stack-unbinds
414
            {"count/stack-unbinds",
415
                hpx::bind_front(&threads::coroutine_type::impl_type::
416
                                    get_stack_unbind_count),
417
                hpx::function<std::uint64_t(bool)>(), "", 0},
418
#endif
419
        };
420
        std::size_t const data_size = sizeof(data) / sizeof(data[0]);
421

422
        for (creator_data const* d = data; d < &d[data_size]; ++d)
423
        {
424
            if (paths.countername_ == d->countername)
425
            {
426
                return counter_creator(info, paths, d->total_func,
427
                    d->individual_func, d->individual_name, d->individual_count,
428
                    ec);
429
            }
430
        }
431

432
        HPX_THROWS_IF(ec, hpx::error::bad_parameter,
433
            "thread_counts_counter_creator",
434
            "invalid counter instance name: {}", paths.instancename_);
435
        return naming::invalid_gid;
436
    }
437
#endif
438
}}}    // namespace hpx::performance_counters::detail
439

440
namespace hpx { namespace performance_counters {
441

442
    ///////////////////////////////////////////////////////////////////////////
443
    void register_threadmanager_counter_types(threads::threadmanager& tm)
593✔
444
    {
445
#if defined(HPX_HAVE_COROUTINE_COUNTERS)
446
        create_counter_func counts_creator(
447
            hpx::bind_front(&detail::thread_counts_counter_creator));
448
#endif
449

450
        generic_counter_type_data counter_types[] = {
8,302✔
451
            // length of thread queue(s)
452
            {"/threadqueue/length", counter_type::raw,
1,186✔
453
                "returns the current queue length for the referenced queue",
593✔
454
                HPX_PERFORMANCE_COUNTER_V1,
455
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
1,186✔
456
                    &tm, &threads::threadmanager::get_queue_length,
593✔
457
                    &threads::thread_pool_base::get_queue_length),
593✔
458
                &locality_pool_thread_counter_discoverer, ""},
593✔
459
#ifdef HPX_HAVE_THREAD_QUEUE_WAITTIME
460
            // average thread wait time for queue(s)
461
            {"/threads/wait-time/pending", counter_type::average_timer,
462
                "returns the average wait time of pending threads for the "
463
                "referenced queue",
464
                HPX_PERFORMANCE_COUNTER_V1,
465
                hpx::bind_front(&detail::queue_wait_time_counter_creator, &tm,
466
                    &threads::threadmanager::get_average_thread_wait_time,
467
                    &threads::thread_pool_base::get_average_thread_wait_time),
468
                &locality_pool_thread_counter_discoverer, "ns"},
469
            // average task wait time for queue(s)
470
            {"/threads/wait-time/staged", counter_type::average_timer,
471
                "returns the average wait time of staged threads (task "
472
                "descriptions) for the referenced queue",
473
                HPX_PERFORMANCE_COUNTER_V1,
474
                hpx::bind_front(&detail::queue_wait_time_counter_creator, &tm,
475
                    &threads::threadmanager::get_average_task_wait_time,
476
                    &threads::thread_pool_base::get_average_task_wait_time),
477
                &locality_pool_thread_counter_discoverer, "ns"},
478
#endif
479
#ifdef HPX_HAVE_THREAD_IDLE_RATES
480
            // idle rate
481
            {"/threads/idle-rate", counter_type::average_count,
482
                "returns the idle rate for the referenced object",
483
                HPX_PERFORMANCE_COUNTER_V1,
484
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
485
                    &tm, &threads::threadmanager::avg_idle_rate,
486
                    &threads::thread_pool_base::avg_idle_rate),
487
                &locality_pool_thread_counter_discoverer, "0.01%"},
488
#ifdef HPX_HAVE_THREAD_CREATION_AND_CLEANUP_RATES
489
            {"/threads/creation-idle-rate", counter_type::average_count,
490
                "returns the % of idle-rate spent creating HPX-threads for the "
491
                "referenced object",
492
                HPX_PERFORMANCE_COUNTER_V1,
493
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
494
                    &tm, &threads::threadmanager::avg_creation_idle_rate,
495
                    &threads::thread_pool_base::avg_creation_idle_rate),
496
                &locality_pool_thread_counter_discoverer, "0.01%"},
497
            {"/threads/cleanup-idle-rate", counter_type::average_count,
498
                "returns the % of time spent cleaning up terminated "
499
                "HPX-threads for the referenced object",
500
                HPX_PERFORMANCE_COUNTER_V1,
501
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
502
                    &tm, &threads::threadmanager::avg_cleanup_idle_rate,
503
                    &threads::thread_pool_base::avg_cleanup_idle_rate),
504
                &locality_pool_thread_counter_discoverer, "0.01%"},
505
#endif
506
#endif
507
#ifdef HPX_HAVE_THREAD_CUMULATIVE_COUNTS
508
            // thread counts
509
            {"/threads/count/cumulative",
1,186✔
510
                counter_type::monotonically_increasing,
511
                "returns the overall number of executed (retired) HPX-threads "
593✔
512
                "for the referenced locality",
513
                HPX_PERFORMANCE_COUNTER_V1,
514
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
1,186✔
515
                    &tm, &threads::threadmanager::get_executed_threads,
593✔
516
                    &threads::thread_pool_base::get_executed_threads),
593✔
517
                &locality_pool_thread_counter_discoverer, ""},
593✔
518
            {"/threads/count/cumulative-phases",
1,186✔
519
                counter_type::monotonically_increasing,
520
                "returns the overall number of HPX-thread phases executed for "
593✔
521
                "the referenced locality",
522
                HPX_PERFORMANCE_COUNTER_V1,
523
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
1,186✔
524
                    &tm, &threads::threadmanager::get_executed_thread_phases,
593✔
525
                    &threads::thread_pool_base::get_executed_thread_phases),
593✔
526
                &locality_pool_thread_counter_discoverer, ""},
593✔
527
#ifdef HPX_HAVE_THREAD_IDLE_RATES
528
            {"/threads/time/average", counter_type::average_timer,
529
                "returns the average time spent executing one HPX-thread",
530
                HPX_PERFORMANCE_COUNTER_V1,
531
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
532
                    &tm, &threads::threadmanager::get_thread_duration,
533
                    &threads::thread_pool_base::get_thread_duration),
534
                &locality_pool_thread_counter_discoverer, "ns"},
535
            {"/threads/time/average-phase", counter_type::average_timer,
536
                "returns the average time spent executing one HPX-thread phase",
537
                HPX_PERFORMANCE_COUNTER_V1,
538
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
539
                    &tm, &threads::threadmanager::get_thread_phase_duration,
540
                    &threads::thread_pool_base::get_thread_phase_duration),
541
                &locality_pool_thread_counter_discoverer, "ns"},
542
            {"/threads/time/average-overhead", counter_type::average_timer,
543
                "returns average overhead time executing one HPX-thread",
544
                HPX_PERFORMANCE_COUNTER_V1,
545
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
546
                    &tm, &threads::threadmanager::get_thread_overhead,
547
                    &threads::thread_pool_base::get_thread_overhead),
548
                &locality_pool_thread_counter_discoverer, "ns"},
549
            {"/threads/time/average-phase-overhead",
550
                counter_type::average_timer,
551
                "returns average overhead time executing one HPX-thread phase",
552
                HPX_PERFORMANCE_COUNTER_V1,
553
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
554
                    &tm, &threads::threadmanager::get_thread_phase_overhead,
555
                    &threads::thread_pool_base::get_thread_phase_overhead),
556
                &locality_pool_thread_counter_discoverer, "ns"},
557
            {"/threads/time/cumulative", counter_type::elapsed_time,
558
                "returns the cumulative time spent executing HPX-threads",
559
                HPX_PERFORMANCE_COUNTER_V1,
560
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
561
                    &tm,
562
                    &threads::threadmanager::get_cumulative_thread_duration,
563
                    &threads::thread_pool_base::get_cumulative_thread_duration),
564
                &locality_pool_thread_counter_discoverer, "ns"},
565
            {"/threads/time/cumulative-overhead", counter_type::elapsed_time,
566
                "returns the cumulative overhead time incurred by executing "
567
                "HPX threads",
568
                HPX_PERFORMANCE_COUNTER_V1,
569
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
570
                    &tm,
571
                    &threads::threadmanager::get_cumulative_thread_overhead,
572
                    &threads::thread_pool_base::get_cumulative_thread_overhead),
573
                &locality_pool_thread_counter_discoverer, "ns"},
574
#endif
575
#endif
576

577
#if defined(HPX_HAVE_BACKGROUND_THREAD_COUNTERS) &&                            \
578
    defined(HPX_HAVE_THREAD_IDLE_RATES)
579
            {"/threads/time/background-work-duration",
580
                counter_type::elapsed_time,
581
                "returns the overall time spent running background work",
582
                HPX_PERFORMANCE_COUNTER_V1,
583
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
584
                    &tm, &threads::threadmanager::get_background_work_duration,
585
                    &threads::thread_pool_base::get_background_work_duration),
586
                &locality_pool_thread_counter_discoverer, "ns"},
587
            {"/threads/background-overhead", counter_type::aggregating,
588
                "returns the overall background overhead",
589
                HPX_PERFORMANCE_COUNTER_V1,
590
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
591
                    &tm, &threads::threadmanager::get_background_overhead,
592
                    &threads::thread_pool_base::get_background_overhead),
593
                &locality_pool_thread_counter_discoverer, "0.1%"},
594
            {"/threads/time/background-send-duration",
595
                counter_type::elapsed_time,
596
                "returns the overall time spent running background work "
597
                "related to sending parcels",
598
                HPX_PERFORMANCE_COUNTER_V1,
599
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
600
                    &tm, &threads::threadmanager::get_background_send_duration,
601
                    &threads::thread_pool_base::get_background_send_duration),
602
                &locality_pool_thread_counter_discoverer, "ns"},
603
            {"/threads/background-send-overhead", counter_type::aggregating,
604
                "returns the overall background overhead "
605
                "related to sending parcels",
606
                HPX_PERFORMANCE_COUNTER_V1,
607
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
608
                    &tm, &threads::threadmanager::get_background_send_overhead,
609
                    &threads::thread_pool_base::get_background_send_overhead),
610
                &locality_pool_thread_counter_discoverer, "0.1%"},
611
            {"/threads/time/background-receive-duration",
612
                counter_type::elapsed_time,
613
                "returns the overall time spent running background work "
614
                "related to receiving parcels",
615
                HPX_PERFORMANCE_COUNTER_V1,
616
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
617
                    &tm,
618
                    &threads::threadmanager::get_background_receive_duration,
619
                    &threads::thread_pool_base::
620
                        get_background_receive_duration),
621
                &locality_pool_thread_counter_discoverer, "ns"},
622
            {"/threads/background-receive-overhead", counter_type::aggregating,
623
                "returns the overall background overhead "
624
                "related to receiving parcels",
625
                HPX_PERFORMANCE_COUNTER_V1,
626
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
627
                    &tm,
628
                    &threads::threadmanager::get_background_receive_overhead,
629
                    &threads::thread_pool_base::
630
                        get_background_receive_overhead),
631
                &locality_pool_thread_counter_discoverer, "0.1%"},
632
#endif    // HPX_HAVE_BACKGROUND_THREAD_COUNTERS
633

634
            {"/threads/time/overall", counter_type::elapsed_time,
1,186✔
635
                "returns the overall time spent running the scheduler on a "
593✔
636
                "core",
637
                HPX_PERFORMANCE_COUNTER_V1,
638
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
1,186✔
639
                    &tm, &threads::threadmanager::get_cumulative_duration,
593✔
640
                    &threads::thread_pool_base::get_cumulative_duration),
593✔
641
                &locality_pool_thread_counter_discoverer, "ns"},
593✔
642
            {"/threads/count/instantaneous/all", counter_type::raw,
1,186✔
643
                "returns the overall current number of HPX-threads "
593✔
644
                "instantiated at the referenced locality",
645
                HPX_PERFORMANCE_COUNTER_V1,
646
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
1,186✔
647
                    &tm, &threads::threadmanager::get_thread_count_unknown,
593✔
648
                    &threads::thread_pool_base::get_thread_count_unknown),
593✔
649
                &locality_pool_thread_counter_discoverer, ""},
593✔
650
            {"/threads/count/instantaneous/active", counter_type::raw,
1,186✔
651
                "returns the current number of active HPX-threads "
593✔
652
                "at the referenced locality",
653
                HPX_PERFORMANCE_COUNTER_V1,
654
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
1,186✔
655
                    &tm, &threads::threadmanager::get_thread_count_active,
593✔
656
                    &threads::thread_pool_base::get_thread_count_active),
593✔
657
                &locality_pool_thread_counter_discoverer, ""},
593✔
658
            {"/threads/count/instantaneous/pending", counter_type::raw,
1,186✔
659
                "returns the current number of pending HPX-threads "
593✔
660
                "at the referenced locality",
661
                HPX_PERFORMANCE_COUNTER_V1,
662
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
1,186✔
663
                    &tm, &threads::threadmanager::get_thread_count_pending,
593✔
664
                    &threads::thread_pool_base::get_thread_count_pending),
593✔
665
                &locality_pool_thread_counter_discoverer, ""},
593✔
666
            {"/threads/count/instantaneous/suspended", counter_type::raw,
1,186✔
667
                "returns the current number of suspended HPX-threads "
593✔
668
                "at the referenced locality",
669
                HPX_PERFORMANCE_COUNTER_V1,
670
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
1,186✔
671
                    &tm, &threads::threadmanager::get_thread_count_suspended,
593✔
672
                    &threads::thread_pool_base::get_thread_count_suspended),
593✔
673
                &locality_pool_thread_counter_discoverer, ""},
593✔
674
            {"/threads/count/instantaneous/terminated", counter_type::raw,
1,186✔
675
                "returns the current number of terminated HPX-threads "
593✔
676
                "at the referenced locality",
677
                HPX_PERFORMANCE_COUNTER_V1,
678
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
1,186✔
679
                    &tm, &threads::threadmanager::get_thread_count_terminated,
593✔
680
                    &threads::thread_pool_base::get_thread_count_terminated),
593✔
681
                &locality_pool_thread_counter_discoverer, ""},
593✔
682
            {"/threads/count/instantaneous/staged", counter_type::raw,
1,186✔
683
                "returns the current number of staged HPX-threads (task "
593✔
684
                "descriptions) "
685
                "at the referenced locality",
686
                HPX_PERFORMANCE_COUNTER_V1,
687
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
1,186✔
688
                    &tm, &threads::threadmanager::get_thread_count_staged,
593✔
689
                    &threads::thread_pool_base::get_thread_count_staged),
593✔
690
                &locality_pool_thread_counter_discoverer, ""},
593✔
691
#if defined(HPX_HAVE_COROUTINE_COUNTERS)
692
            {"/threads/count/stack-recycles",
693
                counter_type::monotonically_increasing,
694
                "returns the total number of HPX-thread recycling operations "
695
                "performed for the referenced locality",
696
                HPX_PERFORMANCE_COUNTER_V1, counts_creator,
697
                &locality_counter_discoverer, ""},
698
#if !defined(HPX_WINDOWS) && !defined(HPX_HAVE_GENERIC_CONTEXT_COROUTINES)
699
            {"/threads/count/stack-unbinds",
700
                counter_type::monotonically_increasing,
701
                "returns the total number of HPX-thread unbind (madvise) "
702
                "operations performed for the referenced locality",
703
                HPX_PERFORMANCE_COUNTER_V1, counts_creator,
704
                &locality_counter_discoverer, ""},
705
#endif
706
            {"/threads/count/objects", counter_type::monotonically_increasing,
707
                "returns the overall number of created HPX-thread objects for "
708
                "the referenced locality",
709
                HPX_PERFORMANCE_COUNTER_V1, counts_creator,
710
                &detail::locality_allocator_counter_discoverer, ""},
711
#endif
712
#ifdef HPX_HAVE_THREAD_STEALING_COUNTS
713
            {"/threads/count/pending-misses",
714
                counter_type::monotonically_increasing,
715
                "returns the number of times that the referenced worker-thread "
716
                "on the referenced locality failed to find pending HPX-threads "
717
                "in its associated queue",
718
                HPX_PERFORMANCE_COUNTER_V1,
719
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
720
                    &tm, &threads::threadmanager::get_num_pending_misses,
721
                    &threads::thread_pool_base::get_num_pending_misses),
722
                &locality_pool_thread_counter_discoverer, ""},
723
            {"/threads/count/pending-accesses",
724
                counter_type::monotonically_increasing,
725
                "returns the number of times that the referenced worker-thread "
726
                "on the referenced locality looked for pending HPX-threads "
727
                "in its associated queue",
728
                HPX_PERFORMANCE_COUNTER_V1,
729
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
730
                    &tm, &threads::threadmanager::get_num_pending_accesses,
731
                    &threads::thread_pool_base::get_num_pending_accesses),
732
                &locality_pool_thread_counter_discoverer, ""},
733
            {"/threads/count/stolen-from-pending",
734
                counter_type::monotonically_increasing,
735
                "returns the overall number of pending HPX-threads stolen by "
736
                "neighboring"
737
                "schedulers from &tm scheduler for the referenced locality",
738
                HPX_PERFORMANCE_COUNTER_V1,
739
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
740
                    &tm, &threads::threadmanager::get_num_stolen_from_pending,
741
                    &threads::thread_pool_base::get_num_stolen_from_pending),
742
                &locality_pool_thread_counter_discoverer, ""},
743
            {"/threads/count/stolen-from-staged",
744
                counter_type::monotonically_increasing,
745
                "returns the overall number of task descriptions stolen by "
746
                "neighboring"
747
                "schedulers from tm scheduler for the referenced locality",
748
                HPX_PERFORMANCE_COUNTER_V1,
749
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
750
                    &tm, &threads::threadmanager::get_num_stolen_from_staged,
751
                    &threads::thread_pool_base::get_num_stolen_from_staged),
752
                &locality_pool_thread_counter_discoverer, ""},
753
            {"/threads/count/stolen-to-pending",
754
                counter_type::monotonically_increasing,
755
                "returns the overall number of pending HPX-threads stolen from "
756
                "neighboring"
757
                "schedulers for the referenced locality",
758
                HPX_PERFORMANCE_COUNTER_V1,
759
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
760
                    &tm, &threads::threadmanager::get_num_stolen_to_pending,
761
                    &threads::thread_pool_base::get_num_stolen_to_pending),
762
                &locality_pool_thread_counter_discoverer, ""},
763
            {"/threads/count/stolen-to-staged",
764
                counter_type::monotonically_increasing,
765
                "returns the overall number of task descriptions stolen from "
766
                "neighboring"
767
                "schedulers for the referenced locality",
768
                HPX_PERFORMANCE_COUNTER_V1,
769
                hpx::bind_front(&detail::locality_pool_thread_counter_creator,
770
                    &tm, &threads::threadmanager::get_num_stolen_to_staged,
771
                    &threads::thread_pool_base::get_num_stolen_to_staged),
772
                &locality_pool_thread_counter_discoverer, ""},
773
#endif
774
            // scheduler utilization
775
            {"/scheduler/utilization/instantaneous", counter_type::raw,
1,186✔
776
                "returns the current scheduler utilization",
593✔
777
                HPX_PERFORMANCE_COUNTER_V1,
778
                hpx::bind_front(
593✔
779
                    &detail::scheduler_utilization_counter_creator, &tm),
593✔
780
                &locality_pool_counter_discoverer, "%"},
593✔
781
            // idle-loop count
782
            {"/threads/idle-loop-count/instantaneous", counter_type::raw,
1,186✔
783
                "returns the current value of the scheduler idle-loop count",
593✔
784
                HPX_PERFORMANCE_COUNTER_V1,
785
                hpx::bind_front(
593✔
786
                    &detail::locality_pool_thread_no_total_counter_creator, &tm,
593✔
787
                    &threads::thread_pool_base::get_idle_loop_count),
593✔
788
                &locality_pool_thread_no_total_counter_discoverer, ""},
593✔
789
            // busy-loop count
790
            {"/threads/busy-loop-count/instantaneous", counter_type::raw,
1,186✔
791
                "returns the current value of the scheduler busy-loop count",
593✔
792
                HPX_PERFORMANCE_COUNTER_V1,
793
                hpx::bind_front(
593✔
794
                    &detail::locality_pool_thread_no_total_counter_creator, &tm,
593✔
795
                    &threads::thread_pool_base::get_busy_loop_count),
593✔
796
                &locality_pool_thread_no_total_counter_discoverer, ""}
593✔
797
        };
798

799
        install_counter_types(
593✔
800
            counter_types, sizeof(counter_types) / sizeof(counter_types[0]));
593✔
801
    }
7,709✔
802
}}    // 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