• 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

0.0
/libs/full/performance_counters/src/performance_counter_set.cpp
1
//  Copyright (c) 2016-2022 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/assert.hpp>
9
#include <hpx/modules/async_base.hpp>
10
#include <hpx/modules/errors.hpp>
11
#include <hpx/modules/functional.hpp>
12
#include <hpx/modules/futures.hpp>
13
#include <hpx/modules/pack_traversal.hpp>
14
#include <hpx/modules/runtime_local.hpp>
15
#include <hpx/performance_counters/counters.hpp>
16
#include <hpx/performance_counters/performance_counter.hpp>
17
#include <hpx/performance_counters/performance_counter_set.hpp>
18

19
#include <algorithm>
20
#include <cstddef>
21
#include <mutex>
22
#include <string>
23
#include <utility>
24
#include <vector>
25

26
#include <hpx/config/warnings_prefix.hpp>
27

28
///////////////////////////////////////////////////////////////////////////////
29
namespace hpx { namespace performance_counters {
×
30
    performance_counter_set::performance_counter_set(
×
31
        std::string const& name, bool reset)
×
32
      : invocation_count_(0)
×
33
      , print_counters_locally_(false)
34
    {
×
35
        add_counters(name, reset);
×
36
    }
37

×
38
    performance_counter_set::performance_counter_set(
×
39
        std::vector<std::string> const& names, bool reset)
×
40
      : invocation_count_(0)
×
41
      , print_counters_locally_(false)
42
    {
×
43
        add_counters(names, reset);
×
44
    }
45

×
46
    void performance_counter_set::release()
47
    {
×
48
        std::vector<hpx::id_type> ids;
49

50
        {
×
51
            std::lock_guard<mutex_type> l(mtx_);
52
            infos_.clear();
53
            std::swap(ids_, ids);
54
        }
×
55
    }
56

×
57
    std::size_t performance_counter_set::size() const
58
    {
×
59
        std::lock_guard<mutex_type> l(mtx_);
×
60
        return ids_.size();
61
    }
62

×
63
    std::vector<counter_info> performance_counter_set::get_counter_infos() const
64
    {
×
65
        std::lock_guard<mutex_type> l(mtx_);
×
66
        return infos_;
67
    }
68

69
    ///////////////////////////////////////////////////////////////////////////
×
70
    bool performance_counter_set::find_counter(
71
        counter_info const& info, bool reset, error_code& ec)
72
    {
73
        // keep only local counters if requested
×
74
        if (print_counters_locally_)
75
        {
76
            counter_path_elements p;
×
77
            get_counter_path_elements(info.fullname_, p, ec);
×
78
            if (ec)
79
                return false;
80

×
81
            if (p.parentinstanceindex_ != hpx::get_locality_id())
82
            {
×
83
                if (&ec != &throws)
×
84
                    ec = make_success_code();
×
85
                return true;
86
            }
×
87
        }
88

×
89
        hpx::id_type id = get_counter(info.fullname_, ec);
×
90
        if (HPX_UNLIKELY(!id))
91
        {
×
92
            HPX_THROWS_IF(ec, hpx::error::bad_parameter,
93
                "performance_counter_set::find_counter",
94
                "unknown performance counter: '{1}' ({2})", info.fullname_,
95
                ec.get_message());
×
96
            return false;
97
        }
98

99
        {
×
100
            std::unique_lock<mutex_type> l(mtx_);
×
101
            infos_.push_back(info);
×
102
            ids_.push_back(id);
×
103
            reset_.push_back(reset ? 1 : 0);
104
        }
105

×
106
        if (&ec != &throws)
×
107
            ec = make_success_code();
108

109
        return true;
110
    }
111

×
112
    void performance_counter_set::add_counters(
113
        std::string const& name, bool reset, error_code& ec)
114
    {
115
        using placeholders::_1;
116
        using placeholders::_2;
117

×
118
        discover_counter_func func = hpx::bind(
×
119
            &performance_counter_set::find_counter, this, _1, reset, _2);
120

121
        // do INI expansion on counter name
122
        std::string n(name);
×
123
        util::expand(n);
124

125
        // find matching counter types
×
126
        discover_counter_type(
127
            n, HPX_MOVE(func), discover_counters_mode::full, ec);
×
128
        if (ec)
129
            return;
130

131
        HPX_ASSERT(ids_.size() == infos_.size());
132
    }
133

×
134
    void performance_counter_set::add_counters(
135
        std::vector<std::string> const& names, bool reset, error_code& ec)
136
    {
137
        using placeholders::_1;
138
        using placeholders::_2;
139

×
140
        discover_counter_func func = hpx::bind(
×
141
            &performance_counter_set::find_counter, this, _1, reset, _2);
142

×
143
        for (std::string const& name : names)
144
        {
145
            // do INI expansion on counter name
146
            std::string n(name);
×
147
            util::expand(n);
148

149
            // find matching counter types
×
150
            discover_counter_type(n, func, discover_counters_mode::full, ec);
×
151
            if (ec)
152
                return;
153
        }
154

155
        HPX_ASSERT(ids_.size() == infos_.size());
156
    }
157

158
    ///////////////////////////////////////////////////////////////////////////
×
159
    std::vector<hpx::future<bool>> performance_counter_set::start()
160
    {
×
161
        std::vector<hpx::id_type> ids;
162

163
        {
×
164
            std::unique_lock<mutex_type> l(mtx_);
×
165
            ids = ids_;
166
        }
167

×
168
        std::vector<hpx::future<bool>> v;
×
169
        v.reserve(ids.size());
170

171
        // start all performance counters
×
172
        for (std::size_t i = 0; i != ids.size(); ++i)
173
        {
174
            performance_counters::performance_counter c(ids[i]);
×
175
            v.emplace_back(c.start());
176
        }
177

×
178
        return v;
×
179
    }
180

×
181
    bool performance_counter_set::start(launch::sync_policy, error_code& ec)
182
    {
183
        try
184
        {
×
185
            auto v = hpx::unwrap(start());
×
186
            return std::all_of(
187
                v.begin(), v.end(), [](bool val) { return val; });
188
        }
×
189
        catch (hpx::exception const& e)
190
        {
×
191
            HPX_RETHROWS_IF(ec, e, "performance_counter_set::start");
192
            return false;
×
193
        }
194
    }
195

×
196
    std::vector<hpx::future<bool>> performance_counter_set::stop()
197
    {
×
198
        std::vector<hpx::id_type> ids;
199

200
        {
×
201
            std::unique_lock<mutex_type> l(mtx_);
×
202
            ids = ids_;
203
        }
204

×
205
        std::vector<hpx::future<bool>> v;
×
206
        v.reserve(ids.size());
207

208
        // stop all performance counters
×
209
        for (std::size_t i = 0; i != ids.size(); ++i)
210
        {
211
            performance_counters::performance_counter c(ids[i]);
×
212
            v.emplace_back(c.stop());
213
        }
214

×
215
        return v;
×
216
    }
217

×
218
    bool performance_counter_set::stop(launch::sync_policy, error_code& ec)
219
    {
220
        try
221
        {
×
222
            auto v = hpx::unwrap(stop());
×
223
            return std::all_of(
224
                v.begin(), v.end(), [](bool val) { return val; });
225
        }
×
226
        catch (hpx::exception const& e)
227
        {
×
228
            HPX_RETHROWS_IF(ec, e, "performance_counter_set::stop");
229
            return false;
×
230
        }
231
    }
232

×
233
    std::vector<hpx::future<void>> performance_counter_set::reset()
234
    {
×
235
        std::vector<hpx::id_type> ids;
236

237
        {
×
238
            std::unique_lock<mutex_type> l(mtx_);
×
239
            ids = ids_;
240
        }
241

×
242
        std::vector<hpx::future<void>> v;
×
243
        v.reserve(ids.size());
244

245
        // reset all performance counters
×
246
        for (std::size_t i = 0; i != ids.size(); ++i)
247
        {
248
            performance_counters::performance_counter c(ids[i]);
×
249
            v.emplace_back(c.reset());
250
        }
251

×
252
        return v;
×
253
    }
254

×
255
    void performance_counter_set::reset(launch::sync_policy, error_code& ec)
256
    {
257
        try
258
        {
×
259
            hpx::unwrap(reset());
260
        }
×
261
        catch (hpx::exception const& e)
262
        {
×
263
            HPX_RETHROWS_IF(ec, e, "performance_counter_set::reset");
×
264
        }
×
265
    }
266

×
267
    std::vector<hpx::future<void>> performance_counter_set::reinit(bool reset)
268
    {
×
269
        std::vector<hpx::id_type> ids;
270

271
        {
×
272
            std::unique_lock<mutex_type> l(mtx_);
×
273
            ids = ids_;
274
        }
275

×
276
        std::vector<hpx::future<void>> v;
×
277
        v.reserve(ids.size());
278

279
        // re-initialize all performance counters
×
280
        for (std::size_t i = 0; i != ids.size(); ++i)
281
        {
282
            performance_counters::performance_counter c(ids[i]);
×
283
            v.emplace_back(c.reinit(reset));
284
        }
285

×
286
        return v;
×
287
    }
288

×
289
    void performance_counter_set::reinit(
290
        launch::sync_policy, bool reset, error_code& ec)
291
    {
292
        try
293
        {
×
294
            hpx::unwrap(reinit(reset));
295
        }
×
296
        catch (hpx::exception const& e)
297
        {
×
298
            HPX_RETHROWS_IF(ec, e, "performance_counter_set::reinit");
×
299
        }
×
300
    }
301

302
    ///////////////////////////////////////////////////////////////////////////
303
    std::vector<hpx::future<counter_value>>
×
304
    performance_counter_set::get_counter_values(bool reset) const
305
    {
×
306
        std::vector<hpx::id_type> ids;
307

308
        {
×
309
            std::unique_lock<mutex_type> l(mtx_);
×
310
            ids = ids_;
×
311
            ++invocation_count_;
312
        }
313

×
314
        std::vector<hpx::future<counter_value>> v;
×
315
        v.reserve(ids.size());
316

317
        // reset all performance counters
×
318
        for (std::size_t i = 0; i != ids.size(); ++i)
319
        {
×
320
            if (infos_[i].type_ == counter_type::histogram ||
321
                infos_[i].type_ == counter_type::raw_values)
322
            {
×
323
                continue;
324
            }
325

326
            performance_counters::performance_counter c(ids[i]);
×
327
            v.emplace_back(c.get_counter_value(reset || reset_[i]));
328
        }
329

×
330
        return v;
×
331
    }
332

×
333
    std::vector<counter_value> performance_counter_set::get_counter_values(
334
        launch::sync_policy, bool reset, error_code& ec) const
335
    {
336
        try
337
        {
×
338
            return hpx::unwrap(get_counter_values(reset));
339
        }
×
340
        catch (hpx::exception const& e)
341
        {
×
342
            HPX_RETHROWS_IF(
343
                ec, e, "performance_counter_set::get_counter_values");
×
344
            return std::vector<counter_value>();
×
345
        }
346
    }
347

348
    ///////////////////////////////////////////////////////////////////////////
349
    std::vector<hpx::future<counter_values_array>>
×
350
    performance_counter_set::get_counter_values_array(bool reset) const
351
    {
×
352
        std::vector<hpx::id_type> ids;
353

354
        {
×
355
            std::unique_lock<mutex_type> l(mtx_);
×
356
            ids = ids_;
×
357
            ++invocation_count_;
358
        }
359

×
360
        std::vector<hpx::future<counter_values_array>> v;
×
361
        v.reserve(ids.size());
362

363
        // reset all performance counters
×
364
        for (std::size_t i = 0; i != ids.size(); ++i)
365
        {
×
366
            if (infos_[i].type_ != counter_type::histogram &&
367
                infos_[i].type_ != counter_type::raw_values)
368
            {
×
369
                continue;
370
            }
371

372
            performance_counters::performance_counter c(ids[i]);
×
373
            v.emplace_back(c.get_counter_values_array(reset || reset_[i]));
374
        }
375

×
376
        return v;
×
377
    }
378

379
    std::vector<counter_values_array>
×
380
    performance_counter_set::get_counter_values_array(
381
        launch::sync_policy, bool reset, error_code& ec) const
382
    {
383
        try
384
        {
×
385
            return hpx::unwrap(get_counter_values_array(reset));
386
        }
×
387
        catch (hpx::exception const& e)
388
        {
×
389
            HPX_RETHROWS_IF(
390
                ec, e, "performance_counter_set::get_counter_values_aray");
×
391
            return std::vector<counter_values_array>();
×
392
        }
393
    }
394

395
    ///////////////////////////////////////////////////////////////////////////
×
396
    std::size_t performance_counter_set::get_invocation_count() const
397
    {
×
398
        std::unique_lock<mutex_type> l(mtx_);
×
399
        return invocation_count_;
400
    }
401
}}    // 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