• 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

8.2
/libs/full/performance_counters/src/counters.cpp
1
//  Copyright (c) 2007-2025 Hartmut Kaiser
2
//  Copyright (c)      2011 Bryce Lelbach
3
//
4
//  SPDX-License-Identifier: BSL-1.0
5
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
6
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7

8
#include <hpx/config.hpp>
9
#include <hpx/actions_base/basic_action.hpp>
10
#include <hpx/assert.hpp>
11
#include <hpx/async_distributed/continuation.hpp>
12
#include <hpx/async_distributed/detail/post.hpp>
13
#include <hpx/async_distributed/transfer_continuation_action.hpp>
14
#include <hpx/components_base/agas_interface.hpp>
15
#include <hpx/modules/errors.hpp>
16
#include <hpx/modules/execution.hpp>
17
#include <hpx/modules/format.hpp>
18
#include <hpx/modules/functional.hpp>
19
#include <hpx/modules/futures.hpp>
20
#include <hpx/modules/runtime_local.hpp>
21
#include <hpx/modules/serialization.hpp>
22
#include <hpx/modules/threading_base.hpp>
23
#include <hpx/performance_counters/base_performance_counter.hpp>
24
#include <hpx/performance_counters/counter_creators.hpp>
25
#include <hpx/performance_counters/counter_interface.hpp>
26
#include <hpx/performance_counters/counter_parser.hpp>
27
#include <hpx/performance_counters/counters.hpp>
28
#include <hpx/performance_counters/registry.hpp>
29

30
#include <cstddef>
31
#include <cstdint>
32
#include <functional>
33
#include <ostream>
34
#include <string>
35
#include <utility>
36
#include <vector>
37

38
#include <hpx/config/warnings_prefix.hpp>
39

40
///////////////////////////////////////////////////////////////////////////////
41
// Initialization support for the performance counter actions
42
HPX_REGISTER_ACTION_ID(hpx::performance_counters::server ::
43
                           base_performance_counter::get_counter_info_action,
44
    performance_counter_get_counter_info_action,
45
    hpx::actions::performance_counter_get_counter_info_action_id)
46
HPX_REGISTER_ACTION_ID(hpx::performance_counters::server ::
47
                           base_performance_counter::get_counter_value_action,
192✔
48
    performance_counter_get_counter_value_action,
49
    hpx::actions::performance_counter_get_counter_value_action_id)
50
HPX_REGISTER_ACTION_ID(
51
    hpx::performance_counters::server ::base_performance_counter::
192✔
52
        get_counter_values_array_action,
53
    performance_counter_get_counter_values_array_action,
54
    hpx::actions::performance_counter_get_counter_values_array_action_id)
55
HPX_REGISTER_ACTION_ID(hpx::performance_counters::server ::
192✔
56
                           base_performance_counter::set_counter_value_action,
57
    performance_counter_set_counter_value_action,
58
    hpx::actions::performance_counter_set_counter_value_action_id)
59
HPX_REGISTER_ACTION_ID(hpx::performance_counters::server ::
60
                           base_performance_counter::reset_counter_value_action,
192✔
61
    performance_counter_reset_counter_value_action,
62
    hpx::actions::performance_counter_reset_counter_value_action_id)
63
HPX_REGISTER_ACTION_ID(
64
    hpx::performance_counters::server::base_performance_counter::start_action,
192✔
65
    performance_counter_start_action,
66
    hpx::actions::performance_counter_start_action_id)
67
HPX_REGISTER_ACTION_ID(
68
    hpx::performance_counters::server::base_performance_counter::stop_action,
192✔
69
    performance_counter_stop_action,
70
    hpx::actions::performance_counter_stop_action_id)
71

72
HPX_REGISTER_BASE_LCO_WITH_VALUE_ID(hpx::performance_counters::counter_info,
192✔
73
    hpx_counter_info, hpx::actions::base_lco_with_value_hpx_counter_info_get,
74
    hpx::actions::base_lco_with_value_hpx_counter_info_set)
75
HPX_REGISTER_BASE_LCO_WITH_VALUE_ID(hpx::performance_counters::counter_value,
76
    hpx_counter_value, hpx::actions::base_lco_with_value_hpx_counter_value_get,
77
    hpx::actions::base_lco_with_value_hpx_counter_value_set)
192✔
78
HPX_REGISTER_BASE_LCO_WITH_VALUE_ID(
79
    hpx::performance_counters::counter_values_array, hpx_counter_values_array,
80
    hpx::actions::base_lco_with_value_hpx_counter_values_array_get,
192✔
81
    hpx::actions::base_lco_with_value_hpx_counter_values_array_set)
82

83
HPX_DEFINE_GET_COMPONENT_TYPE(
192✔
84
    hpx::performance_counters::server::base_performance_counter)
85

86
///////////////////////////////////////////////////////////////////////////////
87
namespace hpx::performance_counters {
88

736✔
89
    std::ostream& operator<<(std::ostream& os, counter_status rhs)
90
    {
91
        return (os << static_cast<int>(rhs));
92
    }
93

94
    /// \brief Create a full name of a counter from the contents of the given
×
95
    ///        \a counter_path_elements instance.
96
    counter_status get_counter_name(
×
97
        counter_path_elements const& path, std::string& result, error_code& ec)
98
    {
99
        if (path.objectname_.empty())
100
        {
101
            HPX_THROWS_IF(ec, hpx::error::bad_parameter, "get_counter_name",
×
102
                "empty counter object name");
103
            return counter_status::invalid_data;
104
        }
×
105

106
#if defined(HPX_GCC_VERSION) && HPX_GCC_VERSION >= 110000
×
107
#pragma GCC diagnostic push
108
#pragma GCC diagnostic ignored "-Wrestrict"
×
109
#endif
110
        result = "/";
111
        result += path.objectname_;
112

113
        if (!path.parentinstancename_.empty() || !path.instancename_.empty() ||
114
            !path.subinstancename_.empty())
×
115
        {
116
            result += "{";
117
            if (!path.parentinstancename_.empty())
118
            {
×
119
                result += path.parentinstancename_;
120
                if (-1 != path.parentinstanceindex_)
121
                {
×
122
                    result += "#";
123
                    result += std::to_string(path.parentinstanceindex_);
124
                }
×
125
            }
126
            if (!path.instancename_.empty())
127
            {
×
128
                result += "/";
129
                result += path.instancename_;
130
                if (path.instanceindex_ != -1)
131
                {
×
132
                    if (path.instancename_ == "pool")
133
                    {
×
134
                        result += "#" +
135
                            hpx::resource::get_pool_name(path.instanceindex_);
×
136
                    }
×
137
                    else
138
                    {
139
                        result += "#" + std::to_string(path.instanceindex_);
140
                    }
×
141
                }
142
            }
143
            if (!path.subinstancename_.empty())
144
            {
×
145
                result += "/";
146
                result += path.subinstancename_;
147
                if (-1 != path.subinstanceindex_)
148
                {
×
149
                    result += "#";
150
                    result += std::to_string(path.subinstanceindex_);
151
                }
×
152
            }
153
            result += "}";
154
        }
155
        if (!path.countername_.empty())
156
        {
×
157
            result += "/";
158
            result += path.countername_;
159
        }
160

161
        if (!path.parameters_.empty())
162
        {
×
163
            result += "@";
164
            result += path.parameters_;
165
        }
166
#if defined(HPX_GCC_VERSION) && HPX_GCC_VERSION >= 110000
167
#pragma GCC diagnostic pop
168
#endif
×
169

×
170
        if (&ec != &throws)
171
            ec = make_success_code();
172
        return counter_status::valid_data;
173
    }
174

175
    /// \brief Create a full name of a counter from the contents of the given
8,060✔
176
    ///        \a counter_path_elements instance.
177
    counter_status get_counter_type_name(counter_type_path_elements const& path,
178
        std::string& result, error_code& ec)
8,060✔
179
    {
180
        if (path.objectname_.empty())
×
181
        {
182
            HPX_THROWS_IF(ec, hpx::error::bad_parameter,
×
183
                "get_counter_type_name", "empty counter object name");
184
            return counter_status::invalid_data;
185
        }
186

187
#if defined(HPX_GCC_VERSION) && HPX_GCC_VERSION >= 110000
188
#pragma GCC diagnostic push
8,060✔
189
#pragma GCC diagnostic ignored "-Wrestrict"
190
#endif
191
        result = "/";
192
#if defined(HPX_GCC_VERSION) && HPX_GCC_VERSION >= 110000
193
#pragma GCC diagnostic pop
194
#endif
8,060✔
195
        result += path.objectname_;
8,060✔
196

197
        if (!path.countername_.empty())
198
        {
199
            result += "/";
200
            result += path.countername_;
201
        }
×
202

203
        if (&ec != &throws)
204
            ec = make_success_code();
205
        return counter_status::valid_data;
×
206
    }
207

×
208
    /// \brief Create a full name of a counter from the contents of the given
209
    ///        \a counter_path_elements instance.
×
210
    counter_status get_full_counter_type_name(
211
        counter_type_path_elements const& path, std::string& result,
212
        error_code& ec)
213
    {
214
        if (path.objectname_.empty())
215
        {
×
216
            HPX_THROWS_IF(ec, hpx::error::bad_parameter,
217
                "get_full_counter_type_name", "empty counter object name");
218
            return counter_status::invalid_data;
219
        }
220

221
#if defined(HPX_GCC_VERSION) && HPX_GCC_VERSION >= 110000
×
222
#pragma GCC diagnostic push
223
#pragma GCC diagnostic ignored "-Wrestrict"
224
#endif
225
        result = "/";
226
#if defined(HPX_GCC_VERSION) && HPX_GCC_VERSION >= 110000
227
#pragma GCC diagnostic pop
×
228
#endif
×
229
        result += path.objectname_;
230

231
        if (!path.countername_.empty())
232
        {
233
            result += "/";
234
            result += path.countername_;
×
235
        }
236

237
        if (!path.parameters_.empty())
×
238
        {
239
            result += "@";
×
240
            result += path.parameters_;
241
        }
×
242

243
        if (&ec != &throws)
244
            ec = make_success_code();
×
245
        return counter_status::valid_data;
246
    }
×
247

248
    /// \brief Create a name of a counter instance from the contents of the
249
    ///        given \a counter_path_elements instance.
250
    counter_status get_counter_instance_name(
251
        counter_path_elements const& path, std::string& result, error_code& ec)
252
    {
×
253
        if (path.parentinstancename_.empty())
254
        {
255
            HPX_THROWS_IF(ec, hpx::error::bad_parameter,
256
                "get_counter_instance_name", "empty counter instance name");
257
            return counter_status::invalid_data;
258
        }
×
259

260
        if (path.parentinstance_is_basename_)
261
        {
×
262
            result = path.parentinstancename_;
263
        }
264
        else
265
        {
×
266
#if defined(HPX_GCC_VERSION) && HPX_GCC_VERSION >= 110000
267
#pragma GCC diagnostic push
268
#pragma GCC diagnostic ignored "-Wrestrict"
269
#endif
×
270
            result = "/";
271
            result += path.parentinstancename_;
272
            if (path.parentinstanceindex_ == -1)
×
273
            {
274
                result += "#*";
275
            }
276
            else
×
277
            {
278
                result += "#" + std::to_string(path.parentinstanceindex_);
279
            }
280

×
281
            if (!path.instancename_.empty())
282
            {
283
                result += "/";
284
                result += path.instancename_;
×
285
                if (path.instanceindex_ == -1)
286
                {
287
                    result += "#*";
288
                }
289
                else if (path.instancename_ == "pool")
290
                {
×
291
                    result +=
292
                        "#" + hpx::resource::get_pool_name(path.instanceindex_);
293
                }
294
                else
295
                {
×
296
                    result += "#" + std::to_string(path.instanceindex_);
×
297
                }
298
            }
299

300
            if (!path.subinstancename_.empty())
301
            {
302
                result += "/";
303
                result += path.subinstancename_;
304
                if (path.subinstanceindex_ == -1)
305
                {
306
                    result += "#*";
×
307
                }
308
                else
309
                {
310
                    result += "#" + std::to_string(path.subinstanceindex_);
×
311
                }
312
            }
×
313
#if defined(HPX_GCC_VERSION) && HPX_GCC_VERSION >= 110000
314
#pragma GCC diagnostic pop
315
#endif
×
316
        }
317

318
        if (&ec != &throws)
×
319
            ec = make_success_code();
×
320
        return counter_status::valid_data;
321
    }
×
322

×
323
    // Fill the given \a counter_path_elements instance from the given full name
×
324
    // of a counter
325
    //
×
326
    //    /objectname{parentinstancename#parentindex
×
327
    //       /instancename#instanceindex}/countername
328
    //
×
329
    counter_status get_counter_path_elements(
×
330
        std::string const& name, counter_path_elements& path, error_code& ec)
331
    {
×
332
        path_elements elements;
333
        if (!parse_counter_name(name, elements))
×
334
        {
335
            HPX_THROWS_IF(ec, hpx::error::bad_parameter,
×
336
                "get_counter_path_elements", "invalid counter name format: {}",
337
                name);
338
            return counter_status::invalid_data;
339
        }
×
340

341
        path.objectname_ = elements.object_;
×
342
        path.countername_ = elements.counter_;
×
343

344
        path.parentinstancename_ = elements.instance_.parent_.name_;
345
        path.parentinstance_is_basename_ = elements.instance_.parent_.basename_;
346
        path.parentinstanceindex_ = -1;
×
347

348
        path.instancename_ = elements.instance_.child_.name_;
349
        path.instanceindex_ = -1;
350

×
351
        path.subinstancename_ = elements.instance_.subchild_.name_;
352
        path.subinstanceindex_ = -1;
×
353

×
354
        path.parameters_ = elements.parameters_;
355

×
356
        if (!path.parentinstance_is_basename_)
357
        {
×
358
            if (elements.instance_.parent_.index_ == "#*")
×
359
            {
360
                path.parentinstancename_ += "#*";
361
            }
362
            else if (!elements.instance_.parent_.index_.empty())
363
            {
×
364
                path.parentinstanceindex_ =
365
                    hpx::util::from_string<std::int64_t>(
×
366
                        elements.instance_.parent_.index_);
×
367
            }
368

×
369
            if (elements.instance_.child_.index_ == "#*")
370
            {
371
                path.instancename_ += "#*";
×
372
            }
373
            else if (!elements.instance_.child_.index_.empty())
374
            {
375
                if (elements.instance_.child_.index_[0] == '#')
376
                    elements.instance_.child_.index_.erase(0, 1);
×
377

378
                if (path.instancename_ == "pool")
379
                {
380
                    path.instanceindex_ =
×
381
                        static_cast<std::int64_t>(hpx::resource::get_pool_index(
382
                            elements.instance_.child_.index_));
×
383
                }
384
                else
385
                {
386
                    path.instanceindex_ = hpx::util::from_string<std::int64_t>(
387
                        elements.instance_.child_.index_,
×
388
                        static_cast<std::int64_t>(-2));
×
389
                    if (path.instanceindex_ == static_cast<std::int64_t>(-2))
390
                    {
391
                        HPX_THROWS_IF(ec, hpx::error::bad_parameter,
×
392
                            "get_counter_path_elements",
393
                            "invalid counter name format: {}", name);
394
                        return counter_status::invalid_data;
395
                    }
396
                }
397
            }
398

12,090✔
399
            if (elements.instance_.subchild_.index_ == "#*")
400
            {
401
                path.subinstancename_ += "#*";
402
            }
403
            else if (!elements.instance_.subchild_.index_.empty())
12,090✔
404
            {
405
                path.subinstanceindex_ = hpx::util::from_string<std::int64_t>(
×
406
                    elements.instance_.subchild_.index_);
407
            }
408
        }
×
409

410
        if (&ec != &throws)
411
            ec = make_success_code();
412

12,090✔
413
        return counter_status::valid_data;
12,090✔
414
    }
12,090✔
415

416
    // Fill the given \a counter_type_path_elements instance from the given full
12,090✔
417
    // name of a counter
16,120✔
418
    //
419
    //    /objectname{...}/countername /objectname
420
    //
12,090✔
421
    counter_status get_counter_type_path_elements(std::string const& name,
422
        counter_type_path_elements& path, error_code& ec)
423
    {
8,060✔
424
        // parse the full name
425
        path_elements elements;
426
        if (!parse_counter_name(name, elements))
427
        {
428
            HPX_THROWS_IF(ec, hpx::error::bad_parameter,
429
                "get_counter_type_path_elements",
8,060✔
430
                "invalid counter name format: {}", name);
8,060✔
431
            return counter_status::invalid_data;
432
        }
433

8,060✔
434
        // but extract only counter type elements
8,060✔
435
        path.objectname_ = elements.object_;
436
        path.countername_ = elements.counter_;
437
        path.parameters_ = elements.parameters_;
×
438

439
        if (&ec != &throws)
440
            ec = make_success_code();
441

442
        return counter_status::valid_data;
×
443
    }
×
444

445
    /// \brief Return the counter type name from a given full instance name
446
    counter_status get_counter_type_name(
×
447
        std::string const& name, std::string& type_name, error_code& ec)
×
448
    {
449
        counter_type_path_elements p;
450

×
451
        counter_status const status =
452
            get_counter_type_path_elements(name, p, ec);
453
        if (!status_is_valid(status))
×
454
            return status;
×
455

×
456
        return get_counter_type_name(p, type_name, ec);
×
457
    }
458

459
    /// \brief Return the counter type name from a given full instance name
×
460
    counter_status get_counter_name(
461
        std::string const& name, std::string& countername, error_code& ec)
462
    {
463
        counter_path_elements p;
464

×
465
        counter_status const status = get_counter_path_elements(name, p, ec);
×
466
        if (!status_is_valid(status))
467
            return status;
468

×
469
        return get_counter_name(p, countername, ec);
470
    }
471

×
472
    /// \brief Complement the counter info if parent instance name is missing
×
473
    counter_status complement_counter_info(
×
474
        counter_info& info, counter_info const& type_info, error_code& ec)
475
    {
476
        info.type_ = type_info.type_;
×
477
        if (info.helptext_.empty())
478
            info.helptext_ = type_info.helptext_;
×
479
        return complement_counter_info(info, ec);
480
    }
×
481

482
    counter_status complement_counter_info(counter_info& info, error_code& ec)
483
    {
484
        counter_path_elements p;
485

486
        counter_status const status =
×
487
            get_counter_path_elements(info.fullname_, p, ec);
488
        if (!status_is_valid(status))
489
            return status;
490

×
491
        if (p.parentinstancename_.empty())
492
        {
493
            p.parentinstancename_ = "locality";
494
            p.parentinstanceindex_ =
495
                static_cast<std::int64_t>(get_locality_id());
×
496
            if (p.instancename_.empty())
×
497
            {
498
                p.instancename_ = "total";
499
                p.instanceindex_ = -1;
500
            }
501
            if (p.subinstancename_.empty())
502
            {
503
                p.subinstanceindex_ = -1;
504
            }
505
        }
506

507
        // fill with complete counter type info
508
        std::string type_name;
509
        get_counter_type_name(p, type_name, ec);
510
        if (!status_is_valid(status))
511
            return status;
512

513
        get_counter_type(type_name, info, ec);
514
        if (!status_is_valid(status))
515
            return status;
516

×
517
        // last, set full counter name
518
        return get_counter_name(p, info.fullname_, ec);
×
519
    }
520

×
521
    ///////////////////////////////////////////////////////////////////////////
522
    /// \brief Get the name for a given counter type
523
    namespace strings {
524

4,030✔
525
        constexpr char const* const counter_type_names[] = {
526
            "text",
527
            "raw",
528
            "monotonically_increasing",
4,030✔
529
            "average_base",
530
            "average_count",
×
531
            "aggregating",
532
            "average_timer",
533
            "elapsed_time",
×
534
            "histogram",
535
            "raw_values",
4,030✔
536
        };
4,030✔
537
    }
538

539
    char const* get_counter_type_name(counter_type type)
540
    {
541
        if (type < counter_type::text || type > counter_type::raw_values)
×
542
            return "unknown";
543
        return strings::counter_type_names[static_cast<int>(type)];
544
    }
545

×
546
    ///////////////////////////////////////////////////////////////////////////
547
    counter_status add_counter_type(counter_info const& info,
×
548
        create_counter_func const& create_counter,
549
        discover_counters_func const& discover_counters, error_code& ec)
550
    {
×
551
        if (hpx::get_runtime_ptr() == nullptr)
552
        {
×
553
            HPX_THROWS_IF(ec, hpx::error::bad_parameter,
554
                "performance_counters::add_counter_type",
555
                "the runtime is not currently running");
556
            return counter_status::generic_error;
557
        }
558
        return registry::instance().add_counter_type(
×
559
            info, create_counter, discover_counters, ec);
560
    }
561

562
    ///////////////////////////////////////////////////////////////////////////
×
563
    /// \brief Call the supplied function for each registered counter type
564
    counter_status discover_counter_types(
×
565
        discover_counter_func const& discover_counter,
566
        discover_counters_mode mode, error_code& ec)
567
    {
×
568
        if (hpx::get_runtime_ptr() == nullptr)
569
        {
×
570
            HPX_THROWS_IF(ec, hpx::error::bad_parameter,
×
571
                "performance_counters::discover_counter_types",
572
                "the runtime is not currently running");
573
            return counter_status::generic_error;
×
574
        }
575
        return registry::instance().discover_counter_types(
576
            discover_counter, mode, ec);
577
    }
×
578

579
    ///////////////////////////////////////////////////////////////////////////
×
580
    /// \brief Call the supplied function for the given registered counter type.
581
    counter_status discover_counter_type(counter_info const& info,
582
        discover_counter_func const& discover_counter,
×
583
        discover_counters_mode mode, error_code& ec)
584
    {
×
585
        if (hpx::get_runtime_ptr() == nullptr)
586
        {
587
            HPX_THROWS_IF(ec, hpx::error::bad_parameter,
588
                "performance_counters::discover_counter_types",
589
                "the runtime is not currently running");
590
            return counter_status::generic_error;
×
591
        }
592
        return registry::instance().discover_counter_type(
593
            info, discover_counter, mode, ec);
×
594
    }
×
595

596
    counter_status discover_counter_type(std::string const& name,
597
        discover_counter_func const& discover_counter,
598
        discover_counters_mode mode, error_code& ec)
×
599
    {
600
        if (hpx::get_runtime_ptr() == nullptr)
601
        {
602
            HPX_THROWS_IF(ec, hpx::error::bad_parameter,
603
                "performance_counters::discover_counter_types",
604
                "the runtime is not currently running");
×
605
            return counter_status::generic_error;
606
        }
607
        return registry::instance().discover_counter_type(
×
608
            name, discover_counter, mode, ec);
609
    }
610

611
    ///////////////////////////////////////////////////////////////////////////
612
    namespace detail {
613
        bool discover_counters(std::vector<counter_info>& counters,
614
            counter_info const& info, error_code& /* ec */)
×
615
        {
616
            counters.push_back(info);
617
            return true;
×
618
        }
619
    }    // namespace detail
620

621
    counter_status discover_counter_types(std::vector<counter_info>& counters,
622
        discover_counters_mode mode, error_code& ec)
623
    {
624
        discover_counter_func func(
×
625
            hpx::bind_front(&detail::discover_counters, std::ref(counters)));
626

627
        return discover_counter_types(HPX_MOVE(func), mode, ec);
628
    }
8,060✔
629

630
    counter_status discover_counter_type(std::string const& name,
631
        std::vector<counter_info>& counters, discover_counters_mode mode,
8,060✔
632
        error_code& ec)
633
    {
634
        discover_counter_func func(
635
            hpx::bind_front(&detail::discover_counters, std::ref(counters)));
4,030✔
636

637
        return discover_counter_type(name, HPX_MOVE(func), mode, ec);
638
    }
639

640
    counter_status discover_counter_type(counter_info const& info,
×
641
        std::vector<counter_info>& counters, discover_counters_mode mode,
642
        error_code& ec)
643
    {
×
644
        discover_counter_func func(
645
            hpx::bind_front(&detail::discover_counters, std::ref(counters)));
×
646

647
        return discover_counter_type(info, HPX_MOVE(func), mode, ec);
648
    }
×
649

650
    ///////////////////////////////////////////////////////////////////////////
×
651
    counter_status remove_counter_type(counter_info const& info, error_code& ec)
652
    {
653
        // the runtime could be gone already
654
        if (hpx::get_runtime_ptr() == nullptr)
×
655
        {
656
            return counter_status::generic_error;
657
        }
658
        return registry::instance().remove_counter_type(info, ec);
×
659
    }
×
660

661
    /// \brief Retrieve the counter type for the given counter name from the
×
662
    ///        (local) registry
663
    counter_status get_counter_type(
664
        std::string const& name, counter_info& info, error_code& ec)
×
665
    {
666
        if (hpx::get_runtime_ptr() == nullptr)
667
        {
668
            HPX_THROWS_IF(ec, hpx::error::bad_parameter,
×
669
                "performance_counters::get_counter_type",
×
670
                "the runtime is not currently running");
×
671
            return counter_status::generic_error;
672
        }
673
        return registry::instance().get_counter_type(name, info, ec);
×
674
    }
675

676
    namespace detail {
677
        naming::gid_type create_raw_counter_value(counter_info const& info,
×
678
            std::int64_t* countervalue, error_code& ec)
×
679
        {
×
680
            HPX_ASSERT(hpx::get_runtime_ptr() != nullptr);
681
            naming::gid_type gid;
682
            registry::instance().create_raw_counter_value(
×
683
                info, countervalue, gid, ec);
684
            return gid;
685
        }
686

×
687
        naming::gid_type create_raw_counter(counter_info const& info,
×
688
            hpx::function<std::int64_t()> const& f, error_code& ec)
×
689
        {
690
            HPX_ASSERT(hpx::get_runtime_ptr() != nullptr);
691
            naming::gid_type gid;
×
692
            registry::instance().create_raw_counter(info, f, gid, ec);
693
            return gid;
694
        }
695

696
        naming::gid_type create_raw_counter(counter_info const& info,
×
697
            hpx::function<std::int64_t(bool)> const& f, error_code& ec)
×
698
        {
×
699
            HPX_ASSERT(hpx::get_runtime_ptr() != nullptr);
700
            naming::gid_type gid;
701
            registry::instance().create_raw_counter(info, f, gid, ec);
702
            return gid;
703
        }
×
704

705
        naming::gid_type create_raw_counter(counter_info const& info,
706
            hpx::function<std::vector<std::int64_t>()> const& f, error_code& ec)
707
        {
×
708
            HPX_ASSERT(hpx::get_runtime_ptr() != nullptr);
×
709
            naming::gid_type gid;
×
710
            registry::instance().create_raw_counter(info, f, gid, ec);
711
            return gid;
712
        }
713

714
        naming::gid_type create_raw_counter(counter_info const& info,
715
            hpx::function<std::vector<std::int64_t>(bool)> const& f,
×
716
            error_code& ec)
717
        {
718
            HPX_ASSERT(hpx::get_runtime_ptr() != nullptr);
719
            naming::gid_type gid;
720
            registry::instance().create_raw_counter(info, f, gid, ec);
×
721
            return gid;
×
722
        }
723

×
724
        // \brief Create a new performance counter instance based on given
725
        //        counter info
726
        naming::gid_type create_counter(
727
            counter_info const& info, error_code& ec)
728
        {
729
            HPX_ASSERT(hpx::get_runtime_ptr() != nullptr);
×
730
            naming::gid_type gid;
731
            registry::instance().create_counter(info, gid, ec);
732
            return gid;
733
        }
×
734

×
735
        // \brief Create a new aggregating performance counter instance based
736
        //        on given base counter name and given base time interval
×
737
        //        (milliseconds).
738
        naming::gid_type create_statistics_counter(counter_info const& info,
739
            std::string const& base_counter_name,
740
            std::vector<std::size_t> const& parameters, error_code& ec)
741
        {
742
            HPX_ASSERT(hpx::get_runtime_ptr() != nullptr);
×
743
            naming::gid_type gid;
744
            registry::instance().create_statistics_counter(
745
                info, base_counter_name, parameters, gid, ec);
746
            return gid;
747
        }
×
748

×
749
        // \brief Create a new aggregating performance counter instance based
750
        //        on given base counter name and given base time interval
×
751
        //        (milliseconds).
752
        naming::gid_type create_arithmetics_counter(counter_info const& info,
753
            std::vector<std::string> const& base_counter_names, error_code& ec)
754
        {
×
755
            HPX_ASSERT(hpx::get_runtime_ptr() != nullptr);
756
            naming::gid_type gid;
757
            registry::instance().create_arithmetics_counter(
758
                info, base_counter_names, gid, ec);
×
759
            return gid;
760
        }
761

×
762
        // \brief Create a new aggregating extended performance counter instance
763
        //        based on given base counter name and given base time interval
764
        //        (milliseconds).
765
        naming::gid_type create_arithmetics_counter_extended(
×
766
            counter_info const& info,
767
            std::vector<std::string> const& base_counter_names, error_code& ec)
768
        {
769
            HPX_ASSERT(hpx::get_runtime_ptr() != nullptr);
×
770
            naming::gid_type gid;
771
            registry::instance().create_arithmetics_counter_extended(
772
                info, base_counter_names, gid, ec);
773
            return gid;
774
        }
775

776
        ///////////////////////////////////////////////////////////////////////
×
777
        counter_status add_counter(
×
778
            hpx::id_type const& id, counter_info const& info, error_code& ec)
×
779
        {
780
            HPX_ASSERT(hpx::get_runtime_ptr() != nullptr);
×
781
            return registry::instance().add_counter(id, info, ec);
782
        }
783

784
        counter_status remove_counter(
785
            counter_info const& info, hpx::id_type const& id, error_code& ec)
786
        {
787
            HPX_ASSERT(hpx::get_runtime_ptr() != nullptr);
×
788
            return registry::instance().remove_counter(info, id, ec);
×
789
        }
790

791
        namespace {
×
792

×
793
            std::string list_available_counternames()
×
794
            {
795
                std::string result;
×
796
                hpx::error_code ec;
797
                discover_counter_types(
798
                    [&result](counter_info const& info, error_code&) {
799
                        result += "  " + info.fullname_ + '\n';
800
                        return true;
801
                    },
802
                    discover_counters_mode::minimal, ec);
803
                return result;
×
804
            }
805
        }    // namespace
×
806

807
        // create an arbitrary counter on this locality
808
        naming::gid_type create_counter_local(counter_info const& info)
809
        {
810
            // find create function for given counter
811
            error_code ec;
812

×
813
            HPX_ASSERT(hpx::get_runtime_ptr() != nullptr);
814

815
            create_counter_func f;
×
816
            registry::instance().get_counter_create_function(info, f, ec);
817
            if (ec)
818
            {
×
819
                HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
820
                    "create_counter_local",
821
                    "no create function for performance counter found: {} ({})",
×
822
                    remove_counter_prefix(info.fullname_), ec.get_message());
823
            }
824

×
825
            counter_path_elements paths;
826
            get_counter_path_elements(info.fullname_, paths, ec);
827
            if (ec)
828
                return hpx::naming::invalid_gid;
829

830
            if (paths.parentinstancename_ == "locality" &&
831
                paths.parentinstanceindex_ !=
832
                    static_cast<std::int64_t>(hpx::get_locality_id()))
833
            {
834
                HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
835
                    "create_counter_local",
836
                    "attempt to create counter on wrong locality ({})",
837
                    ec.get_message());
×
838
            }
839

840
            // attempt to create the new counter instance
841
            naming::gid_type gid = f(info, ec);
×
842
            if (ec)
843
            {
844
                HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
845
                    "create_counter_local",
846
                    "couldn't create performance counter: {} ({})\n"
847
                    "available counters:\n{}",
×
848
                    remove_counter_prefix(info.fullname_), ec.get_message(),
849
                    list_available_counternames());
850
            }
×
851

852
            return gid;
853
        }
854

855
        ///////////////////////////////////////////////////////////////////////
×
856
        inline bool is_thread_kind(std::string const& pattern)
857
        {
858
            std::string::size_type const p = pattern.find("-thread#*");
859
            return p != std::string::npos && p == pattern.size() - 9;
860
        }
×
861

862
        inline std::string get_thread_kind(std::string const& pattern)
×
863
        {
864
            HPX_ASSERT(is_thread_kind(pattern));
×
865
            return pattern.substr(0, pattern.find_last_of('-'));
866
        }
867

868
        ///////////////////////////////////////////////////////////////////////
869
        inline bool is_pool_kind(std::string const& pattern)
×
870
        {
×
871
            std::string::size_type const p = pattern.find("pool#*");
872
            return p != std::string::npos;
×
873
        }
874

×
875
        inline std::string get_pool_kind(std::string const& pattern)
×
876
        {
877
            HPX_ASSERT(is_pool_kind(pattern));
878
            return pattern.substr(0, pattern.find_last_of('#'));
879
        }
880

881
        ///////////////////////////////////////////////////////////////////////
×
882
        inline bool is_node_kind(std::string const& pattern)
883
        {
884
            std::string::size_type const p = pattern.find("-node#*");
885
            return p != std::string::npos && p == pattern.size() - 7;
×
886
        }
887

888
        inline std::string get_node_kind(std::string const& pattern)
889
        {
×
890
            HPX_ASSERT(is_node_kind(pattern));
×
891
            return pattern.substr(0, pattern.find_last_of('-'));
892
        }
×
893

894
        ///////////////////////////////////////////////////////////////////////
×
895
        /// Expand all wild-cards in a counter base name (for aggregate counters)
896
        bool expand_basecounter(counter_info const& info,
897
            counter_path_elements& p, discover_counter_func const& f,
×
898
            error_code& ec)
×
899
        {
900
            // discover all base names
×
901
            std::vector<counter_info> counter_infos;
902
            if (counter_status const status =
903
                    discover_counter_type(p.parentinstancename_, counter_infos,
×
904
                        discover_counters_mode::full, ec);
×
905
                !status_is_valid(status) || ec)
906
            {
×
907
                return false;
908
            }
909

910
            counter_info i = info;
911
            for (counter_info const& basei : counter_infos)
912
            {
913
                p.parentinstancename_ = basei.fullname_;
×
914
                if (counter_status const s =
×
915
                        get_counter_name(p, i.fullname_, ec);
916
                    !status_is_valid(s) || !f(i, ec) || ec)
×
917
                {
918
                    return false;
919
                }
920
            }
921
            return true;
922
        }
923

×
924
        ///////////////////////////////////////////////////////////////////////
925
        // expand main counter name
926
        bool expand_counter_info_pools(bool expand_threads, counter_info& i,
927
            counter_path_elements& p, discover_counter_func const& f,
928
            error_code& ec)
×
929
        {
×
930
            std::size_t const num_pools = hpx::resource::get_num_thread_pools();
931
            for (std::size_t l = 0; l != num_pools; ++l)
×
932
            {
933
                p.instanceindex_ = static_cast<std::int64_t>(l);
934

×
935
                if (expand_threads)
×
936
                {
937
                    std::size_t const num_threads =
×
938
                        hpx::resource::get_num_threads(p.instanceindex_);
939
                    for (std::size_t t = 0; t != num_threads; ++t)
940
                    {
941
                        p.subinstanceindex_ = static_cast<std::int64_t>(t);
942

943
                        if (counter_status const status =
×
944
                                get_counter_name(p, i.fullname_, ec);
945
                            !status_is_valid(status) || !f(i, ec) || ec)
946
                        {
947
                            return false;
×
948
                        }
×
949
                    }
950
                }
×
951
                else
952
                {
×
953
                    if (counter_status const status =
×
954
                            get_counter_name(p, i.fullname_, ec);
955
                        !status_is_valid(status) || !f(i, ec) || ec)
×
956
                    {
957
                        return false;
958
                    }
959
                }
960
            }
961
            return true;
×
962
        }
963

964
        bool expand_counter_info_pool_threads(counter_info& i,
965
            counter_path_elements& p, discover_counter_func const& f,
966
            error_code& ec)
×
967
        {
×
968
            std::size_t const num_threads =
969
                hpx::resource::get_num_threads(p.instanceindex_);
×
970
            for (std::size_t t = 0; t != num_threads; ++t)
971
            {
×
972
                p.subinstanceindex_ = static_cast<std::int64_t>(t);
×
973

974
                if (counter_status const status =
×
975
                        get_counter_name(p, i.fullname_, ec);
976
                    !status_is_valid(status) || !f(i, ec) || ec)
977
                {
978
                    return false;
979
                }
980
            }
×
981
            return true;
982
        }
983

984
        bool expand_counter_info_threads(counter_info& i,
985
            counter_path_elements& p, discover_counter_func const& f,
986
            error_code& ec)
987
        {
988
            std::size_t const num_threads = get_os_thread_count();
×
989
            for (std::size_t l = 0; l != num_threads; ++l)
990
            {
×
991
                p.instanceindex_ = static_cast<std::int64_t>(l);
992
                if (counter_status const status =
993
                        get_counter_name(p, i.fullname_, ec);
×
994
                    !status_is_valid(status) || !f(i, ec) || ec)
995
                {
996
                    return false;
×
997
                }
998
            }
999
            return true;
1000
        }
×
1001

1002
        bool expand_counter_info_nodes(counter_info& i,
×
1003
            counter_path_elements& p, discover_counter_func const& f,
1004
            error_code& ec)
1005
        {
×
1006
            std::size_t const num_nodes =
1007
                hpx::threads::get_topology().get_number_of_numa_nodes();
×
1008
            for (std::size_t l = 0; l != num_nodes; ++l)
1009
            {
1010
                p.instanceindex_ = static_cast<std::int64_t>(l);
1011
                if (counter_status const status =
1012
                        get_counter_name(p, i.fullname_, ec);
×
1013
                    !status_is_valid(status) || !f(i, ec) || ec)
×
1014
                {
1015
                    return false;
×
1016
                }
×
1017
            }
1018
            return true;
×
1019
        }
1020

1021
        bool expand_counter_info_localities(counter_info& i,
1022
            counter_path_elements& p, discover_counter_func const& f,
1023
            error_code& ec)
1024
        {
×
1025
            bool expand_pools = false;
1026
            bool expand_threads = false;
×
1027
            bool expand_nodes = false;
1028

1029
            if (is_pool_kind(p.instancename_))
×
1030
            {
1031
                p.instancename_ = get_pool_kind(p.instancename_);
×
1032
                expand_pools = true;
1033

1034
                if (is_thread_kind(p.subinstancename_))
1035
                {
1036
                    p.subinstancename_ =
1037
                        get_thread_kind(p.subinstancename_) + "-thread";
×
1038
                    expand_threads = true;
×
1039
                }
1040
            }
×
1041
            else if (is_thread_kind(p.instancename_))
1042
            {
1043
                p.instancename_ = get_thread_kind(p.instancename_) + "-thread";
1044
                expand_threads = true;
1045
            }
1046
            else if (is_node_kind(p.instancename_))
1047
            {
1048
                p.instancename_ = get_node_kind(p.instancename_) + "-node";
×
1049
                expand_nodes = true;
1050
            }
1051

1052
            std::uint32_t const last_locality =
1053
                get_num_localities(hpx::launch::sync);
1054
            for (std::uint32_t l = 0; l != last_locality; ++l)
×
1055
            {
1056
                p.parentinstanceindex_ = static_cast<std::int32_t>(l);
1057
                if (expand_pools)
1058
                {
1059
                    if (!detail::expand_counter_info_pools(
1060
                            expand_threads, i, p, f, ec))
1061
                    {
×
1062
                        return false;
1063
                    }
×
1064
                }
1065
                else if (expand_threads)
×
1066
                {
×
1067
                    if (!detail::expand_counter_info_threads(i, p, f, ec))
1068
                        return false;
1069
                }
×
1070
                else if (expand_nodes)
1071
                {
1072
                    if (!detail::expand_counter_info_nodes(i, p, f, ec))
×
1073
                        return false;
1074
                }
×
1075
                else
×
1076
                {
×
1077
                    if (counter_status const status =
1078
                            get_counter_name(p, i.fullname_, ec);
1079
                        !status_is_valid(status) || !f(i, ec) || ec)
×
1080
                    {
1081
                        return false;
×
1082
                    }
1083
                }
×
1084
            }
×
1085
            return true;
1086
        }
1087

×
1088
        ///////////////////////////////////////////////////////////////////////
×
1089
        bool expand_counter_info(counter_info const& info,
×
1090
            counter_path_elements& p, discover_counter_func const& f,
×
1091
            error_code& ec)
1092
        {
×
1093
            // A '*' wild-card as the instance name is equivalent to no instance
1094
            // name at all.
1095
            if (p.parentinstancename_ == "*")
×
1096
            {
1097
                HPX_ASSERT(p.parentinstanceindex_ == -1);
×
1098
                p.parentinstancename_.clear();
×
1099
            }
×
1100

1101
            // first expand "locality*"
1102
            if (p.parentinstancename_ == "locality#*")
×
1103
            {
1104
                counter_info i = info;
×
1105
                p.parentinstancename_ = "locality";
1106
                return detail::expand_counter_info_localities(i, p, f, ec);
×
1107
            }
×
1108

×
1109
            // now expand "pool#*"
1110
            if (detail::is_pool_kind(p.instancename_))
1111
            {
×
1112
                bool expand_threads =
1113
                    detail::is_thread_kind(p.subinstancename_);
×
1114

1115
                counter_info i = info;
1116
                p.instancename_ = detail::get_pool_kind(p.instancename_);
1117
                if (expand_threads)
×
1118
                {
1119
                    p.subinstancename_ =
1120
                        detail::get_thread_kind(p.subinstancename_) + "-thread";
1121
                }
1122
                return detail::expand_counter_info_pools(
1123
                    expand_threads, i, p, f, ec);
1124
            }
×
1125
            else if (p.instancename_ == "pool" && p.subinstancename_ == "*")
1126
            {
1127
                p.subinstancename_ = "worker-thread";
1128
                p.subinstanceindex_ = -1;
×
1129
                counter_info i = info;
×
1130
                return detail::expand_counter_info_pool_threads(i, p, f, ec);
1131
            }
1132

1133
            if (detail::is_thread_kind(p.instancename_))
1134
            {
1135
                // now expand "<...>-thread#*"
×
1136
                counter_info i = info;
×
1137
                p.instancename_ =
1138
                    detail::get_thread_kind(p.instancename_) + "-thread";
1139
                return detail::expand_counter_info_threads(i, p, f, ec);
×
1140
            }
1141

1142
            // now expand "<...>-node#*"
1143
            if (detail::is_node_kind(p.instancename_))
×
1144
            {
×
1145
                counter_info i = info;
×
1146
                p.instancename_ =
1147
                    detail::get_node_kind(p.instancename_) + "-node";
1148
                return detail::expand_counter_info_nodes(i, p, f, ec);
1149
            }
×
1150

1151
            // handle wild-cards in aggregate counters
1152
            if (p.parentinstance_is_basename_)
1153
            {
×
1154
                return detail::expand_basecounter(info, p, f, ec);
×
1155
            }
×
1156

×
1157
            // everything else is handled directly
1158
            return f(info, ec);
×
1159
        }
1160
    }    // namespace detail
1161

1162
    ///////////////////////////////////////////////////////////////////////////
1163
    /// \brief call the supplied function will all expanded versions of the
×
1164
    /// supplied counter info.
×
1165
    bool expand_counter_info(counter_info const& info,
1166
        discover_counter_func const& f, error_code& ec)
1167
    {
1168
        counter_path_elements p;
1169
        if (counter_status const status =
1170
                get_counter_path_elements(info.fullname_, p, ec);
×
1171
            !status_is_valid(status))
×
1172
        {
×
1173
            return false;
1174
        }
1175

1176
        return detail::expand_counter_info(info, p, f, ec);
×
1177
    }
1178

×
1179
    ///////////////////////////////////////////////////////////////////////////
×
1180
    static hpx::id_type register_with_agas(
×
1181
        std::string const& fullname, hpx::future<hpx::id_type> f)
1182
    {
1183
        // register the canonical name with AGAS
×
1184
        hpx::id_type id = f.get();
×
1185
        agas::register_name(launch::sync, fullname, id);
1186
        return id;
×
1187
    }
×
1188

1189
    ///////////////////////////////////////////////////////////////////////////
×
1190
    hpx::future<hpx::id_type> get_counter_async(
1191
        counter_info const& info, error_code& ec)
×
1192
    {
1193
        // complement counter info data
1194
        counter_info complemented_info = info;
1195
        complement_counter_info(complemented_info, ec);
1196
        if (ec)
×
1197
            return {};
×
1198

1199
        ensure_counter_prefix(complemented_info.fullname_);
×
1200
        // pre-pend prefix, if necessary
×
1201

1202
        // ask AGAS for the id of the given counter
1203
        hpx::id_type id =
1204
            agas::resolve_name(launch::sync, complemented_info.fullname_, ec);
1205
        if (id == hpx::invalid_id)
1206
        {
×
1207
            try
×
1208
            {
1209
                // figure out target locality
1210
                counter_path_elements p;
1211
                get_counter_path_elements(complemented_info.fullname_, p, ec);
1212
                if (ec)
1213
                    return {};
1214

×
1215
                // Take target locality from base counter if this is an
×
1216
                // aggregating counter (the instance name is a base counter).
×
1217
                if (p.parentinstance_is_basename_)
×
1218
                {
1219
                    get_counter_path_elements(p.parentinstancename_, p, ec);
×
1220
                    if (ec)
×
1221
                        return {};
×
1222
                }
×
1223

×
1224
                if (p.parentinstancename_ == "locality" &&
×
1225
                    (p.parentinstanceindex_ < 0 ||
×
1226
                        p.parentinstanceindex_ >=
×
1227
                            static_cast<std::int32_t>(
1228
                                get_num_localities(hpx::launch::sync))))
×
1229
                {
×
1230
                    HPX_THROWS_IF(ec, hpx::error::bad_parameter, "get_counter",
1231
                        "attempt to create counter on non-existing locality");
1232
                    return {};
×
1233
                }
1234

×
1235
                // use the runtime_support component of the target locality to
1236
                // create the new performance counter
1237
                hpx::future<hpx::id_type> f;
×
1238
                if (p.parentinstanceindex_ >= 0)
1239
                {
×
1240
                    f = create_performance_counter_async(
×
1241
                        naming::get_id_from_locality_id(
×
1242
                            static_cast<std::uint32_t>(p.parentinstanceindex_)),
1243
                        complemented_info);
1244
                }
×
1245
                else
1246
                {
1247
                    f = create_performance_counter_async(
1248
                        naming::get_id_from_locality_id(
×
1249
                            agas::get_locality_id()),
1250
                        complemented_info);
×
1251
                }
1252

×
1253
                // attach the function which registers the id_type with AGAS
1254
                return f.then(hpx::launch::sync,
1255
                    hpx::bind_front(
1256
                        &register_with_agas, complemented_info.fullname_));
×
1257
            }
1258
            catch (hpx::exception const& e)
×
1259
            {
1260
                if (&ec == &throws)
×
1261
                    throw;
1262
                ec = make_error_code(e.get_error(), e.what());
1263
                LPCS_(warning).format("failed to create counter {} ({})",
1264
                    remove_counter_prefix(complemented_info.fullname_),
×
1265
                    e.what());
1266
                return {};
×
1267
            }
1268
        }
×
1269
        if (ec)
1270
            return {};
1271

1272
        return hpx::make_ready_future(id);
×
1273
    }
1274

×
1275
    hpx::future<hpx::id_type> get_counter_async(
1276
        std::string name, error_code& ec)
1277
    {
×
1278
        ensure_counter_prefix(name);    // prepend prefix, if necessary
1279

1280
        counter_info const info(name);    // set full counter name
1281
        return get_counter_async(info, ec);
×
1282
    }
1283

×
1284
    ///////////////////////////////////////////////////////////////////////////
1285
    void counter_value::serialize(
×
1286
        serialization::output_archive& ar, unsigned int const) const
1287
    {
1288
        // clang-format off
1289
        ar & status_ & time_ & count_ & value_ & scaling_ & scale_inverse_;
×
1290
        // clang-format on
1291
    }
×
1292

1293
    void counter_value::serialize(
1294
        serialization::input_archive& ar, unsigned int const)
×
1295
    {
1296
        // clang-format off
1297
        ar & status_ & time_ & count_ & value_ & scaling_ & scale_inverse_;
1298
        // clang-format on
1299
    }
1300

1301
    void counter_values_array::serialize(
1302
        serialization::output_archive& ar, unsigned int const) const
1303
    {
×
1304
        // clang-format off
×
1305
        ar & status_ & time_ & count_ & values_ & scaling_ & scale_inverse_;
×
1306
        // clang-format on
1307
    }
×
1308

1309
    void counter_values_array::serialize(
×
1310
        serialization::input_archive& ar, unsigned int const)
1311
    {
1312
        // clang-format off
1313
        ar & status_ & time_ & count_ & values_ & scaling_ & scale_inverse_;
1314
        // clang-format on
1315
    }
1316

1317
    ///////////////////////////////////////////////////////////////////////////
1318
    void counter_type_path_elements::serialize(
×
1319
        serialization::output_archive& ar, unsigned int const) const
×
1320
    {
×
1321
        // clang-format off
1322
        ar & objectname_ & countername_ & parameters_;
×
1323
        // clang-format on
1324
    }
1325

×
1326
    void counter_type_path_elements::serialize(
1327
        serialization::input_archive& ar, unsigned int const)
1328
    {
1329
        // clang-format off
×
1330
        ar & objectname_ & countername_ & parameters_;
×
1331
        // clang-format on
1332
    }
×
1333

1334
    ///////////////////////////////////////////////////////////////////////////
×
1335
    void counter_path_elements::serialize(
1336
        serialization::output_archive& ar, unsigned int const)
1337
    {
1338
        using base_type = counter_type_path_elements;
×
1339
        hpx::serialization::base_object_type<counter_path_elements,
×
1340
            base_type> const base =
1341
            hpx::serialization::base_object<base_type>(*this);
×
1342

1343
        // clang-format off
1344
        ar & base & parentinstancename_ & instancename_ & subinstancename_ &
1345
            parentinstanceindex_ & instanceindex_ & subinstanceindex_ &
1346
            parentinstance_is_basename_;
1347
        // clang-format on
1348
    }
1349

1350
    void counter_path_elements::serialize(
1351
        serialization::input_archive& ar, unsigned int const)
1352
    {
1353
        using base_type = counter_type_path_elements;
1354
        hpx::serialization::base_object_type<counter_path_elements,
1355
            base_type> const base =
1356
            hpx::serialization::base_object<base_type>(*this);
1357

1358
        // clang-format off
1359
        ar & base & parentinstancename_ & instancename_ & subinstancename_ &
1360
            parentinstanceindex_ & instanceindex_ & subinstanceindex_ &
1361
            parentinstance_is_basename_;
1362
        // clang-format on
1363
    }
1364

1365
    ///////////////////////////////////////////////////////////////////////////
1366
    void counter_info::serialize(
1367
        serialization::output_archive& ar, unsigned int const) const
1368
    {
1369
        // clang-format off
1370
        ar & type_ & version_ & status_ & fullname_ & helptext_ &
1371
            unit_of_measure_;
1372
        // clang-format on
1373
    }
1374

1375
    void counter_info::serialize(
1376
        serialization::input_archive& ar, unsigned int const)
1377
    {
1378
        // clang-format off
1379
        ar & type_ & version_ & status_ & fullname_ & helptext_ &
1380
            unit_of_measure_;
1381
        // clang-format on
1382
    }
1383
}    // 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