• 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

11.11
/examples/performance_counters/sine/sine.cpp
1
//  Copyright (c) 2007-2025 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
#if !defined(HPX_COMPUTE_DEVICE_CODE)
9
#include <hpx/hpx.hpp>
10
#include <hpx/include/performance_counters.hpp>
11
#include <hpx/include/util.hpp>
12
#include <hpx/modules/runtime_local.hpp>
13

14
#include <cstdint>
15

16
#include "server/sine.hpp"
17

18
///////////////////////////////////////////////////////////////////////////////
19
// Add factory registration functionality, We register the module dynamically
20
// as no executable links against it.
21
HPX_REGISTER_COMPONENT_MODULE_DYNAMIC()
×
22

23
///////////////////////////////////////////////////////////////////////////////
24
typedef hpx::components::component<
25
    ::performance_counters::sine::server::sine_counter>
26
    sine_counter_type;
27

28
///////////////////////////////////////////////////////////////////////////////
29
namespace performance_counters { namespace sine {
30
    ///////////////////////////////////////////////////////////////////////////
31
    // This function will be invoked whenever the implicit counter is queried.
32
    std::int64_t immediate_sine(bool)
×
33
    {
34
        static std::uint64_t started_at =
35
            hpx::chrono::high_resolution_clock::now();
×
36

37
        std::uint64_t up_time =
38
            hpx::chrono::high_resolution_clock::now() - started_at;
×
39
        return std::int64_t(
×
40
            std::sin(static_cast<double>(up_time) / 1e10) * 100000.);
41
    }
42

43
    ///////////////////////////////////////////////////////////////////////////
44
    // This will be called to return special command line options supported by
45
    // this component.
32✔
46
    hpx::program_options::options_description command_line_options()
47
    {
48
        hpx::program_options::options_description opts(
32✔
49
            "Additional command line options for the sine component");
32✔
50
        opts.add_options()("sine",
51
            "enables the performance counters implemented by the "
52
            "sine component");
32✔
53
        return opts;
×
54
    }
55

56
    ///////////////////////////////////////////////////////////////////////////
57
    // Parse the command line to figure out whether the sine performance
58
    // counters need to be created.
×
59
    bool need_perf_counters()
60
    {
61
        using hpx::program_options::options_description;
62
        using hpx::program_options::variables_map;
63
        using hpx::util::retrieve_commandline_arguments;
64

65
        // Retrieve command line using the HPX.ProgramOptions library.
×
66
        variables_map vm;
×
67
        if (!retrieve_commandline_arguments(command_line_options(), vm))
68
        {
×
69
            HPX_THROW_EXCEPTION(hpx::error::commandline_option_error,
70
                "sine::need_perf_counters",
71
                "Failed to handle command line options");
72
            return false;
73
        }
74

75
        // We enable the performance counters if --sine is specified on the
76
        // command line.
×
77
        return vm.count("sine") != 0;
×
78
    }
79

80
    ///////////////////////////////////////////////////////////////////////////
81
    // Discoverer for the explicit (hand-rolled performance counter. The
82
    // purpose of this function is to invoke the supplied function f for all
83
    // allowed counter instance names supported by the counter type this
84
    // function has been registered with.
×
85
    bool explicit_sine_counter_discoverer(
86
        hpx::performance_counters::counter_info const& info,
87
        hpx::performance_counters::discover_counter_func const& f,
88
        hpx::performance_counters::discover_counters_mode mode,
89
        hpx::error_code& ec)
90
    {
×
91
        hpx::performance_counters::counter_info i = info;
92

93
        // compose the counter name templates
94
        hpx::performance_counters::counter_path_elements p;
95
        hpx::performance_counters::counter_status status =
×
96
            get_counter_path_elements(info.fullname_, p, ec);
×
97
        if (!status_is_valid(status))
98
            return false;
99

100
        if (mode ==
×
101
                hpx::performance_counters::discover_counters_mode::minimal ||
×
102
            p.parentinstancename_.empty() || p.instancename_.empty())
103
        {
×
104
            if (p.parentinstancename_.empty())
105
            {
106
                p.parentinstancename_ = "locality#*";
×
107
                p.parentinstanceindex_ = -1;
108
            }
109

×
110
            if (p.instancename_.empty())
111
            {
112
                p.instancename_ = "instance#*";
×
113
                p.instanceindex_ = -1;
114
            }
115

×
116
            status = get_counter_name(p, i.fullname_, ec);
×
117
            if (!status_is_valid(status) || !f(i, ec) || ec)
×
118
                return false;
119
        }
×
120
        else if (p.instancename_ == "instance#*")
121
        {
122
            HPX_ASSERT(mode ==
123
                hpx::performance_counters::discover_counters_mode::full);
124

125
            // FIXME: expand for all instances
126
            p.instancename_ = "instance";
×
127
            p.instanceindex_ = 0;
×
128
            status = get_counter_name(p, i.fullname_, ec);
×
129
            if (!status_is_valid(status) || !f(i, ec) || ec)
×
130
                return false;
131
        }
×
132
        else if (!f(i, ec) || ec)
133
        {
134
            return false;
135
        }
136

×
137
        if (&ec != &hpx::throws)
×
138
            ec = hpx::make_success_code();
139

140
        return true;    // everything is ok
×
141
    }
142

143
    ///////////////////////////////////////////////////////////////////////////
144
    // Creation function for explicit sine performance counter. It's purpose is
145
    // to create and register a new instance of the given name (or reuse an
146
    // existing instance).
×
147
    hpx::naming::gid_type explicit_sine_counter_creator(
148
        hpx::performance_counters::counter_info const& info,
149
        hpx::error_code& ec)
150
    {
151
        // verify the validity of the counter instance name
152
        hpx::performance_counters::counter_path_elements paths;
×
153
        get_counter_path_elements(info.fullname_, paths, ec);
×
154
        if (ec)
155
            return hpx::naming::invalid_gid;
156

×
157
        if (paths.parentinstance_is_basename_)
158
        {
×
159
            HPX_THROWS_IF(ec, hpx::error::bad_parameter,
160
                "sine::explicit_sine_counter_creator",
161
                "invalid counter instance parent name: " +
162
                    paths.parentinstancename_);
163
            return hpx::naming::invalid_gid;
164
        }
165

166
        // create individual counter
×
167
        if (paths.instancename_ == "instance" && paths.instanceindex_ != -1)
168
        {
169
            // make sure parent instance name is set properly
×
170
            hpx::performance_counters::counter_info complemented_info = info;
×
171
            complement_counter_info(complemented_info, info, ec);
×
172
            if (ec)
173
                return hpx::naming::invalid_gid;
174

175
            // create the counter as requested
176
            hpx::naming::gid_type id;
177
            try
178
            {
179
                // create the 'sine' performance counter component locally, we
180
                // only get here if this instance does not exist yet
×
181
                id = hpx::components::server::construct<sine_counter_type>(
182
                    complemented_info);
183
            }
×
184
            catch (hpx::exception const& e)
185
            {
×
186
                if (&ec == &hpx::throws)
×
187
                    throw;
×
188
                ec = make_error_code(e.get_error(), e.what());
189
                return hpx::naming::invalid_gid;
×
190
            }
191

×
192
            if (&ec != &hpx::throws)
×
193
                ec = hpx::make_success_code();
194
            return id;
×
195
        }
196

×
197
        HPX_THROWS_IF(ec, hpx::error::bad_parameter,
198
            "sine::explicit_sine_counter_creator",
199
            "invalid counter instance name: " + paths.instancename_);
200
        return hpx::naming::invalid_gid;
×
201
    }
202

203
    ///////////////////////////////////////////////////////////////////////////
204
    // This function will be registered as a startup function for HPX below.
205
    //
206
    // That means it will be executed in a HPX-thread before hpx_main, but after
207
    // the runtime has been initialized and started.
×
208
    void startup()
209
    {
210
        using namespace hpx::performance_counters;
211
        using hpx::placeholders::_1;
212
        using hpx::placeholders::_2;
213

214
        // define the counter types
215
        generic_counter_type_data const counter_types[] = {
216
            // We assume that valid counter names have the following scheme:
217
            //
218
            //  /sine(locality#<locality_id>/instance#<instance_id>)/immediate/explicit
219
            //
220
            // where '<locality_id>' is the number of the locality the
221
            // counter has to be instantiated on and '<instance_id>' is the
222
            // instance number to use for the particular counter. We allow
223
            // any arbitrary number of instances.
224
            {"/sine/immediate/explicit", counter_type::raw,
225
                "returns the current value of a sine wave calculated over "
226
                "an arbitrary time line (explicit, hand-rolled version)",
×
227
                HPX_PERFORMANCE_COUNTER_V1, &explicit_sine_counter_creator,
×
228
                &explicit_sine_counter_discoverer, ""},
229
            // We assume that valid counter names have the following scheme:
230
            //
231
            //  /sine(locality#<locality_id>/total)/immediate/implicit
232
            //
233
            // where '<locality_id>' is the number of the locality the
234
            // counter has to be instantiated on. The function 'immediate_sine'
235
            // is used as the source of counter data for the created counter.
236
            {"/sine/immediate/implicit", counter_type::raw,
237
                "returns the current value of a sine wave calculated over "
238
                "an arbitrary time line (implicit version, using HPX "
239
                "facilities)",
240
                HPX_PERFORMANCE_COUNTER_V1,
241
                hpx::bind(
242
                    &hpx::performance_counters::locality_raw_counter_creator,
243
                    _1, &immediate_sine, _2),
×
244
                &hpx::performance_counters::locality_counter_discoverer, ""}};
245

246
        // Install the counter types, de-installation of the types is handled
247
        // automatically.
×
248
        install_counter_types(
249
            counter_types, sizeof(counter_types) / sizeof(counter_types[0]));
×
250
    }
251

252
    ///////////////////////////////////////////////////////////////////////////
32✔
253
    bool get_startup(
254
        hpx::startup_function_type& startup_func, bool& pre_startup)
255
    {
256
        // exit silently if this gets loaded outside of the sine_client example
64✔
257
        if (hpx::get_config_entry("hpx.components.sine.enabled", "0") == "0")
258
        {
259
            return false;
260
        }
261

262
        // check whether the performance counters need to be enabled
×
263
        if (!need_perf_counters())
264
        {
×
265
            HPX_THROW_EXCEPTION(hpx::error::dynamic_link_failure,
266
                "performance_counters::sine::get_startup",
267
                "the sine component is not enabled on the commandline "
268
                "(--sine), bailing out");
269
            return false;
270
        }
271

272
        // return our startup-function if performance counters are required
273
        startup_func = startup;    // function to run during startup
×
274
        pre_startup = true;        // run 'startup' as pre-startup function
×
275
        return true;
276
    }
277
}}    // namespace performance_counters::sine
278

279
///////////////////////////////////////////////////////////////////////////////
280
// Register a startup function which will be called as a HPX-thread during
281
// runtime startup. We use this function to register our performance counter
282
// type and performance counter instances.
283
//
284
// Note that this macro can be used not more than once in one module.
64✔
285
HPX_REGISTER_STARTUP_MODULE_DYNAMIC(::performance_counters::sine::get_startup)
286

287
///////////////////////////////////////////////////////////////////////////////
288
// Register a function to be called to populate the special command line
289
// options supported by this component.
290
//
291
// Note that this macro can be used not more than once in one module.
32✔
292
HPX_REGISTER_COMMANDLINE_MODULE_DYNAMIC(
293
    ::performance_counters::sine::command_line_options)
294
#endif
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