• 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

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

7
#include <hpx/config.hpp>
8
#include <hpx/async_base/launch_policy.hpp>
9
#include <hpx/async_distributed/continuation.hpp>
10
#include <hpx/components_base/agas_interface.hpp>
11
#include <hpx/functional/bind_front.hpp>
12
#include <hpx/performance_counters/counter_creators.hpp>
13
#include <hpx/performance_counters/counters.hpp>
14
#include <hpx/performance_counters/performance_counter.hpp>
15
#include <hpx/performance_counters/server/statistics_counter.hpp>
16
#include <hpx/runtime_components/derived_component_factory.hpp>
17
#include <hpx/runtime_local/runtime_local_fwd.hpp>
18
#include <hpx/thread_support/unlock_guard.hpp>
19
#include <hpx/timing/high_resolution_clock.hpp>
20

21
#include <boost/accumulators/accumulators.hpp>
22
#include <boost/accumulators/statistics/max.hpp>
23
#include <boost/accumulators/statistics/mean.hpp>
24
#include <boost/accumulators/statistics/min.hpp>
25
#include <boost/accumulators/statistics/rolling_mean.hpp>
26
#include <boost/accumulators/statistics/rolling_variance.hpp>
27
#include <boost/accumulators/statistics/stats.hpp>
28
#include <boost/accumulators/statistics/variance.hpp>
29

30
#include <hpx/statistics/rolling_max.hpp>
31
#include <hpx/statistics/rolling_min.hpp>
32

33
#if defined(HPX_MSVC)
34
#pragma warning(push)
35
#pragma warning(disable : 4244)
36
#endif
37
#include <boost/accumulators/statistics/median.hpp>
38
#if defined(HPX_MSVC)
39
#pragma warning(pop)
40
#endif
41

42
#include <boost/spirit/home/x3/char.hpp>
43
#include <boost/spirit/home/x3/core.hpp>
44
#include <boost/spirit/home/x3/numeric.hpp>
45
#include <boost/spirit/home/x3/operator.hpp>
46

47
#include <boost/version.hpp>
48

49
#include <cstddef>
50
#include <cstdint>
51
#include <mutex>
52
#include <string>
53
#include <vector>
54

55
///////////////////////////////////////////////////////////////////////////////
56
namespace hpx { namespace performance_counters { namespace server {
57
    ///////////////////////////////////////////////////////////////////////////
58
    namespace detail {
×
59
        template <typename Statistic>
60
        struct counter_type_from_statistic;
4✔
61

62
        template <>
63
        struct counter_type_from_statistic<boost::accumulators::tag::mean>
×
64
          : counter_type_from_statistic_base
65
        {
66
            typedef boost::accumulators::tag::mean aggregating_tag;
67
            typedef boost::accumulators::accumulator_set<double,
68
                boost::accumulators::stats<aggregating_tag>>
69
                accumulator_type;
70

71
            counter_type_from_statistic(std::size_t /*parameter2*/) {}
1✔
72

73
            double get_value() override
2✔
74
            {
75
                return boost::accumulators::mean(accum_);
2✔
76
            }
77

78
            void add_value(double value) override
10✔
79
            {
80
                accum_(value);
10✔
81
            }
10✔
82

83
            bool need_reset() const override
2✔
84
            {
85
                return false;
2✔
86
            }
87

88
        private:
89
            accumulator_type accum_;
90
        };
91

92
        template <>
93
        struct counter_type_from_statistic<boost::accumulators::tag::variance>
×
94
          : counter_type_from_statistic_base
95
        {
96
            typedef boost::accumulators::tag::variance aggregating_tag;
97
            typedef boost::accumulators::accumulator_set<double,
98
                boost::accumulators::stats<aggregating_tag>>
99
                accumulator_type;
100

101
            counter_type_from_statistic(std::size_t /*parameter2*/) {}
×
102

103
            double get_value() override
×
104
            {
105
                return sqrt(boost::accumulators::variance(accum_));
×
106
            }
107

108
            void add_value(double value) override
×
109
            {
110
                accum_(value);
×
111
            }
×
112

113
            bool need_reset() const override
×
114
            {
115
                return false;
×
116
            }
117

118
        private:
119
            accumulator_type accum_;
120
        };
121

122
        template <>
123
        struct counter_type_from_statistic<boost::accumulators::tag::median>
×
124
          : counter_type_from_statistic_base
125
        {
126
            typedef boost::accumulators::tag::median aggregating_tag;
127
            typedef boost::accumulators::with_p_square_quantile
128
                aggregating_type_tag;
129
            typedef boost::accumulators::accumulator_set<double,
130
                boost::accumulators::stats<aggregating_tag(
131
                    aggregating_type_tag)>>
132
                accumulator_type;
133

134
            counter_type_from_statistic(std::size_t /*parameter2*/) {}
×
135

136
            double get_value() override
×
137
            {
138
                return boost::accumulators::median(accum_);
×
139
            }
140

141
            void add_value(double value) override
×
142
            {
143
                accum_(value);
×
144
            }
×
145

146
            bool need_reset() const override
×
147
            {
148
                return false;
×
149
            }
150

151
        private:
152
            accumulator_type accum_;
153
        };
154

155
        template <>
156
        struct counter_type_from_statistic<
×
157
            boost::accumulators::tag::rolling_mean>
158
          : counter_type_from_statistic_base
159
        {
160
            typedef boost::accumulators::tag::rolling_mean aggregating_tag;
161
            typedef boost::accumulators::accumulator_set<double,
162
                boost::accumulators::stats<aggregating_tag>>
163
                accumulator_type;
164

165
            counter_type_from_statistic(std::size_t parameter2)
×
166
              : accum_(boost::accumulators::tag::rolling_window::window_size =
×
167
                           parameter2)
168
            {
×
169
                if (parameter2 == 0)
×
170
                {
171
                    HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
172
                        "counter_type_from_statistic<Statistic>",
173
                        "base rolling window size is specified to be zero");
174
                }
175
            }
×
176

177
            double get_value() override
×
178
            {
179
                return boost::accumulators::rolling_mean(accum_);
×
180
            }
181

182
            void add_value(double value) override
×
183
            {
184
                accum_(value);
×
185
            }
×
186

187
            bool need_reset() const override
×
188
            {
189
                return false;
×
190
            }
191

192
        private:
193
            accumulator_type accum_;
194
        };
195

196
        template <>
197
        struct counter_type_from_statistic<
×
198
            boost::accumulators::tag::rolling_variance>
199
          : counter_type_from_statistic_base
200
        {
201
            typedef boost::accumulators::tag::rolling_variance aggregating_tag;
202
            typedef boost::accumulators::accumulator_set<double,
203
                boost::accumulators::stats<aggregating_tag>>
204
                accumulator_type;
205

206
            counter_type_from_statistic(std::size_t parameter2)
×
207
              : accum_(boost::accumulators::tag::rolling_window::window_size =
×
208
                           parameter2)
209
            {
×
210
                if (parameter2 == 0)
×
211
                {
212
                    HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
213
                        "counter_type_from_statistic<Statistic>",
214
                        "base rolling window size is specified to be zero");
215
                }
216
            }
×
217

218
            double get_value() override
×
219
            {
220
                return sqrt(boost::accumulators::rolling_variance(accum_));
×
221
            }
222

223
            void add_value(double value) override
×
224
            {
225
                accum_(value);
×
226
            }
×
227

228
            bool need_reset() const override
×
229
            {
230
                return false;
×
231
            }
232

233
        private:
234
            accumulator_type accum_;
235
        };
236

237
        template <>
238
        struct counter_type_from_statistic<boost::accumulators::tag::max>
×
239
          : counter_type_from_statistic_base
240
        {
241
            typedef boost::accumulators::tag::max aggregating_tag;
242
            typedef boost::accumulators::accumulator_set<double,
243
                boost::accumulators::stats<aggregating_tag>>
244
                accumulator_type;
245

246
            counter_type_from_statistic(std::size_t /*parameter2*/) {}
×
247

248
            double get_value() override
×
249
            {
250
                return (boost::accumulators::max)(accum_);
×
251
            }
252

253
            void add_value(double value) override
×
254
            {
255
                accum_(value);
×
256
            }
×
257

258
            bool need_reset() const override
×
259
            {
260
                return true;
×
261
            }
262

263
        private:
264
            accumulator_type accum_;
265
        };
266

267
        template <>
268
        struct counter_type_from_statistic<boost::accumulators::tag::min>
×
269
          : counter_type_from_statistic_base
270
        {
271
            typedef boost::accumulators::tag::min aggregating_tag;
272
            typedef boost::accumulators::accumulator_set<double,
273
                boost::accumulators::stats<aggregating_tag>>
274
                accumulator_type;
275

276
            counter_type_from_statistic(std::size_t /*parameter2*/) {}
×
277

278
            double get_value() override
×
279
            {
280
                return (boost::accumulators::min)(accum_);
×
281
            }
282

283
            void add_value(double value) override
×
284
            {
285
                accum_(value);
×
286
            }
×
287

288
            bool need_reset() const override
×
289
            {
290
                return true;
×
291
            }
292

293
        private:
294
            accumulator_type accum_;
295
        };
296

297
        template <>
298
        struct counter_type_from_statistic<hpx::util::tag::rolling_min>
×
299
          : counter_type_from_statistic_base
300
        {
301
            typedef hpx::util::tag::rolling_min aggregating_tag;
302
            typedef boost::accumulators::accumulator_set<double,
303
                boost::accumulators::stats<aggregating_tag>>
304
                accumulator_type;
305

306
            counter_type_from_statistic(std::size_t parameter2)
×
307
              : accum_(boost::accumulators::tag::rolling_window::window_size =
×
308
                           parameter2)
309
            {
×
310
                if (parameter2 == 0)
×
311
                {
312
                    HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
313
                        "counter_type_from_statistic<Statistic>",
314
                        "base rolling window size is specified to be zero");
315
                }
316
            }
×
317

318
            double get_value() override
×
319
            {
320
                return hpx::util::rolling_min(accum_);
×
321
            }
322

323
            void add_value(double value) override
×
324
            {
325
                accum_(value);
×
326
            }
×
327

328
            bool need_reset() const override
×
329
            {
330
                return false;
×
331
            }
332

333
        private:
334
            accumulator_type accum_;
335
        };
336

337
        template <>
338
        struct counter_type_from_statistic<hpx::util::tag::rolling_max>
×
339
          : counter_type_from_statistic_base
340
        {
341
            typedef hpx::util::tag::rolling_max aggregating_tag;
342
            typedef boost::accumulators::accumulator_set<double,
343
                boost::accumulators::stats<aggregating_tag>>
344
                accumulator_type;
345

346
            counter_type_from_statistic(std::size_t parameter2)
×
347
              : accum_(boost::accumulators::tag::rolling_window::window_size =
×
348
                           parameter2)
349
            {
×
350
                if (parameter2 == 0)
×
351
                {
352
                    HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
353
                        "counter_type_from_statistic<Statistic>",
354
                        "base rolling window size is specified to be zero");
355
                }
356
            }
×
357

358
            double get_value() override
×
359
            {
360
                return hpx::util::rolling_max(accum_);
×
361
            }
362

363
            void add_value(double value) override
×
364
            {
365
                accum_(value);
×
366
            }
×
367

368
            bool need_reset() const override
×
369
            {
370
                return false;
×
371
            }
372

373
        private:
374
            accumulator_type accum_;
375
        };
376
    }    // namespace detail
377

378
    ///////////////////////////////////////////////////////////////////////////
379
    template <typename Statistic>
380
    statistics_counter<Statistic>::statistics_counter()
×
381
      : has_prev_value_(false)
×
382
      , parameter1_(0)
×
383
      , parameter2_(0)
×
384
      , reset_base_counter_(false)
×
385
    {
×
386
    }
×
387

388
    template <typename Statistic>
389
    statistics_counter<Statistic>::statistics_counter(counter_info const& info,
1✔
390
        std::string const& base_counter_name, std::size_t parameter1,
391
        std::size_t parameter2, bool reset_base_counter)
392
      : base_type_holder(info)
1✔
393
      , timer_(hpx::bind_front(&statistics_counter::evaluate, this_()),
2✔
394
            hpx::bind_front(&statistics_counter::on_terminate, this_()),
1✔
395
            1000 * parameter1, info.fullname_, true)
1✔
396
      , base_counter_name_(ensure_counter_prefix(base_counter_name))
1✔
397
      , value_(new detail::counter_type_from_statistic<Statistic>(parameter2))
1✔
398
      , has_prev_value_(false)
1✔
399
      , parameter1_(parameter1)
1✔
400
      , parameter2_(parameter2)
1✔
401
      , reset_base_counter_(reset_base_counter)
1✔
402
    {
3✔
403
        if (parameter1 == 0)
1✔
404
        {
405
            HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
406
                "statistics_counter<Statistic>::statistics_counter",
407
                "base interval is specified to be zero");
408
        }
409

410
        if (info.type_ != counter_type::aggregating)
1✔
411
        {
412
            HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
413
                "statistics_counter<Statistic>::statistics_counter",
414
                "unexpected counter type specified");
415
        }
416

417
        // make sure this counter starts collecting data
418
        start();
1✔
419
    }
1✔
420

421
    template <typename Statistic>
422
    hpx::performance_counters::counter_value
423
    statistics_counter<Statistic>::get_counter_value(bool reset)
2✔
424
    {
425
        std::lock_guard<mutex_type> l(mtx_);
2✔
426

427
        hpx::performance_counters::counter_value value;
2✔
428

429
        prev_value_.value_ = static_cast<std::int64_t>(value_->get_value());
2✔
430
        prev_value_.status_ = counter_status::new_data;
2✔
431
        prev_value_.time_ = static_cast<std::int64_t>(hpx::get_system_uptime());
2✔
432
        prev_value_.count_ = ++invocation_count_;
2✔
433
        has_prev_value_ = true;
2✔
434

435
        value = prev_value_;    // return value
2✔
436

437
        if (reset || value_->need_reset())
2✔
438
        {
439
            value_.reset(new detail::counter_type_from_statistic<Statistic>(
×
440
                parameter2_));    // reset accumulator
×
441
            value_->add_value(static_cast<double>(prev_value_.value_));
×
442
            // start off with last base value
443
        }
×
444

445
        return value;
446
    }
2✔
447

448
    template <typename Statistic>
449
    bool statistics_counter<Statistic>::evaluate()
10✔
450
    {
451
        // gather current base value
452
        counter_value base_value;
10✔
453
        if (!evaluate_base_counter(base_value))
10✔
454
            return false;
×
455

456
        // simply average the measured base counter values since it got queried
457
        // for the last time
458
        counter_value value;
10✔
459
        if (base_value.scaling_ != prev_value_.scaling_ ||
10✔
460
            base_value.scale_inverse_ != prev_value_.scale_inverse_)
10✔
461
        {
462
            // not supported right now
463
            HPX_THROW_EXCEPTION(hpx::error::not_implemented,
×
464
                "statistics_counter<Statistic>::evaluate",
465
                "base counter should keep scaling constant over time");
466
            return false;
467
        }
468
        else
469
        {
470
            // accumulate new value
471
            std::lock_guard<mutex_type> l(mtx_);
10✔
472
            value_->add_value(static_cast<double>(base_value.value_));
10✔
473
        }
10✔
474
        return true;
10✔
475
    }
10✔
476

477
    template <typename Statistic>
478
    bool statistics_counter<Statistic>::ensure_base_counter()
1✔
479
    {
480
        // lock here to avoid checking out multiple reference counted GIDs
481
        // from AGAS. This
482
        std::unique_lock<mutex_type> l(mtx_);
1✔
483

484
        if (!base_counter_id_)
1✔
485
        {
486
            // get or create the base counter
487
            error_code ec(throwmode::lightweight);
1✔
488
            hpx::id_type base_counter_id;
1✔
489
            {
490
                // We need to unlock the lock here since get_counter might suspend
491
                unlock_guard<std::unique_lock<mutex_type>> unlock(l);
1✔
492
                base_counter_id = get_counter(base_counter_name_, ec);
1✔
493
            }
1✔
494

495
            // After reacquiring the lock, we need to check again if base_counter_id_
496
            // hasn't been set yet
497
            if (!base_counter_id_)
1✔
498
            {
499
                base_counter_id_ = base_counter_id;
1✔
500
            }
1✔
501
            else
502
            {
503
                // If it was set already by a different thread, return true.
504
                return true;
×
505
            }
506

507
            if (HPX_UNLIKELY(ec || !base_counter_id_))
1✔
508
            {
509
                // base counter could not be retrieved
510
                HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
511
                    "statistics_counter<Statistic>::evaluate_base_counter",
512
                    "could not get or create performance counter: '{}'",
513
                    base_counter_name_);
514
                return false;
515
            }
516
        }
1✔
517

518
        return true;
1✔
519
    }
1✔
520

521
    template <typename Statistic>
522
    bool statistics_counter<Statistic>::evaluate_base_counter(
10✔
523
        counter_value& value)
524
    {
525
        // query the actual value
526
        if (!base_counter_id_ && !ensure_base_counter())
10✔
527
            return false;
×
528

529
        performance_counters::performance_counter c(base_counter_id_);
10✔
530
        value = c.get_counter_value(launch::sync, reset_base_counter_);
10✔
531

532
        if (!has_prev_value_)
10✔
533
        {
534
            has_prev_value_ = true;
1✔
535
            prev_value_ = value;
1✔
536
        }
1✔
537

538
        return true;
10✔
539
    }
10✔
540

541
    ///////////////////////////////////////////////////////////////////////////
542
    // Start and stop this counter. We dispatch the calls to the base counter
543
    // and control our own interval_timer.
544
    template <typename Statistic>
545
    bool statistics_counter<Statistic>::start()
2✔
546
    {
547
        if (!timer_.is_started())
2✔
548
        {
549
            // start base counter
550
            if (!base_counter_id_ && !ensure_base_counter())
1✔
551
                return false;
×
552

553
            performance_counters::performance_counter c(base_counter_id_);
1✔
554
            bool result = c.start(launch::sync);
1✔
555
            if (result)
1✔
556
            {
557
                // acquire the current value of the base counter
558
                counter_value base_value;
×
559
                if (evaluate_base_counter(base_value))
×
560
                {
561
                    std::lock_guard<mutex_type> l(mtx_);
×
562
                    value_->add_value(static_cast<double>(base_value.value_));
×
563
                    prev_value_ = base_value;
×
564
                }
×
565

566
                // start timer
567
                timer_.start();
×
568
            }
×
569
            else
570
            {
571
                // start timer even if base counter does not support being
572
                // start/stop operations
573
                timer_.start(true);
1✔
574
            }
575
            return result;
1✔
576
        }
1✔
577
        return false;
1✔
578
    }
2✔
579

580
    template <typename Statistic>
581
    bool statistics_counter<Statistic>::stop()
1✔
582
    {
583
        if (timer_.is_started())
1✔
584
        {
585
            timer_.stop();
1✔
586

587
            if (!base_counter_id_ && !ensure_base_counter())
1✔
588
                return false;
×
589

590
            performance_counters::performance_counter c(base_counter_id_);
1✔
591
            return c.stop(launch::sync);
1✔
592
        }
1✔
593
        return false;
×
594
    }
1✔
595

596
    template <typename Statistic>
597
    void statistics_counter<Statistic>::reset_counter_value()
×
598
    {
599
        std::lock_guard<mutex_type> l(mtx_);
×
600

601
        // reset accumulator
602
        value_.reset(
×
603
            new detail::counter_type_from_statistic<Statistic>(parameter2_));
×
604

605
        // start off with last base value
606
        value_->add_value(static_cast<double>(prev_value_.value_));
×
607
    }
×
608

609
    template <typename Statistic>
610
    void statistics_counter<Statistic>::on_terminate()
1✔
611
    {
612
    }
1✔
613

614
    template <typename Statistic>
615
    void statistics_counter<Statistic>::finalize()
×
616
    {
617
        base_performance_counter::finalize();
×
618
        base_type::finalize();
×
619
    }
×
620

621
    template <typename Statistic>
622
    naming::address statistics_counter<Statistic>::get_current_address() const
1✔
623
    {
624
        return naming::address(
1✔
625
            naming::get_gid_from_locality_id(agas::get_locality_id()),
1✔
626
            components::get_component_type<statistics_counter>(),
1✔
627
            const_cast<statistics_counter*>(this));
1✔
628
    }
629
}}}    // namespace hpx::performance_counters::server
630

631
///////////////////////////////////////////////////////////////////////////////
632
template class HPX_EXPORT hpx::performance_counters::server::statistics_counter<
×
633
    boost::accumulators::tag::mean>;
634
template class HPX_EXPORT hpx::performance_counters::server::statistics_counter<
×
635
    boost::accumulators::tag::variance>;
636
template class HPX_EXPORT hpx::performance_counters::server::statistics_counter<
×
637
    boost::accumulators::tag::rolling_variance>;
638
template class HPX_EXPORT hpx::performance_counters::server::statistics_counter<
×
639
    boost::accumulators::tag::median>;
640
template class HPX_EXPORT hpx::performance_counters::server::statistics_counter<
×
641
    boost::accumulators::tag::rolling_mean>;
642
template class HPX_EXPORT hpx::performance_counters::server::statistics_counter<
×
643
    boost::accumulators::tag::max>;
644
template class HPX_EXPORT hpx::performance_counters::server::statistics_counter<
×
645
    boost::accumulators::tag::min>;
646
template class HPX_EXPORT hpx::performance_counters::server::statistics_counter<
×
647
    hpx::util::tag::rolling_min>;
648
template class HPX_EXPORT hpx::performance_counters::server::statistics_counter<
×
649
    hpx::util::tag::rolling_max>;
650

651
///////////////////////////////////////////////////////////////////////////////
652
// Average
653
typedef hpx::components::component<hpx::performance_counters::server::
654
        statistics_counter<boost::accumulators::tag::mean>>
655
    average_count_counter_type;
656

657
HPX_REGISTER_DERIVED_COMPONENT_FACTORY(average_count_counter_type,
31,246✔
658
    average_count_counter, "base_performance_counter",
659
    hpx::components::factory_enabled)
660
HPX_DEFINE_GET_COMPONENT_TYPE(average_count_counter_type::wrapped_type)
1,084✔
661

662
///////////////////////////////////////////////////////////////////////////////
663
// Rolling variance
664
typedef hpx::components::component<hpx::performance_counters::server::
665
        statistics_counter<boost::accumulators::tag::rolling_variance>>
666
    rolling_variance_count_counter_type;
667

668
HPX_REGISTER_DERIVED_COMPONENT_FACTORY(rolling_variance_count_counter_type,
41,676✔
669
    rolling_variance_count_counter, "base_performance_counter",
670
    hpx::components::factory_enabled)
671
HPX_DEFINE_GET_COMPONENT_TYPE(rolling_variance_count_counter_type::wrapped_type)
1,082✔
672

673
///////////////////////////////////////////////////////////////////////////////
674
// Variance
675
typedef hpx::components::component<hpx::performance_counters::server::
676
        statistics_counter<boost::accumulators::tag::variance>>
677
    variance_count_counter_type;
678

679
HPX_REGISTER_DERIVED_COMPONENT_FACTORY(variance_count_counter_type,
32,404✔
680
    variance_count_counter, "base_performance_counter",
681
    hpx::components::factory_enabled)
682
HPX_DEFINE_GET_COMPONENT_TYPE(variance_count_counter_type::wrapped_type)
1,082✔
683

684
///////////////////////////////////////////////////////////////////////////////
685
// Rolling average
686
typedef hpx::components::component<hpx::performance_counters::server::
687
        statistics_counter<boost::accumulators::tag::rolling_mean>>
688
    rolling_mean_count_counter_type;
689

690
HPX_REGISTER_DERIVED_COMPONENT_FACTORY(rolling_mean_count_counter_type,
37,040✔
691
    rolling_mean_count_counter, "base_performance_counter",
692
    hpx::components::factory_enabled)
693
HPX_DEFINE_GET_COMPONENT_TYPE(rolling_mean_count_counter_type::wrapped_type)
1,082✔
694

695
///////////////////////////////////////////////////////////////////////////////
696
// Median
697
typedef hpx::components::component<hpx::performance_counters::server::
698
        statistics_counter<boost::accumulators::tag::median>>
699
    median_count_counter_type;
700

701
HPX_REGISTER_DERIVED_COMPONENT_FACTORY(median_count_counter_type,
30,086✔
702
    median_count_counter, "base_performance_counter",
703
    hpx::components::factory_enabled)
704
HPX_DEFINE_GET_COMPONENT_TYPE(median_count_counter_type::wrapped_type)
1,082✔
705

706
///////////////////////////////////////////////////////////////////////////////
707
// Max
708
typedef hpx::components::component<hpx::performance_counters::server::
709
        statistics_counter<boost::accumulators::tag::max>>
710
    max_count_counter_type;
711

712
HPX_REGISTER_DERIVED_COMPONENT_FACTORY(max_count_counter_type,
26,609✔
713
    max_count_counter, "base_performance_counter",
714
    hpx::components::factory_enabled)
715
HPX_DEFINE_GET_COMPONENT_TYPE(max_count_counter_type::wrapped_type)
1,082✔
716

717
///////////////////////////////////////////////////////////////////////////////
718
// Min
719
typedef hpx::components::component<hpx::performance_counters::server::
720
        statistics_counter<boost::accumulators::tag::min>>
721
    min_count_counter_type;
722

723
HPX_REGISTER_DERIVED_COMPONENT_FACTORY(min_count_counter_type,
26,609✔
724
    min_count_counter, "base_performance_counter",
725
    hpx::components::factory_enabled)
726
HPX_DEFINE_GET_COMPONENT_TYPE(min_count_counter_type::wrapped_type)
1,082✔
727

728
///////////////////////////////////////////////////////////////////////////////
729
// Rolling min
730
typedef hpx::components::component<hpx::performance_counters::server::
731
        statistics_counter<hpx::util::tag::rolling_min>>
732
    rolling_min_count_counter_type;
733

734
HPX_REGISTER_DERIVED_COMPONENT_FACTORY(rolling_min_count_counter_type,
35,881✔
735
    rolling_min_count_counter, "base_performance_counter",
736
    hpx::components::factory_enabled)
737
HPX_DEFINE_GET_COMPONENT_TYPE(rolling_min_count_counter_type::wrapped_type)
1,082✔
738

739
///////////////////////////////////////////////////////////////////////////////
740
// Rolling max
741
typedef hpx::components::component<hpx::performance_counters::server::
742
        statistics_counter<hpx::util::tag::rolling_max>>
743
    rolling_max_count_counter_type;
744

745
HPX_REGISTER_DERIVED_COMPONENT_FACTORY(rolling_max_count_counter_type,
35,881✔
746
    rolling_max_count_counter, "base_performance_counter",
747
    hpx::components::factory_enabled)
748
HPX_DEFINE_GET_COMPONENT_TYPE(rolling_max_count_counter_type::wrapped_type)
1,082✔
749

750
///////////////////////////////////////////////////////////////////////////////
751
namespace hpx { namespace performance_counters { namespace detail {
752
    /// Creation function for aggregating performance counters to be registered
753
    /// with the counter types.
754
    naming::gid_type statistics_counter_creator(
1✔
755
        counter_info const& info, error_code& ec)
756
    {
757
        switch (info.type_)
1✔
758
        {
759
        case counter_type::aggregating:
760
        {
761
            counter_path_elements paths;
1✔
762
            get_counter_path_elements(info.fullname_, paths, ec);
1✔
763
            if (ec)
1✔
764
                return naming::invalid_gid;
×
765

766
            if (!paths.parentinstance_is_basename_)
1✔
767
            {
768
                HPX_THROWS_IF(ec, hpx::error::bad_parameter,
×
769
                    "statistics_counter_creator",
770
                    "invalid aggregate counter "
771
                    "name (instance name must be valid base counter name)");
772
                return naming::invalid_gid;
×
773
            }
774

775
            std::string base_name;
1✔
776
            get_counter_name(paths.parentinstancename_, base_name, ec);
1✔
777
            if (ec)
1✔
778
                return naming::invalid_gid;
×
779

780
            std::vector<std::size_t> parameters;
1✔
781
            if (!paths.parameters_.empty())
1✔
782
            {
783
                // try to interpret the additional parameters
784
                namespace x3 = boost::spirit::x3;
785
                if (!x3::parse(paths.parameters_.begin(),
1✔
786
                        paths.parameters_.end(), x3::uint_ % ',', parameters))
1✔
787
                {
788
                    HPX_THROWS_IF(ec, hpx::error::bad_parameter,
×
789
                        "statistics_counter_creator",
790
                        "invalid parameter specification format for "
791
                        "this counter: {}",
792
                        paths.parameters_);
793
                    return naming::invalid_gid;
×
794
                }
795
                if (paths.countername_.find("rolling") != std::string::npos)
1✔
796
                {
797
                    if (parameters.size() > 3)
×
798
                    {
799
                        HPX_THROWS_IF(ec, hpx::error::bad_parameter,
×
800
                            "statistics_counter_creator",
801
                            "too many parameter specifications for "
802
                            "this counter: {}",
803
                            paths.parameters_);
804
                        return naming::invalid_gid;
×
805
                    }
806
                }
×
807
                else if (parameters.size() > 2)
1✔
808
                {
809
                    HPX_THROWS_IF(ec, hpx::error::bad_parameter,
×
810
                        "statistics_counter_creator",
811
                        "too many parameter specifications for "
812
                        "this counter: {}",
813
                        paths.parameters_);
814
                    return naming::invalid_gid;
×
815
                }
816
            }
1✔
817
            else if (paths.countername_.find("rolling") != std::string::npos)
×
818
            {
819
                parameters.push_back(1000);    // sample interval
×
820
                parameters.push_back(10);      // rolling window
×
821
                parameters.push_back(0);       // don't reset underlying counter
×
822
            }
×
823
            else
824
            {
825
                parameters.push_back(1000);    // sample interval
×
826
                parameters.push_back(0);       // don't reset underlying counter
×
827
            }
828
            return create_statistics_counter(info, base_name, parameters, ec);
1✔
829
        }
1✔
830
        break;
831

832
        default:
833
            HPX_THROWS_IF(ec, hpx::error::bad_parameter,
×
834
                "statistics_counter_creator", "invalid counter type requested");
835
            return naming::invalid_gid;
×
836
        }
837
    }
1✔
838
}}}    // namespace hpx::performance_counters::detail
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

© 2026 Coveralls, Inc