• 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

74.16
/libs/full/runtime_distributed/src/runtime_distributed.cpp
1
//  Copyright (c) 2007-2021 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

10
#include <hpx/agas/addressing_service.hpp>
11
#include <hpx/assert.hpp>
12
#include <hpx/async_base/launch_policy.hpp>
13
#include <hpx/async_distributed/post.hpp>
14
#include <hpx/components_base/agas_interface.hpp>
15
#include <hpx/components_base/server/component.hpp>
16
#include <hpx/components_base/server/component_base.hpp>
17
#include <hpx/coroutines/coroutine.hpp>
18
#include <hpx/datastructures/tuple.hpp>
19
#include <hpx/errors/try_catch_exception_ptr.hpp>
20
#include <hpx/execution_base/this_thread.hpp>
21
#include <hpx/format.hpp>
22
#include <hpx/functional/bind.hpp>
23
#include <hpx/functional/function.hpp>
24
#include <hpx/itt_notify/thread_name.hpp>
25
#include <hpx/modules/errors.hpp>
26
#include <hpx/modules/logging.hpp>
27
#include <hpx/modules/static_reinit.hpp>
28
#include <hpx/modules/threadmanager.hpp>
29
#include <hpx/modules/topology.hpp>
30
#include <hpx/naming_base/id_type.hpp>
31
#include <hpx/parcelset/parcelhandler.hpp>
32
#include <hpx/parcelset/parcelset_fwd.hpp>
33
#include <hpx/performance_counters/counter_creators.hpp>
34
#include <hpx/performance_counters/counters.hpp>
35
#include <hpx/performance_counters/manage_counter_type.hpp>
36
#include <hpx/performance_counters/query_counters.hpp>
37
#include <hpx/performance_counters/registry.hpp>
38
#include <hpx/runtime_components/components_fwd.hpp>
39
#include <hpx/runtime_components/console_error_sink.hpp>
40
#include <hpx/runtime_components/console_logging.hpp>
41
#include <hpx/runtime_components/server/console_error_sink.hpp>
42
#include <hpx/runtime_configuration/runtime_configuration.hpp>
43
#include <hpx/runtime_distributed.hpp>
44
#include <hpx/runtime_distributed/applier.hpp>
45
#include <hpx/runtime_distributed/big_boot_barrier.hpp>
46
#include <hpx/runtime_distributed/find_localities.hpp>
47
#include <hpx/runtime_distributed/get_num_localities.hpp>
48
#include <hpx/runtime_distributed/runtime_fwd.hpp>
49
#include <hpx/runtime_distributed/runtime_support.hpp>
50
#include <hpx/runtime_distributed/server/runtime_support.hpp>
51
#include <hpx/runtime_local/config_entry.hpp>
52
#include <hpx/runtime_local/custom_exception_info.hpp>
53
#include <hpx/runtime_local/debugging.hpp>
54
#include <hpx/runtime_local/runtime_local.hpp>
55
#include <hpx/runtime_local/shutdown_function.hpp>
56
#include <hpx/runtime_local/startup_function.hpp>
57
#include <hpx/runtime_local/state.hpp>
58
#include <hpx/runtime_local/thread_hooks.hpp>
59
#include <hpx/runtime_local/thread_mapper.hpp>
60
#include <hpx/thread_support/set_thread_name.hpp>
61
#include <hpx/threading_base/external_timer.hpp>
62
#include <hpx/threading_base/scheduler_mode.hpp>
63
#include <hpx/timing/high_resolution_clock.hpp>
64
#include <hpx/type_support/unused.hpp>
65
#include <hpx/util/from_string.hpp>
66
#include <hpx/version.hpp>
67

68
#include <atomic>
69
#include <condition_variable>
70
#include <cstddef>
71
#include <cstdint>
72
#include <cstring>
73
#include <exception>
74
#include <functional>
75
#include <iostream>
76
#include <list>
77
#include <memory>
78
#include <mutex>
79
#include <sstream>
80
#include <string>
81
#include <thread>
82
#include <utility>
83
#include <vector>
84

85
#if defined(_WIN64) && defined(HPX_DEBUG) &&                                   \
86
    !defined(HPX_HAVE_FIBER_BASED_COROUTINES)
87
#include <io.h>
88
#endif
89

90
///////////////////////////////////////////////////////////////////////////////
91
namespace hpx {
92

93
    namespace detail {
94
        naming::gid_type get_next_id(std::size_t count)
1,062✔
95
        {
96
            if (nullptr == get_runtime_ptr())
1,062✔
97
                return naming::invalid_gid;
×
98

99
            return get_runtime_distributed().get_next_id(count);
1,062✔
100
        }
1,062✔
101

102
        ///////////////////////////////////////////////////////////////////////
103
#if defined(HPX_HAVE_NETWORKING)
104
        void dijkstra_make_black()
458,268✔
105
        {
106
            get_runtime_support_ptr()->dijkstra_make_black();
458,268✔
107
        }
458,269✔
108
#endif
109

110
#if defined(HPX_HAVE_BACKGROUND_THREAD_COUNTERS) &&                            \
111
    defined(HPX_HAVE_THREAD_IDLE_RATES)
112
        bool network_background_callback(std::size_t num_thread,
113
            std::int64_t& background_work_exec_time_send,
114
            std::int64_t& background_work_exec_time_receive)
115
        {
116
            bool result = false;
117

118
#if defined(HPX_HAVE_NETWORKING)
119
            // count background work duration
120
            {
121
                threads::background_work_duration_counter bg_send_duration(
122
                    background_work_exec_time_send);
123
                threads::background_exec_time_wrapper bg_exec_time(
124
                    bg_send_duration);
125

126
                if (hpx::parcelset::do_background_work(
127
                        num_thread, parcelset::parcelport_background_mode_send))
128
                {
129
                    result = true;
130
                }
131
            }
132

133
            {
134
                threads::background_work_duration_counter bg_receive_duration(
135
                    background_work_exec_time_receive);
136
                threads::background_exec_time_wrapper bg_exec_time(
137
                    bg_receive_duration);
138

139
                if (hpx::parcelset::do_background_work(num_thread,
140
                        parcelset::parcelport_background_mode_receive))
141
                {
142
                    result = true;
143
                }
144
            }
145
#endif
146

147
            if (0 == num_thread)
148
                hpx::agas::garbage_collect_non_blocking();
149
            return result;
150
        }
151
#else
152
        bool network_background_callback(std::size_t num_thread)
80,220,422✔
153
        {
154
            bool result = false;
80,838,519✔
155

156
#if defined(HPX_HAVE_NETWORKING)
157
            if (hpx::parcelset::do_background_work(
80,838,519✔
158
                    num_thread, parcelset::parcelport_background_mode_all))
80,838,519✔
159
            {
160
                result = true;
×
161
            }
×
162
#endif
163

164
            if (0 == num_thread)
81,143,880✔
165
                hpx::agas::garbage_collect_non_blocking();
22,101,506✔
166
            return result;
80,883,362✔
167
        }
168
#endif
169
    }    // namespace detail
170

171
    ///////////////////////////////////////////////////////////////////////////
172
    components::server::runtime_support* get_runtime_support_ptr()
459,033✔
173
    {
174
        return static_cast<components::server::runtime_support*>(
459,034✔
175
            get_runtime_distributed().get_runtime_support_lva());
459,033✔
176
    }
177

178
    ///////////////////////////////////////////////////////////////////////////
179
    runtime_distributed::runtime_distributed(util::runtime_configuration& rtcfg,
1,779✔
180
        int (*pre_main)(runtime_mode), void (*post_main)())
181
      : runtime(rtcfg)
593✔
182
      , mode_(rtcfg_.mode_)
593✔
183
#if defined(HPX_HAVE_NETWORKING)
184
      , parcel_handler_notifier_()
593✔
185
      , parcel_handler_(rtcfg_)
593✔
186
#endif
187
      , agas_client_(rtcfg_)
593✔
188
      , applier_()
593✔
189
      , runtime_support_()
593✔
190
      , pre_main_(pre_main)
593✔
191
      , post_main_(post_main)
593✔
192
    {
1,186✔
193
        // set notification policies only after the object was completely
194
        // initialized
195
        runtime::set_notification_policies(
1,186✔
196
            runtime_distributed::get_notification_policy(
593✔
197
                "worker-thread", runtime_local::os_thread_type::worker_thread),
198
#ifdef HPX_HAVE_IO_POOL
199
            runtime_distributed::get_notification_policy(
593✔
200
                "io-thread", runtime_local::os_thread_type::io_thread),
201
#endif
202
#ifdef HPX_HAVE_TIMER_POOL
203
            runtime_distributed::get_notification_policy(
593✔
204
                "timer-thread", runtime_local::os_thread_type::timer_thread),
205
#endif
206
            threads::detail::network_background_callback_type(
593✔
207
                &detail::network_background_callback));
593✔
208

209
#if defined(HPX_HAVE_NETWORKING)
210
        parcel_handler_notifier_ = runtime_distributed::get_notification_policy(
593✔
211
            "parcel-thread", runtime_local::os_thread_type::parcel_thread);
212
        parcel_handler_.set_notification_policies(
1,186✔
213
            rtcfg_, thread_manager_.get(), parcel_handler_notifier_);
593✔
214

215
        applier_.init(parcel_handler_, *thread_manager_);
593✔
216
#else
217
        applier_.init(*thread_manager_);
218
#endif
219
        runtime_support_.reset(new components::server::runtime_support(rtcfg_));
593✔
220

221
        // This needs to happen first
222
        runtime::init();
593✔
223

224
        init_global_data();
593✔
225
        util::reinit_construct();
593✔
226

227
        LPROGRESS_;
593✔
228

229
        components::server::get_error_dispatcher().set_error_sink(
593✔
230
            &runtime_distributed::default_errorsink);
593✔
231

232
        // now, launch AGAS and register all nodes, launch all other components
233
        initialize_agas();
593✔
234

235
        applier_.initialize(std::uint64_t(runtime_support_.get()));
593✔
236
    }
593✔
237

238
    void runtime_distributed::initialize_agas()
593✔
239
    {
240
#if defined(HPX_HAVE_NETWORKING)
241
        std::shared_ptr<parcelset::parcelport> pp =
242
            parcel_handler_.get_bootstrap_parcelport();
593✔
243

244
        agas::create_big_boot_barrier(
593✔
245
            pp ? pp.get() : nullptr, parcel_handler_.endpoints(), rtcfg_);
593✔
246

247
        if (agas_client_.is_bootstrap())
593✔
248
        {
249
            // store number of cores used by other processes
250
            std::uint32_t cores_needed = assign_cores();
451✔
251
            std::uint32_t first_used_core = assign_cores(
451✔
252
                pp ? pp->get_locality_name() : "<console>", cores_needed);
451✔
253

254
            rtcfg_.set_first_used_core(first_used_core);
451✔
255
            HPX_ASSERT(pp ? pp->here() == pp->agas_locality(rtcfg_) : true);
451✔
256

257
            agas_client_.bootstrap(parcel_handler_.endpoints(), rtcfg_);
451✔
258

259
            init_id_pool_range();
451✔
260

261
            hpx::detail::try_catch_exception_ptr(
451✔
262
                [&]() {
902✔
263
                    if (pp)
451✔
264
                        pp->run(false);
141✔
265
                },
451✔
266
                [&](std::exception_ptr&& e) {
451✔
267
                    std::cerr << hpx::util::format(
×
268
                        "the bootstrap parcelport ({}) has failed to "
×
269
                        "initialize on locality {}:\n{},\nbailing out\n",
270
                        pp->type(), hpx::get_locality_id(),
×
271
                        hpx::get_error_what(e));
×
272
                    std::terminate();
×
273
                });
×
274

275
            agas::get_big_boot_barrier().wait_bootstrap();
451✔
276
        }
451✔
277
        else
278
        {
279
            hpx::detail::try_catch_exception_ptr(
142✔
280
                [&]() {
284✔
281
                    if (pp)
142✔
282
                        pp->run(false);
142✔
283
                },
142✔
284
                [&](std::exception_ptr&& e) {
142✔
285
                    std::cerr << hpx::util::format(
×
286
                        "the bootstrap parcelport ({}) has failed to "
×
287
                        "initialize on locality {}:\n{},\nbailing out\n",
288
                        pp->type(), hpx::get_locality_id(),
×
289
                        hpx::get_error_what(e));
×
290
                    std::terminate();
×
291
                });
×
292

293
            agas::get_big_boot_barrier().wait_hosted(
284✔
294
                pp ? pp->get_locality_name() : "<console>",
142✔
295
                agas_client_.get_primary_ns_lva(),
142✔
296
                agas_client_.get_symbol_ns_lva());
142✔
297
        }
298

299
        agas_client_.initialize(std::uint64_t(runtime_support_.get()));
593✔
300
        parcel_handler_.initialize();
593✔
301
#else
302
        if (agas_client_.is_bootstrap())
303
        {
304
            parcelset::endpoints_type endpoints;
305
            endpoints.insert(parcelset::endpoints_type::value_type(
306
                "local-loopback", parcelset::locality{}));
307
            agas_client_.bootstrap(endpoints, rtcfg_);
308
        }
309
        agas_client_.initialize(std::uint64_t(runtime_support_.get()));
310
#endif
311
    }
593✔
312

313
    ///////////////////////////////////////////////////////////////////////////
314
    runtime_distributed::~runtime_distributed()
1,182✔
315
    {
1,182✔
316
        LRT_(debug).format("~runtime_distributed(entering)");
591✔
317

318
        // reset counter registry
319
        get_counter_registry().clear();
591✔
320

321
        runtime_support_->delete_function_lists();
591✔
322

323
        // stop all services
324
#if defined(HPX_HAVE_NETWORKING)
325
        parcel_handler_.stop();    // stops parcel pools as well
591✔
326
#endif
327
        // unload libraries
328
        runtime_support_->tidy();
591✔
329

330
        LRT_(debug).format("~runtime_distributed(finished)");
591✔
331

332
        LPROGRESS_;
591✔
333
    }
1,182✔
334

335
    threads::thread_result_type runtime_distributed::run_helper(
593✔
336
        hpx::function<runtime::hpx_main_function_type> const& func, int& result)
337
    {
338
        bool caught_exception = false;
593✔
339
        try
340
        {
341
            lbt_ << "(2nd stage) runtime_distributed::run_helper: launching "
593✔
342
                    "pre_main";
343

344
            // Change our thread description, as we're about to call pre_main
345
            threads::set_thread_description(threads::get_self_id(), "pre_main");
593✔
346

347
            // Finish the bootstrap
348
            result = 0;
593✔
349
            if (pre_main_ != nullptr)
593✔
350
            {
351
                result = pre_main_(mode_);
593✔
352
            }
593✔
353

354
            if (result)
593✔
355
            {
356
                lbt_ << "runtime_distributed::run_helper: bootstrap "
×
357
                        "aborted, bailing out";
358
                return threads::thread_result_type(
×
359
                    threads::thread_schedule_state::terminated,
×
360
                    threads::invalid_thread_id);
361
            }
362

363
            lbt_ << "(4th stage) runtime_distributed::run_helper: bootstrap "
593✔
364
                    "complete";
365
            set_state(hpx::state::running);
593✔
366

367
#if defined(HPX_HAVE_NETWORKING)
368
            parcel_handler_.enable_alternative_parcelports();
593✔
369
#endif
370
            // reset all counters right before running main, if requested
371
            if (get_config_entry("hpx.print_counter.startup", "0") == "1")
593✔
372
            {
373
                bool reset = false;
×
374
                if (get_config_entry("hpx.print_counter.reset", "0") == "1")
×
375
                    reset = true;
×
376

377
                error_code ec(throwmode::lightweight);    // ignore errors
×
378
                evaluate_active_counters(reset, "startup", ec);
×
379
            }
×
380
        }
593✔
381
        catch (...)
382
        {
383
            // make sure exceptions thrown in hpx_main don't escape
384
            // unnoticed
385
            {
386
                std::lock_guard<std::mutex> l(mtx_);
×
387
                exception_ = std::current_exception();
×
388
            }
×
389
            result = -1;
×
390
            caught_exception = true;
×
391
        }
×
392

393
        if (caught_exception)
593✔
394
        {
395
            HPX_ASSERT(exception_);
×
396
            report_error(exception_, false);
×
397
            finalize(-1.0);    // make sure the application exits
×
398
        }
×
399

400
        auto result_value = runtime::run_helper(func, result, false);
593✔
401

402
        if (post_main_ != nullptr)
593✔
403
        {
404
            post_main_();
593✔
405
        }
593✔
406

407
        return result_value;
593✔
408
    }
593✔
409

410
    int runtime_distributed::start(
593✔
411
        hpx::function<hpx_main_function_type> const& func, bool blocking)
412
    {
413
#if defined(_WIN64) && defined(HPX_DEBUG) &&                                   \
414
    !defined(HPX_HAVE_FIBER_BASED_COROUTINES)
415
        // needs to be called to avoid problems at system startup
416
        // see: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100319
417
        _isatty(0);
418
#endif
419
        // {{{ early startup code - local
420

421
        // initialize instrumentation system
422
#ifdef HPX_HAVE_APEX
423
        util::external_timer::init(
424
            nullptr, hpx::get_locality_id(), hpx::get_initial_num_localities());
425
#endif
426

427
        LRT_(info).format("cmd_line: {}", get_config().get_cmd_line());
593✔
428

429
        lbt_ << "(1st stage) runtime_distributed::start: booting locality "
593✔
430
             << here();
593✔
431

432
        // Register this thread with the runtime system to allow calling
433
        // certain HPX functionality from the main thread. Also calls
434
        // registered startup callbacks.
435
        init_tss_helper("main-thread",
593✔
436
            runtime_local::os_thread_type::main_thread, 0, 0, "", "", false);
437

438
        // start runtime_support services
439
        runtime_support_->run();
593✔
440
        lbt_ << "(1st stage) runtime_distributed::start: started "
593✔
441
                "runtime_support component";
442

443
#ifdef HPX_HAVE_IO_POOL
444
        // start the io pool
445
        io_pool_.run(false);
593✔
446
        lbt_ << "(1st stage) runtime_distributed::start: started the "
593✔
447
                "application "
448
                "I/O service pool";
449
#endif
450
        // start the thread manager
451
        thread_manager_->run();
593✔
452
        lbt_ << "(1st stage) runtime_distributed::start: started "
593✔
453
                "threadmanager";
454
        // }}}
455

456
        // invoke the AGAS v2 notifications
457
#if defined(HPX_HAVE_NETWORKING)
458
        agas::get_big_boot_barrier().trigger();
593✔
459
#endif
460

461
        // {{{ launch main
462
        // register the given main function with the thread manager
463
        lbt_ << "(1st stage) runtime_distributed::start: launching "
593✔
464
                "run_helper HPX thread";
465

466
        threads::thread_init_data data(
593✔
467
            hpx::bind(&runtime_distributed::run_helper, this, func,
1,186✔
468
                std::ref(result_)),
593✔
469
            "run_helper", threads::thread_priority::normal,
593✔
470
            threads::thread_schedule_hint(0), threads::thread_stacksize::large);
593✔
471

472
        this->runtime::starting();
593✔
473
        threads::thread_id_ref_type id = threads::invalid_thread_id;
593✔
474
        thread_manager_->register_thread(data, id);
593✔
475
        // }}}
476

477
        // block if required
478
        if (blocking)
593✔
479
        {
480
            return wait();    // wait for the shutdown_action to be executed
×
481
        }
482
        else
483
        {
484
            // wait for at least hpx::state::running
485
            util::yield_while(
593✔
486
                [this]() { return get_state() < hpx::state::running; },
2,013,433✔
487
                "runtime_impl::start");
488
        }
489

490
        return 0;    // return zero as we don't know the outcome of hpx_main yet
593✔
491
    }
593✔
492

493
    int runtime_distributed::start(bool blocking)
118✔
494
    {
495
        hpx::function<hpx_main_function_type> empty_main;
118✔
496
        return start(empty_main, blocking);
118✔
497
    }
118✔
498

499
    ///////////////////////////////////////////////////////////////////////////
500
    std::string locality_prefix(util::runtime_configuration const& cfg)
5,768✔
501
    {
502
        std::string localities = cfg.get_entry("hpx.localities", "1");
5,768✔
503
        std::size_t num_localities =
5,792✔
504
            util::from_string<std::size_t>(localities, 1);
5,792✔
505
        if (num_localities > 1)
5,792✔
506
        {
507
            std::string locality = cfg.get_entry("hpx.locality", "");
2,831✔
508
            if (!locality.empty())
2,831✔
509
            {
510
                locality = "locality#" + locality;
2,831✔
511
            }
2,831✔
512
            return locality;
2,831✔
513
        }
2,831✔
514
        return "";
2,961✔
515
    }
5,792✔
516

517
    ///////////////////////////////////////////////////////////////////////////
518
    void runtime_distributed::wait_helper(
593✔
519
        std::mutex& mtx, std::condition_variable& cond, bool& running)
520
    {
521
        // signal successful initialization
522
        {
523
            std::lock_guard<std::mutex> lk(mtx);
593✔
524
            running = true;
593✔
525
            cond.notify_all();
593✔
526
        }
593✔
527

528
        // prefix thread name with locality number, if needed
529
        std::string locality = locality_prefix(get_config());
593✔
530

531
        // register this thread with any possibly active Intel tool
532
        std::string thread_name(locality + "main-thread#wait_helper");
593✔
533
        HPX_ITT_THREAD_SET_NAME(thread_name.c_str());
592✔
534

535
        // set thread name as shown in Visual Studio
536
        util::set_thread_name(thread_name.c_str());
592✔
537

538
#if defined(HPX_HAVE_APEX)
539
        // not registering helper threads - for now
540
        //util::external_timer::register_thread(thread_name.c_str());
541
#endif
542

543
        // wait for termination
544
        runtime_support_->wait();
592✔
545

546
        // stop main thread pool
547
        main_pool_.stop();
592✔
548
    }
592✔
549

550
    int runtime_distributed::wait()
593✔
551
    {
552
        LRT_(info).format("runtime_distributed: about to enter wait state");
593✔
553

554
        // start the wait_helper in a separate thread
555
        std::mutex mtx;
593✔
556
        std::condition_variable cond;
593✔
557
        bool running = false;
593✔
558

559
        std::thread t(hpx::bind(&runtime_distributed::wait_helper, this,
1,186✔
560
            std::ref(mtx), std::ref(cond), std::ref(running)));
593✔
561

562
        // wait for the thread to run
563
        {
564
            std::unique_lock<std::mutex> lk(mtx);
593✔
565
            // NOLINTNEXTLINE(bugprone-infinite-loop)
566
            while (!running)    // -V776 // -V1044
1,186✔
567
                cond.wait(lk);
593✔
568
        }
592✔
569

570
        // use main thread to drive main thread pool
571
        main_pool_.thread_run(0);
592✔
572

573
        // block main thread
574
        t.join();
592✔
575

576
        LRT_(info).format("runtime_distributed: exiting wait state");
592✔
577
        return result_;
592✔
578
    }
592✔
579

580
    ///////////////////////////////////////////////////////////////////////////
581
    // First half of termination process: stop thread manager,
582
    // schedule a task managed by timer_pool to initiate second part
583
    void runtime_distributed::stop(bool blocking)
592✔
584
    {
585
        LRT_(warning).format("runtime_distributed: about to stop services");
592✔
586

587
        // flush all parcel buffers, stop buffering parcels at this point
588
        //parcel_handler_.do_background_work(true, parcelport_background_mode_all);
589

590
        // execute all on_exit functions whenever the first thread calls this
591
        this->runtime::stopping();
592✔
592

593
        // stop runtime_distributed services (threads)
594
        thread_manager_->stop(false);    // just initiate shutdown
592✔
595

596
#ifdef HPX_HAVE_APEX
597
        util::external_timer::finalize();
598
#endif
599

600
        if (threads::get_self_ptr())
592✔
601
        {
602
            // schedule task on separate thread to execute stop_helper() below
603
            // this is necessary as this function (stop()) might have been called
604
            // from a HPX thread, so it would deadlock by waiting for the thread
605
            // manager
606
            std::mutex mtx;
×
607
            std::condition_variable cond;
×
608
            std::unique_lock<std::mutex> l(mtx);
×
609

610
            std::thread t(hpx::bind(&runtime_distributed::stop_helper, this,
×
611
                blocking, std::ref(cond), std::ref(mtx)));
×
612
            cond.wait(l);
×
613

614
            t.join();
×
615
        }
×
616
        else
617
        {
618
            runtime_support_->stopped();    // re-activate shutdown HPX-thread
592✔
619
            thread_manager_->stop(blocking);    // wait for thread manager
592✔
620

621
            deinit_global_data();
592✔
622

623
            // this disables all logging from the main thread
624
            deinit_tss_helper("main-thread", 0);
592✔
625

626
            LRT_(info).format("runtime_distributed: stopped all services");
592✔
627
        }
628

629
        // stop the rest of the system
630
#if defined(HPX_HAVE_NETWORKING)
631
        parcel_handler_.stop(blocking);
592✔
632
#endif
633
#ifdef HPX_HAVE_TIMER_POOL
634
        LTM_(info).format("stop: stopping timer pool");
592✔
635
        timer_pool_.stop();
592✔
636
        if (blocking)
592✔
637
        {
638
            timer_pool_.join();
592✔
639
            timer_pool_.clear();
592✔
640
        }
592✔
641
#endif
642
#ifdef HPX_HAVE_IO_POOL
643
        LTM_(info).format("stop: stopping io pool");
592✔
644
        io_pool_.stop();
592✔
645
        if (blocking)
592✔
646
        {
647
            io_pool_.join();
592✔
648
            io_pool_.clear();
592✔
649
        }
592✔
650
#endif
651
    }
592✔
652

653
    int runtime_distributed::finalize(double shutdown_timeout)
478✔
654
    {
655
#if !defined(HPX_COMPUTE_DEVICE_CODE)
656
        //   tell main locality to start application exit, duplicated requests
657
        // will be ignored
658
        hpx::post<components::server::runtime_support::shutdown_all_action>(
478✔
659
            hpx::find_root_locality(), shutdown_timeout);
478✔
660
#else
661
        HPX_ASSERT(false);
662
        HPX_UNUSED(shutdown_timeout);
663
#endif
664
        return 0;
478✔
665
    }
×
666

667
    // Second step in termination: shut down all services.
668
    // This gets executed as a task in the timer_pool io_service and not as
669
    // a HPX thread!
670
    void runtime_distributed::stop_helper(
×
671
        bool blocking, std::condition_variable& cond, std::mutex& mtx)
672
    {
673
        // wait for thread manager to exit
674
        runtime_support_->stopped();        // re-activate shutdown HPX-thread
×
675
        thread_manager_->stop(blocking);    // wait for thread manager
×
676

677
        deinit_global_data();
×
678

679
        // this disables all logging from the main thread
680
        deinit_tss_helper("main-thread", 0);
×
681

682
        LRT_(info).format("runtime_distributed: stopped all services");
×
683

684
        std::lock_guard<std::mutex> l(mtx);
×
685
        cond.notify_all();    // we're done now
×
686
    }
×
687

688
    int runtime_distributed::suspend()
101✔
689
    {
690
        return runtime::suspend();
101✔
691
    }
692

693
    int runtime_distributed::resume()
101✔
694
    {
695
        return runtime::resume();
101✔
696
    }
697

698
    ///////////////////////////////////////////////////////////////////////////
699
    bool runtime_distributed::report_error(
2✔
700
        std::size_t num_thread, std::exception_ptr const& e, bool terminate_all)
701
    {
702
        // call thread-specific user-supplied on_error handler
703
        bool report_exception = true;
2✔
704
        if (on_error_func_)
2✔
705
        {
706
            report_exception = on_error_func_(num_thread, e);
×
707
        }
×
708

709
        // Early and late exceptions, errors outside of HPX-threads
710
        if (!threads::get_self_ptr() ||
2✔
711
            !threads::threadmanager_is(hpx::state::running))
2✔
712
        {
713
            // report the error to the local console
714
            if (report_exception)
×
715
            {
716
                detail::report_exception_and_continue(e);
×
717
            }
×
718

719
            // store the exception to be able to rethrow it later
720
            {
721
                std::lock_guard<std::mutex> l(mtx_);
×
722
                exception_ = e;
×
723
            }
×
724

725
            // initiate stopping the runtime system
726
            runtime_support_->notify_waiting_main();
×
727
            stop(false);
×
728

729
            return report_exception;
×
730
        }
731

732
        // The components::console_error_sink is only applied at the console,
733
        // so the default error sink never gets called on the locality, meaning
734
        // that the user never sees errors that kill the system before the
735
        // error parcel gets sent out. So, before we try to send the error
736
        // parcel (which might cause a double fault), print local diagnostics.
737
        components::server::console_error_sink(e);
2✔
738

739
        // Report this error to the console.
740
        naming::gid_type console_id;
2✔
741
        if (agas_client_.get_console_locality(console_id))
2✔
742
        {
743
            if (agas_client_.get_local_locality() != console_id)
2✔
744
            {
745
                components::console_error_sink(
×
746
                    hpx::id_type(
×
747
                        console_id, hpx::id_type::management_type::unmanaged),
748
                    e);
×
749
            }
×
750
        }
2✔
751

752
        if (terminate_all)
2✔
753
        {
754
            components::stubs::runtime_support::terminate_all(
×
755
                naming::get_id_from_locality_id(agas::booststrap_prefix));
×
756
        }
×
757

758
        return report_exception;
2✔
759
    }
2✔
760

761
    bool runtime_distributed::report_error(
2✔
762
        std::exception_ptr const& e, bool terminate_all)
763
    {
764
        return report_error(hpx::get_worker_thread_num(), e, terminate_all);
2✔
765
    }
766

767
    ///////////////////////////////////////////////////////////////////////////
768
    int runtime_distributed::run(
370✔
769
        hpx::function<hpx_main_function_type> const& func)
770
    {
771
        // start the main thread function
772
        start(func);
370✔
773

774
        // now wait for everything to finish
775
        wait();
370✔
776
        stop();
370✔
777

778
#if defined(HPX_HAVE_NETWORKING)
779
        parcel_handler_.stop();    // stops parcelport for sure
370✔
780
#endif
781

782
        rethrow_exception();
370✔
783
        return result_;
370✔
784
    }
785

786
    ///////////////////////////////////////////////////////////////////////////
787
    int runtime_distributed::run()
117✔
788
    {
789
        // start the main thread function
790
        start();
117✔
791

792
        // now wait for everything to finish
793
        int result = wait();
117✔
794
        stop();
117✔
795

796
#if defined(HPX_HAVE_NETWORKING)
797
        parcel_handler_.stop();    // stops parcelport for sure
117✔
798
#endif
799

800
        rethrow_exception();
117✔
801
        return result;
117✔
802
    }
803

804
    bool runtime_distributed::is_networking_enabled()
1,188✔
805
    {
806
#if defined(HPX_HAVE_NETWORKING)
807
        return get_config().enable_networking();
1,188✔
808
#else
809
        return false;
810
#endif
811
    }
812

813
    performance_counters::registry& runtime_distributed::get_counter_registry()
591✔
814
    {
815
        return performance_counters::registry::instance();
591✔
816
    }
817

818
    performance_counters::registry const&
819
    runtime_distributed::get_counter_registry() const
×
820
    {
821
        return performance_counters::registry::instance();
×
822
    }
823

824
    ///////////////////////////////////////////////////////////////////////////
825
    void runtime_distributed::register_query_counters(
×
826
        std::shared_ptr<util::query_counters> const& active_counters)
827
    {
828
        active_counters_ = active_counters;
×
829
    }
×
830

831
    void runtime_distributed::start_active_counters(error_code& ec)
×
832
    {
833
        if (active_counters_.get())
×
834
            active_counters_->start_counters(ec);
×
835
    }
×
836

837
    void runtime_distributed::stop_active_counters(error_code& ec)
×
838
    {
839
        if (active_counters_.get())
×
840
            active_counters_->stop_counters(ec);
×
841
    }
×
842

843
    void runtime_distributed::reset_active_counters(error_code& ec)
×
844
    {
845
        if (active_counters_.get())
×
846
            active_counters_->reset_counters(ec);
×
847
    }
×
848

849
    void runtime_distributed::reinit_active_counters(bool reset, error_code& ec)
×
850
    {
851
        if (active_counters_.get())
×
852
            active_counters_->reinit_counters(reset, ec);
×
853
    }
×
854

855
    void runtime_distributed::evaluate_active_counters(
×
856
        bool reset, char const* description, error_code& ec)
857
    {
858
        if (active_counters_.get())
×
859
            active_counters_->evaluate_counters(reset, description, true, ec);
×
860
    }
×
861

862
    void runtime_distributed::stop_evaluating_counters(bool terminate)
451✔
863
    {
864
        if (active_counters_.get())
451✔
865
            active_counters_->stop_evaluating_counters(terminate);
×
866
    }
451✔
867

868
    naming::resolver_client& runtime_distributed::get_agas_client()
59,610,782✔
869
    {
870
        return agas_client_;
59,612,258✔
871
    }
872

873
#if defined(HPX_HAVE_NETWORKING)
874
    parcelset::parcelhandler const& runtime_distributed::get_parcel_handler()
×
875
        const
876
    {
877
        return parcel_handler_;
×
878
    }
879

880
    parcelset::parcelhandler& runtime_distributed::get_parcel_handler()
80,356,881✔
881
    {
882
        return parcel_handler_;
80,367,659✔
883
    }
884
#endif
885

886
    hpx::threads::threadmanager& runtime_distributed::get_thread_manager()
3,391,846✔
887
    {
888
        return *thread_manager_;
3,391,855✔
889
    }
890

891
    applier::applier& runtime_distributed::get_applier()
7,386✔
892
    {
893
        return applier_;
7,386✔
894
    }
895

896
#if defined(HPX_HAVE_NETWORKING)
897
    parcelset::endpoints_type const& runtime_distributed::endpoints() const
2,173✔
898
    {
899
        return parcel_handler_.endpoints();
2,173✔
900
    }
901
#endif
902

903
    std::string runtime_distributed::here() const
2,172✔
904
    {
905
#if defined(HPX_HAVE_NETWORKING)
906
        std::ostringstream strm;
2,172✔
907
        strm << endpoints();
2,172✔
908
        return strm.str();
2,173✔
909
#else
910
        return "console";
911
#endif
912
    }
2,173✔
913

914
    naming::address_type runtime_distributed::get_runtime_support_lva() const
459,312✔
915
    {
916
        return runtime_support_.get();
459,312✔
917
    }
918

919
    naming::gid_type get_next_id(std::size_t count = 1);
920

921
    void runtime_distributed::init_id_pool_range()
593✔
922
    {
923
        naming::gid_type lower, upper;
593✔
924
        naming::get_agas_client().get_id_range(
593✔
925
            HPX_INITIAL_GID_RANGE, lower, upper);
926
        return id_pool_.set_range(lower, upper);
593✔
927
    }
928

929
    util::unique_id_ranges& runtime_distributed::get_id_pool()
×
930
    {
931
        return id_pool_;
×
932
    }
933

934
    /// \brief Register all performance counter types related to this runtime
935
    ///        instance
936
    void runtime_distributed::register_counter_types()
593✔
937
    {
938
        performance_counters::generic_counter_type_data
939
            statistic_counter_types[] =
940
        {    // averaging counter
8,302✔
941
            {"/statistics/average",
593✔
942
                performance_counters::counter_type::aggregating,
943
                "returns the averaged value of its base counter over "
593✔
944
                "an arbitrary time line; pass required base counter as the "
945
                "instance "
946
                "name: /statistics{<base_counter_name>}/average",
947
                HPX_PERFORMANCE_COUNTER_V1,
948
                &performance_counters::detail::statistics_counter_creator,
593✔
949
                &performance_counters::default_counter_discoverer, ""},
593✔
950

951
            // stddev counter
952
            {"/statistics/stddev",
593✔
953
                performance_counters::counter_type::aggregating,
954
                "returns the standard deviation value of its base counter "
593✔
955
                "over "
956
                "an arbitrary time line; pass required base counter as the "
957
                "instance "
958
                "name: /statistics{<base_counter_name>}/stddev",
959
                HPX_PERFORMANCE_COUNTER_V1,
960
                &performance_counters::detail::statistics_counter_creator,
593✔
961
                &performance_counters::default_counter_discoverer, ""},
593✔
962

963
            // rolling_averaging counter
964
            {"/statistics/rolling_average",
593✔
965
                performance_counters::counter_type::aggregating,
966
                "returns the rolling average value of its base counter "
593✔
967
                "over "
968
                "an arbitrary time line; pass required base counter as the "
969
                "instance "
970
                "name: /statistics{<base_counter_name>}/rolling_averaging",
971
                HPX_PERFORMANCE_COUNTER_V1,
972
                &performance_counters::detail::statistics_counter_creator,
593✔
973
                &performance_counters::default_counter_discoverer, ""},
593✔
974

975
            // rolling stddev counter
976
            {"/statistics/rolling_stddev",
593✔
977
                performance_counters::counter_type::aggregating,
978
                "returns the rolling standard deviation value of its base "
593✔
979
                "counter over "
980
                "an arbitrary time line; pass required base counter as the "
981
                "instance "
982
                "name: /statistics{<base_counter_name>}/rolling_stddev",
983
                HPX_PERFORMANCE_COUNTER_V1,
984
                &performance_counters::detail::statistics_counter_creator,
593✔
985
                &performance_counters::default_counter_discoverer, ""},
593✔
986

987
            // median counter
988
            {"/statistics/median",
593✔
989
                performance_counters::counter_type::aggregating,
990
                "returns the median value of its base counter over "
593✔
991
                "an arbitrary time line; pass required base counter as the "
992
                "instance "
993
                "name: /statistics{<base_counter_name>}/median",
994
                HPX_PERFORMANCE_COUNTER_V1,
995
                &performance_counters::detail::statistics_counter_creator,
593✔
996
                &performance_counters::default_counter_discoverer, ""},
593✔
997

998
            // max counter
999
            {"/statistics/max", performance_counters::counter_type::aggregating,
593✔
1000
                "returns the maximum value of its base counter over "
593✔
1001
                "an arbitrary time line; pass required base counter as the "
1002
                "instance "
1003
                "name: /statistics{<base_counter_name>}/max",
1004
                HPX_PERFORMANCE_COUNTER_V1,
1005
                &performance_counters::detail::statistics_counter_creator,
593✔
1006
                &performance_counters::default_counter_discoverer, ""},
593✔
1007

1008
            // min counter
1009
            {"/statistics/min", performance_counters::counter_type::aggregating,
593✔
1010
                "returns the minimum value of its base counter over "
593✔
1011
                "an arbitrary time line; pass required base counter as the "
1012
                "instance "
1013
                "name: /statistics{<base_counter_name>}/min",
1014
                HPX_PERFORMANCE_COUNTER_V1,
1015
                &performance_counters::detail::statistics_counter_creator,
593✔
1016
                &performance_counters::default_counter_discoverer, ""},
593✔
1017

1018
            // rolling max counter
1019
            {"/statistics/rolling_max",
593✔
1020
                performance_counters::counter_type::aggregating,
1021
                "returns the rolling maximum value of its base counter "
593✔
1022
                "over "
1023
                "an arbitrary time line; pass required base counter as the "
1024
                "instance "
1025
                "name: /statistics{<base_counter_name>}/rolling_max",
1026
                HPX_PERFORMANCE_COUNTER_V1,
1027
                &performance_counters::detail::statistics_counter_creator,
593✔
1028
                &performance_counters::default_counter_discoverer, ""},
593✔
1029

1030
            // rolling min counter
1031
            {"/statistics/rolling_min",
593✔
1032
                performance_counters::counter_type::aggregating,
1033
                "returns the rolling minimum value of its base counter "
593✔
1034
                "over "
1035
                "an arbitrary time line; pass required base counter as the "
1036
                "instance "
1037
                "name: /statistics{<base_counter_name>}/rolling_min",
1038
                HPX_PERFORMANCE_COUNTER_V1,
1039
                &performance_counters::detail::statistics_counter_creator,
593✔
1040
                &performance_counters::default_counter_discoverer, ""},
593✔
1041

1042
            // uptime counters
1043
            {
593✔
1044
                "/runtime/uptime",
593✔
1045
                performance_counters::counter_type::elapsed_time,
1046
                "returns the up time of the runtime instance for the "
593✔
1047
                "referenced "
1048
                "locality",
1049
                HPX_PERFORMANCE_COUNTER_V1,
1050
                &performance_counters::detail::uptime_counter_creator,
593✔
1051
                &performance_counters::locality_counter_discoverer,
593✔
1052
                "s"    // unit of measure is seconds
593✔
1053
            },
1054

1055
            // component instance counters
1056
            {"/runtime/count/component",
593✔
1057
                performance_counters::counter_type::raw,
1058
                "returns the number of component instances currently alive "
593✔
1059
                "on "
1060
                "this locality (the component type has to be specified as "
1061
                "the "
1062
                "counter parameter)",
1063
                HPX_PERFORMANCE_COUNTER_V1,
1064
                &performance_counters::detail::
593✔
1065
                    component_instance_counter_creator,
1066
                &performance_counters::locality_counter_discoverer, ""},
593✔
1067

1068
            // action invocation counters
1069
            {"/runtime/count/action-invocation",
593✔
1070
                performance_counters::counter_type::raw,
1071
                "returns the number of (local) invocations of a specific "
593✔
1072
                "action "
1073
                "on this locality (the action type has to be specified as "
1074
                "the "
1075
                "counter parameter)",
1076
                HPX_PERFORMANCE_COUNTER_V1,
1077
                &performance_counters::local_action_invocation_counter_creator,
593✔
1078
                &performance_counters::
593✔
1079
                    local_action_invocation_counter_discoverer,
1080
                ""},
593✔
1081

1082
#if defined(HPX_HAVE_NETWORKING)
1083
            {"/runtime/count/remote-action-invocation",
593✔
1084
                performance_counters::counter_type::raw,
1085
                "returns the number of (remote) invocations of a specific "
593✔
1086
                "action "
1087
                "on this locality (the action type has to be specified as "
1088
                "the "
1089
                "counter parameter)",
1090
                HPX_PERFORMANCE_COUNTER_V1,
1091
                &performance_counters::remote_action_invocation_counter_creator,
593✔
1092
                &performance_counters::
593✔
1093
                    remote_action_invocation_counter_discoverer,
1094
                ""}
593✔
1095
#endif
1096
        };
1097
        performance_counters::install_counter_types(statistic_counter_types,
593✔
1098
            sizeof(statistic_counter_types) /
1099
                sizeof(statistic_counter_types[0]));
1100

1101
        performance_counters::generic_counter_type_data
1102
            arithmetic_counter_types[] = {
6,523✔
1103
                // adding counter
1104
                {"/arithmetics/add",
593✔
1105
                    performance_counters::counter_type::aggregating,
1106
                    "returns the sum of the values of the specified base "
593✔
1107
                    "counters; "
1108
                    "pass required base counters as the parameters: "
1109
                    "/arithmetics/"
1110
                    "add@<base_counter_name1>,<base_counter_name2>",
1111
                    HPX_PERFORMANCE_COUNTER_V1,
1112
                    &performance_counters::detail::arithmetics_counter_creator,
593✔
1113
                    &performance_counters::default_counter_discoverer, ""},
593✔
1114
                // minus counter
1115
                {"/arithmetics/subtract",
593✔
1116
                    performance_counters::counter_type::aggregating,
1117
                    "returns the difference of the values of the specified "
593✔
1118
                    "base counters; "
1119
                    "pass the required base counters as the parameters: "
1120
                    "/arithmetics/"
1121
                    "subtract@<base_counter_name1>,<base_counter_name2>",
1122
                    HPX_PERFORMANCE_COUNTER_V1,
1123
                    &performance_counters::detail::arithmetics_counter_creator,
593✔
1124
                    &performance_counters::default_counter_discoverer, ""},
593✔
1125
                // multiply counter
1126
                {"/arithmetics/multiply",
593✔
1127
                    performance_counters::counter_type::aggregating,
1128
                    "returns the product of the values of the specified "
593✔
1129
                    "base "
1130
                    "counters; "
1131
                    "pass the required base counters as the parameters: "
1132
                    "/arithmetics/"
1133
                    "multiply@<base_counter_name1>,<base_counter_name2>",
1134
                    HPX_PERFORMANCE_COUNTER_V1,
1135
                    &performance_counters::detail::arithmetics_counter_creator,
593✔
1136
                    &performance_counters::default_counter_discoverer, ""},
593✔
1137
                // divide counter
1138
                {"/arithmetics/divide",
593✔
1139
                    performance_counters::counter_type::aggregating,
1140
                    "returns the result of division of the values of the "
593✔
1141
                    "specified "
1142
                    "base counters; pass the required base counters as the "
1143
                    "parameters: "
1144
                    "/arithmetics/"
1145
                    "divide@<base_counter_name1>,<base_counter_name2>",
1146
                    HPX_PERFORMANCE_COUNTER_V1,
1147
                    &performance_counters::detail::arithmetics_counter_creator,
593✔
1148
                    &performance_counters::default_counter_discoverer, ""},
593✔
1149

1150
                // arithmetics mean counter
1151
                {"/arithmetics/mean",
593✔
1152
                    performance_counters::counter_type::aggregating,
1153
                    "returns the average value of all values of the "
593✔
1154
                    "specified "
1155
                    "base counters; pass the required base counters as the "
1156
                    "parameters: "
1157
                    "/arithmetics/"
1158
                    "mean@<base_counter_name1>,<base_counter_name2>",
1159
                    HPX_PERFORMANCE_COUNTER_V1,
1160
                    &performance_counters::detail::
593✔
1161
                        arithmetics_counter_extended_creator,
1162
                    &performance_counters::default_counter_discoverer, ""},
593✔
1163
                // arithmetics variance counter
1164
                {"/arithmetics/variance",
593✔
1165
                    performance_counters::counter_type::aggregating,
1166
                    "returns the standard deviation of all values of the "
593✔
1167
                    "specified "
1168
                    "base counters; pass the required base counters as the "
1169
                    "parameters: "
1170
                    "/arithmetics/"
1171
                    "variance@<base_counter_name1>,<base_counter_name2>",
1172
                    HPX_PERFORMANCE_COUNTER_V1,
1173
                    &performance_counters::detail::
593✔
1174
                        arithmetics_counter_extended_creator,
1175
                    &performance_counters::default_counter_discoverer, ""},
593✔
1176
                // arithmetics median counter
1177
                {"/arithmetics/median",
593✔
1178
                    performance_counters::counter_type::aggregating,
1179
                    "returns the median of all values of the specified "
593✔
1180
                    "base counters; pass the required base counters as the "
1181
                    "parameters: "
1182
                    "/arithmetics/"
1183
                    "median@<base_counter_name1>,<base_counter_name2>",
1184
                    HPX_PERFORMANCE_COUNTER_V1,
1185
                    &performance_counters::detail::
593✔
1186
                        arithmetics_counter_extended_creator,
1187
                    &performance_counters::default_counter_discoverer, ""},
593✔
1188
                // arithmetics min counter
1189
                {"/arithmetics/min",
593✔
1190
                    performance_counters::counter_type::aggregating,
1191
                    "returns the minimum value of all values of the "
593✔
1192
                    "specified "
1193
                    "base counters; pass the required base counters as the "
1194
                    "parameters: "
1195
                    "/arithmetics/"
1196
                    "min@<base_counter_name1>,<base_counter_name2>",
1197
                    HPX_PERFORMANCE_COUNTER_V1,
1198
                    &performance_counters::detail::
593✔
1199
                        arithmetics_counter_extended_creator,
1200
                    &performance_counters::default_counter_discoverer, ""},
593✔
1201
                // arithmetics max counter
1202
                {"/arithmetics/max",
593✔
1203
                    performance_counters::counter_type::aggregating,
1204
                    "returns the maximum value of all values of the "
593✔
1205
                    "specified "
1206
                    "base counters; pass the required base counters as the "
1207
                    "parameters: "
1208
                    "/arithmetics/"
1209
                    "max@<base_counter_name1>,<base_counter_name2>",
1210
                    HPX_PERFORMANCE_COUNTER_V1,
1211
                    &performance_counters::detail::
593✔
1212
                        arithmetics_counter_extended_creator,
1213
                    &performance_counters::default_counter_discoverer, ""},
593✔
1214
                // arithmetics count counter
1215
                {"/arithmetics/count",
593✔
1216
                    performance_counters::counter_type::aggregating,
1217
                    "returns the count value of all values of the "
593✔
1218
                    "specified "
1219
                    "base counters; pass the required base counters as the "
1220
                    "parameters: "
1221
                    "/arithmetics/"
1222
                    "count@<base_counter_name1>,<base_counter_name2>",
1223
                    HPX_PERFORMANCE_COUNTER_V1,
1224
                    &performance_counters::detail::
593✔
1225
                        arithmetics_counter_extended_creator,
1226
                    &performance_counters::default_counter_discoverer, ""},
593✔
1227
            };
1228
        performance_counters::install_counter_types(arithmetic_counter_types,
593✔
1229
            sizeof(arithmetic_counter_types) /
1230
                sizeof(arithmetic_counter_types[0]));
1231
    }
13,046✔
1232

1233
    ///////////////////////////////////////////////////////////////////////////
1234
    void start_active_counters(error_code& ec)
×
1235
    {
1236
        runtime_distributed* rtd = get_runtime_distributed_ptr();
×
1237
        if (nullptr != rtd)
×
1238
        {
1239
            rtd->start_active_counters(ec);
×
1240
        }
×
1241
        else
1242
        {
1243
            HPX_THROWS_IF(ec, hpx::error::invalid_status,
×
1244
                "start_active_counters",
1245
                "the runtime system is not available at this time");
1246
        }
1247
    }
×
1248

1249
    void stop_active_counters(error_code& ec)
×
1250
    {
1251
        runtime_distributed* rtd = get_runtime_distributed_ptr();
×
1252
        if (nullptr != rtd)
×
1253
        {
1254
            rtd->stop_active_counters(ec);
×
1255
        }
×
1256
        else
1257
        {
1258
            HPX_THROWS_IF(ec, hpx::error::invalid_status,
×
1259
                "stop_active_counters",
1260
                "the runtime system is not available at this time");
1261
        }
1262
    }
×
1263

1264
    void reset_active_counters(error_code& ec)
×
1265
    {
1266
        runtime_distributed* rtd = get_runtime_distributed_ptr();
×
1267
        if (nullptr != rtd)
×
1268
        {
1269
            rtd->reset_active_counters(ec);
×
1270
        }
×
1271
        else
1272
        {
1273
            HPX_THROWS_IF(ec, hpx::error::invalid_status,
×
1274
                "reset_active_counters",
1275
                "the runtime system is not available at this time");
1276
        }
1277
    }
×
1278

1279
    void reinit_active_counters(bool reset, error_code& ec)
×
1280
    {
1281
        runtime_distributed* rtd = get_runtime_distributed_ptr();
×
1282
        if (nullptr != rtd)
×
1283
        {
1284
            rtd->reinit_active_counters(reset, ec);
×
1285
        }
×
1286
        else
1287
        {
1288
            HPX_THROWS_IF(ec, hpx::error::invalid_status,
×
1289
                "reinit_active_counters",
1290
                "the runtime system is not available at this time");
1291
        }
1292
    }
×
1293

1294
    void evaluate_active_counters(
×
1295
        bool reset, char const* description, error_code& ec)
1296
    {
1297
        runtime_distributed* rtd = get_runtime_distributed_ptr();
×
1298
        if (nullptr != rtd)
×
1299
        {
1300
            rtd->evaluate_active_counters(reset, description, ec);
×
1301
        }
×
1302
        else
1303
        {
1304
            HPX_THROWS_IF(ec, hpx::error::invalid_status,
×
1305
                "evaluate_active_counters",
1306
                "the runtime system is not available at this time");
1307
        }
1308
    }
×
1309

1310
    // helper function to stop evaluating counters during shutdown
1311
    void stop_evaluating_counters(bool terminate)
451✔
1312
    {
1313
        runtime_distributed* rtd = get_runtime_distributed_ptr();
451✔
1314
        if (nullptr != rtd)
451✔
1315
            rtd->stop_evaluating_counters(terminate);
451✔
1316
    }
451✔
1317

1318
    ///////////////////////////////////////////////////////////////////////////
1319
    threads::policies::callback_notifier
1320
    runtime_distributed::get_notification_policy(
2,372✔
1321
        char const* prefix, runtime_local::os_thread_type type)
1322
    {
1323
        typedef bool (runtime_distributed::*report_error_t)(
1324
            std::size_t, std::exception_ptr const&, bool);
1325

1326
        using placeholders::_1;
1327
        using placeholders::_2;
1328
        using placeholders::_3;
1329
        using placeholders::_4;
1330

1331
        notification_policy_type notifier;
2,372✔
1332

1333
        notifier.add_on_start_thread_callback(
2,372✔
1334
            hpx::bind(&runtime_distributed::init_tss_helper, this, prefix, type,
4,744✔
1335
                _1, _2, _3, _4, false));
2,372✔
1336
        notifier.add_on_stop_thread_callback(hpx::bind(
2,372✔
1337
            &runtime_distributed::deinit_tss_helper, this, prefix, _1));
2,372✔
1338
        notifier.set_on_error_callback(hpx::bind(
2,372✔
1339
            static_cast<report_error_t>(&runtime_distributed::report_error),
2,372✔
1340
            this, _1, _2, true));
2,372✔
1341

1342
        return notifier;
2,372✔
1343
    }
2,372✔
1344

1345
    void runtime_distributed::init_tss_helper(char const* context,
5,166✔
1346
        runtime_local::os_thread_type type, std::size_t local_thread_num,
1347
        std::size_t global_thread_num, char const* pool_name,
1348
        char const* postfix, bool service_thread)
1349
    {
1350
        // prefix thread name with locality number, if needed
1351
        std::string locality = locality_prefix(get_config());
5,196✔
1352

1353
        error_code ec(throwmode::lightweight);
5,196✔
1354
        return init_tss_ex(locality, context, type, local_thread_num,
10,392✔
1355
            global_thread_num, pool_name, postfix, service_thread, ec);
5,196✔
1356
    }
5,196✔
1357

1358
    void runtime_distributed::init_tss_ex(std::string const& locality,
5,199✔
1359
        char const* context, runtime_local::os_thread_type type,
1360
        std::size_t local_thread_num, std::size_t global_thread_num,
1361
        char const* pool_name, char const* postfix, bool service_thread,
1362
        error_code& ec)
1363
    {
1364
        // set the thread's name, if it's not already set
1365
        HPX_ASSERT(detail::thread_name().empty());
5,199✔
1366

1367
        std::string fullname = std::string(locality);
5,199✔
1368
        if (!locality.empty())
5,199✔
1369
            fullname += "/";
2,551✔
1370
        fullname += context;
5,199✔
1371
        if (postfix && *postfix)
5,199✔
1372
            fullname += postfix;
566✔
1373
        fullname += "#" + std::to_string(global_thread_num);
5,199✔
1374
        detail::thread_name() = HPX_MOVE(fullname);
5,199✔
1375

1376
        char const* name = detail::thread_name().c_str();
5,199✔
1377

1378
        // initialize thread mapping for external libraries (i.e. PAPI)
1379
        thread_support_->register_thread(name, type);
5,199✔
1380

1381
        // register this thread with any possibly active Intel tool
1382
        HPX_ITT_THREAD_SET_NAME(name);
5,199✔
1383

1384
        // set thread name as shown in Visual Studio
1385
        util::set_thread_name(name);
5,199✔
1386

1387
#if defined(HPX_HAVE_APEX)
1388
        if (std::strstr(name, "worker") != nullptr)
1389
            util::external_timer::register_thread(name);
1390
#endif
1391

1392
        // call thread-specific user-supplied on_start handler
1393
        if (on_start_func_)
5,199✔
1394
        {
1395
            on_start_func_(
18✔
1396
                local_thread_num, global_thread_num, pool_name, context);
9✔
1397
        }
9✔
1398

1399
        // if this is a service thread, set its service affinity
1400
        if (service_thread)
5,199✔
1401
        {
1402
            // FIXME: We don't set the affinity of the service threads on BG/Q,
1403
            // as this is causing a hang (needs to be investigated)
1404
#if !defined(__bgq__)
1405
            threads::mask_cref_type used_processing_units =
3✔
1406
                thread_manager_->get_used_processing_units();
3✔
1407

1408
            // --hpx:bind=none  should disable all affinity definitions
1409
            if (threads::any(used_processing_units))
3✔
1410
            {
1411
                this->topology_.set_thread_affinity_mask(
3✔
1412
                    this->topology_.get_service_affinity_mask(
6✔
1413
                        used_processing_units),
3✔
1414
                    ec);
3✔
1415

1416
                // comment this out for now as on CircleCI this is causing unending grief
1417
                //if (ec)
1418
                //{
1419
                //    HPX_THROW_EXCEPTION(hpx::error::kernel_error,
1420
                //        "runtime_distributed::init_tss_ex",
1421
                //        "failed to set thread affinity mask ({}) for service "
1422
                //        "thread: {}",
1423
                //        hpx::threads::to_string(used_processing_units),
1424
                //        detail::thread_name());
1425
                //}
1426
            }
3✔
1427
#endif
1428
        }
3✔
1429
    }
5,199✔
1430

1431
    void runtime_distributed::deinit_tss_helper(
5,139✔
1432
        char const* context, std::size_t global_thread_num)
1433
    {
1434
        threads::reset_continuation_recursion_count();
5,127✔
1435

1436
        // call thread-specific user-supplied on_stop handler
1437
        if (on_stop_func_)
5,127✔
1438
        {
1439
            on_stop_func_(global_thread_num, global_thread_num, "", context);
9✔
1440
        }
9✔
1441

1442
        // reset PAPI support
1443
        thread_support_->unregister_thread();
5,127✔
1444

1445
        // reset thread local storage
1446
        detail::thread_name().clear();
5,127✔
1447
    }
5,127✔
1448

1449
    naming::gid_type runtime_distributed::get_next_id(std::size_t count)
1,062✔
1450
    {
1451
        return id_pool_.get_id(count);
1,062✔
1452
    }
1453

1454
    void runtime_distributed::add_pre_startup_function(startup_function_type f)
×
1455
    {
1456
        runtime_support_->add_pre_startup_function(HPX_MOVE(f));
×
1457
    }
×
1458

1459
    void runtime_distributed::add_startup_function(startup_function_type f)
585✔
1460
    {
1461
        runtime_support_->add_startup_function(HPX_MOVE(f));
585✔
1462
    }
585✔
1463

1464
    void runtime_distributed::add_pre_shutdown_function(
595✔
1465
        shutdown_function_type f)
1466
    {
1467
        runtime_support_->add_pre_shutdown_function(HPX_MOVE(f));
595✔
1468
    }
595✔
1469

1470
    void runtime_distributed::add_shutdown_function(shutdown_function_type f)
73,168✔
1471
    {
1472
        runtime_support_->add_shutdown_function(HPX_MOVE(f));
73,168✔
1473
    }
73,168✔
1474

1475
    hpx::util::io_service_pool* runtime_distributed::get_thread_pool(
15,025✔
1476
        char const* name)
1477
    {
1478
        HPX_ASSERT(name != nullptr);
15,025✔
1479
#ifdef HPX_HAVE_IO_POOL
1480
        if (0 == std::strncmp(name, "io", 2))
15,025✔
1481
            return &io_pool_;
5,506✔
1482
#endif
1483
#if defined(HPX_HAVE_NETWORKING)
1484
        if (0 == std::strncmp(name, "parcel", 6))
9,519✔
1485
            return parcel_handler_.get_thread_pool(name);
×
1486
#endif
1487
#ifdef HPX_HAVE_TIMER_POOL
1488
        if (0 == std::strncmp(name, "timer", 5))
9,519✔
1489
            return &timer_pool_;
9,519✔
1490
#endif
1491
        if (0 == std::strncmp(name, "main", 4))    //-V112
×
1492
            return &main_pool_;
×
1493

1494
        HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
1495
            "runtime_distributed::get_thread_pool",
1496
            "unknown thread pool requested: {}", name);
1497
        return nullptr;
1498
    }
15,025✔
1499

1500
    /// Register an external OS-thread with HPX
1501
    bool runtime_distributed::register_thread(char const* name,
3✔
1502
        std::size_t global_thread_num, bool service_thread, error_code& ec)
1503
    {
1504
        // prefix thread name with locality number, if needed
1505
        std::string locality = locality_prefix(get_config());
3✔
1506

1507
        std::string thread_name(name);
3✔
1508
        thread_name += "-thread";
3✔
1509

1510
        init_tss_ex(locality, thread_name.c_str(),
6✔
1511
            runtime_local::os_thread_type::custom_thread, global_thread_num,
3✔
1512
            global_thread_num, "", nullptr, service_thread, ec);
3✔
1513

1514
        return !ec ? true : false;
3✔
1515
    }
3✔
1516

1517
#if defined(HPX_HAVE_NETWORKING)
1518
    void runtime_distributed::register_message_handler(
20,171✔
1519
        char const* message_handler_type, char const* action, error_code& ec)
1520
    {
1521
        return runtime_support_->register_message_handler(
40,342✔
1522
            message_handler_type, action, ec);
20,171✔
1523
    }
1524

1525
    parcelset::policies::message_handler*
1526
    runtime_distributed::create_message_handler(
285✔
1527
        char const* message_handler_type, char const* action,
1528
        parcelset::parcelport* pp, std::size_t num_messages,
1529
        std::size_t interval, error_code& ec)
1530
    {
1531
        return runtime_support_->create_message_handler(
570✔
1532
            message_handler_type, action, pp, num_messages, interval, ec);
285✔
1533
    }
1534

1535
    serialization::binary_filter* runtime_distributed::create_binary_filter(
×
1536
        char const* binary_filter_type, bool compress,
1537
        serialization::binary_filter* next_filter, error_code& ec)
1538
    {
1539
        return runtime_support_->create_binary_filter(
×
1540
            binary_filter_type, compress, next_filter, ec);
×
1541
    }
1542
#endif
1543

1544
    std::uint32_t runtime_distributed::get_locality_id(error_code& ec) const
31,407,003✔
1545
    {
1546
        return agas::get_locality_id(ec);
31,407,173✔
1547
    }
1548

1549
    std::size_t runtime_distributed::get_num_worker_threads() const
11✔
1550
    {
1551
        error_code ec(throwmode::lightweight);
11✔
1552
        return static_cast<std::size_t>(
1553
            agas_client_.get_num_overall_threads(ec));
11✔
1554
    }
11✔
1555

1556
    std::uint32_t runtime_distributed::get_num_localities(
310✔
1557
        hpx::launch::sync_policy, error_code& ec) const
1558
    {
1559
        return agas_client_.get_num_localities(ec);
310✔
1560
    }
1561

1562
    std::uint32_t runtime_distributed::get_initial_num_localities() const
67,866✔
1563
    {
1564
        return get_config().get_num_localities();
67,866✔
1565
    }
1566

1567
    hpx::future<std::uint32_t> runtime_distributed::get_num_localities() const
9✔
1568
    {
1569
        return agas_client_.get_num_localities_async();
9✔
1570
    }
1571

1572
    std::string runtime_distributed::get_locality_name() const
×
1573
    {
1574
#if defined(HPX_HAVE_NETWORKING)
1575
        return get_parcel_handler().get_locality_name();
×
1576
#else
1577
        return "<unknown>";
1578
#endif
1579
    }
1580

1581
    std::uint32_t runtime_distributed::get_num_localities(
×
1582
        hpx::launch::sync_policy, components::component_type type,
1583
        error_code& ec) const
1584
    {
1585
        return agas_client_.get_num_localities(type, ec);
×
1586
    }
1587

1588
    hpx::future<std::uint32_t> runtime_distributed::get_num_localities(
×
1589
        components::component_type type) const
1590
    {
1591
        return agas_client_.get_num_localities_async(type);
×
1592
    }
1593

1594
    std::uint32_t runtime_distributed::assign_cores(
592✔
1595
        std::string const& locality_basename, std::uint32_t cores_needed)
1596
    {
1597
        std::lock_guard<std::mutex> l(mtx_);
592✔
1598

1599
        used_cores_map_type::iterator it =
1600
            used_cores_map_.find(locality_basename);
592✔
1601
        if (it == used_cores_map_.end())
592✔
1602
        {
1603
            used_cores_map_.insert(used_cores_map_type::value_type(
902✔
1604
                locality_basename, cores_needed));
451✔
1605
            return 0;
451✔
1606
        }
1607

1608
        std::uint32_t current = (*it).second;
141✔
1609
        (*it).second += cores_needed;
141✔
1610
        return current;
141✔
1611
    }
592✔
1612

1613
    std::uint32_t runtime_distributed::assign_cores()
735✔
1614
    {
1615
        // adjust thread assignments to allow for more than one locality per
1616
        // node
1617
        std::size_t first_core =
735✔
1618
            static_cast<std::size_t>(this->get_config().get_first_used_core());
735✔
1619
        std::size_t cores_needed =
735✔
1620
            hpx::resource::get_partitioner().assign_cores(first_core);
735✔
1621

1622
        return static_cast<std::uint32_t>(cores_needed);
735✔
1623
    }
1624

1625
    ///////////////////////////////////////////////////////////////////////////
1626
    void runtime_distributed::default_errorsink(std::string const& msg)
2✔
1627
    {
1628
        // log the exception information in any case
1629
        LERR_(always).format("default_errorsink: unhandled exception: {}", msg);
2✔
1630

1631
        std::cerr << msg << std::endl;
2✔
1632
    }
2✔
1633

1634
#if defined(HPX_HAVE_NETWORKING)
1635
    ///////////////////////////////////////////////////////////////////////////
1636
    // Create an instance of a binary filter plugin
1637
    serialization::binary_filter* create_binary_filter(
×
1638
        char const* binary_filter_type, bool compress,
1639
        serialization::binary_filter* next_filter, error_code& ec)
1640
    {
1641
        runtime_distributed* rtd = get_runtime_distributed_ptr();
×
1642
        if (nullptr != rtd)
×
1643
            return rtd->create_binary_filter(
×
1644
                binary_filter_type, compress, next_filter, ec);
×
1645

1646
        HPX_THROWS_IF(ec, hpx::error::invalid_status, "create_binary_filter",
×
1647
            "the runtime system is not available at this time");
1648
        return nullptr;
×
1649
    }
×
1650
#endif
1651

1652
    runtime_distributed& get_runtime_distributed()
140,430,218✔
1653
    {
1654
        HPX_ASSERT(get_runtime_distributed_ptr() != nullptr);
140,430,218✔
1655
        return *get_runtime_distributed_ptr();
140,191,800✔
1656
    }
1657

1658
    runtime_distributed*& get_runtime_distributed_ptr()
279,738,262✔
1659
    {
1660
        static runtime_distributed* runtime_distributed_ = nullptr;
1661
        return runtime_distributed_;
279,738,262✔
1662
    }
1663

1664
    void runtime_distributed::init_global_data()
593✔
1665
    {
1666
        runtime_distributed*& runtime_distributed_ =
593✔
1667
            get_runtime_distributed_ptr();
593✔
1668
        HPX_ASSERT(!runtime_distributed_);
593✔
1669
        HPX_ASSERT(nullptr == threads::thread_self::get_self());
593✔
1670
        runtime_distributed_ = this;
593✔
1671
    }
593✔
1672

1673
    void runtime_distributed::deinit_global_data()
592✔
1674
    {
1675
        runtime_distributed*& runtime_distributed_ =
592✔
1676
            get_runtime_distributed_ptr();
592✔
1677
        HPX_ASSERT(runtime_distributed_);
592✔
1678
        runtime_distributed_ = nullptr;
592✔
1679

1680
        runtime::deinit_global_data();
592✔
1681
    }
592✔
1682

1683
    naming::gid_type const& get_locality()
163✔
1684
    {
1685
        return get_runtime_distributed().get_agas_client().get_local_locality();
163✔
1686
    }
1687

1688
    ///////////////////////////////////////////////////////////////////////////
1689
    // Helpers
1690
    hpx::id_type find_here(error_code& ec)
50,116✔
1691
    {
1692
        runtime* rt = get_runtime_ptr();
50,116✔
1693
        if (nullptr == rt)
50,116✔
1694
        {
1695
            HPX_THROWS_IF(ec, hpx::error::invalid_status, "hpx::find_here",
×
1696
                "the runtime system is not available at this time");
1697
            return hpx::invalid_id;
×
1698
        }
1699

1700
        static hpx::id_type here =
50,604✔
1701
            naming::get_id_from_locality_id(rt->get_locality_id(ec));
488✔
1702
        return here;
50,116✔
1703
    }
50,116✔
1704

1705
    hpx::id_type find_root_locality(error_code& ec)
959✔
1706
    {
1707
        runtime_distributed* rt = hpx::get_runtime_distributed_ptr();
959✔
1708
        if (nullptr == rt)
959✔
1709
        {
1710
            HPX_THROWS_IF(ec, hpx::error::invalid_status,
×
1711
                "hpx::find_root_locality",
1712
                "the runtime system is not available at this time");
1713
            return hpx::invalid_id;
×
1714
        }
1715

1716
        naming::gid_type console_locality;
959✔
1717
        if (!rt->get_agas_client().get_console_locality(console_locality))
959✔
1718
        {
1719
            HPX_THROWS_IF(ec, hpx::error::invalid_status,
×
1720
                "hpx::find_root_locality",
1721
                "the root locality is not available at this time");
1722
            return hpx::invalid_id;
×
1723
        }
1724

1725
        if (&ec != &throws)
959✔
1726
            ec = make_success_code();
×
1727

1728
        return hpx::id_type(
959✔
1729
            console_locality, hpx::id_type::management_type::unmanaged);
1730
    }
959✔
1731

1732
    std::vector<hpx::id_type> find_all_localities(
1✔
1733
        components::component_type type, error_code& ec)
1734
    {
1735
        std::vector<hpx::id_type> locality_ids;
1✔
1736
        if (nullptr == hpx::applier::get_applier_ptr())
1✔
1737
        {
1738
            HPX_THROWS_IF(ec, hpx::error::invalid_status,
×
1739
                "hpx::find_all_localities",
1740
                "the runtime system is not available at this time");
1741
            return locality_ids;
×
1742
        }
1743

1744
        hpx::applier::get_applier().get_localities(locality_ids, type, ec);
1✔
1745
        return locality_ids;
1✔
1746
    }
1✔
1747

1748
    std::vector<hpx::id_type> find_all_localities(error_code& ec)
1,390✔
1749
    {
1750
        std::vector<hpx::id_type> locality_ids;
1,390✔
1751
        if (nullptr == hpx::applier::get_applier_ptr())
1,390✔
1752
        {
1753
            HPX_THROWS_IF(ec, hpx::error::invalid_status,
×
1754
                "hpx::find_all_localities",
1755
                "the runtime system is not available at this time");
1756
            return locality_ids;
×
1757
        }
1758

1759
        hpx::applier::get_applier().get_localities(locality_ids, ec);
1,390✔
1760
        return locality_ids;
1,390✔
1761
    }
1,390✔
1762

1763
    std::vector<hpx::id_type> find_remote_localities(
14✔
1764
        components::component_type type, error_code& ec)
1765
    {
1766
        std::vector<hpx::id_type> locality_ids;
14✔
1767
        if (nullptr == hpx::applier::get_applier_ptr())
14✔
1768
        {
1769
            HPX_THROWS_IF(ec, hpx::error::invalid_status,
×
1770
                "hpx::find_remote_localities",
1771
                "the runtime system is not available at this time");
1772
            return locality_ids;
×
1773
        }
1774

1775
        hpx::applier::get_applier().get_remote_localities(
14✔
1776
            locality_ids, type, ec);
14✔
1777
        return locality_ids;
14✔
1778
    }
14✔
1779

1780
    std::vector<hpx::id_type> find_remote_localities(error_code& ec)
42✔
1781
    {
1782
        std::vector<hpx::id_type> locality_ids;
42✔
1783
        if (nullptr == hpx::applier::get_applier_ptr())
42✔
1784
        {
1785
            HPX_THROWS_IF(ec, hpx::error::invalid_status,
×
1786
                "hpx::find_remote_localities",
1787
                "the runtime system is not available at this time");
1788
            return locality_ids;
×
1789
        }
1790

1791
        hpx::applier::get_applier().get_remote_localities(
42✔
1792
            locality_ids, components::component_invalid, ec);
42✔
1793

1794
        return locality_ids;
42✔
1795
    }
42✔
1796

1797
    // find a locality supporting the given component
1798
    hpx::id_type find_locality(components::component_type type, error_code& ec)
×
1799
    {
1800
        if (nullptr == hpx::applier::get_applier_ptr())
×
1801
        {
1802
            HPX_THROWS_IF(ec, hpx::error::invalid_status, "hpx::find_locality",
×
1803
                "the runtime system is not available at this time");
1804
            return hpx::invalid_id;
×
1805
        }
1806

1807
        std::vector<hpx::id_type> locality_ids;
×
1808
        hpx::applier::get_applier().get_localities(locality_ids, type, ec);
×
1809

1810
        if (ec || locality_ids.empty())
×
1811
            return hpx::invalid_id;
×
1812

1813
        // chose first locality to host the object
1814
        return locality_ids.front();
×
1815
    }
×
1816

1817
    std::uint32_t get_num_localities(hpx::launch::sync_policy,
×
1818
        components::component_type type, error_code& ec)
1819
    {
1820
        runtime_distributed* rt = get_runtime_distributed_ptr();
×
1821
        if (nullptr == rt)
×
1822
        {
1823
            HPX_THROW_EXCEPTION(hpx::error::invalid_status,
×
1824
                "hpx::get_num_localities",
1825
                "the runtime system has not been initialized yet");
1826
            return 0;
1827
        }
1828

1829
        return rt->get_num_localities(hpx::launch::sync, type, ec);
×
1830
    }
×
1831

1832
    hpx::future<std::uint32_t> get_num_localities(
×
1833
        components::component_type type)
1834
    {
1835
        runtime_distributed* rt = get_runtime_distributed_ptr();
×
1836
        if (nullptr == rt)
×
1837
        {
1838
            HPX_THROW_EXCEPTION(hpx::error::invalid_status,
×
1839
                "hpx::get_num_localities",
1840
                "the runtime system has not been initialized yet");
1841
            return make_ready_future(std::uint32_t(0));
1842
        }
1843

1844
        return rt->get_num_localities(type);
×
1845
    }
×
1846
}    // namespace hpx
1847

1848
///////////////////////////////////////////////////////////////////////////////
1849
namespace hpx { namespace naming {
1850

1851
    // shortcut for get_runtime().get_agas_client()
1852
    resolver_client& get_agas_client()
59,643,887✔
1853
    {
1854
        return get_runtime_distributed().get_agas_client();
59,643,887✔
1855
    }
1856

1857
    // shortcut for get_runtime_ptr()->get_agas_client()
1858
    resolver_client* get_agas_client_ptr()
12,733✔
1859
    {
1860
        auto* rtd = get_runtime_distributed_ptr();
12,733✔
1861
        return rtd ? &rtd->get_agas_client() : nullptr;
12,733✔
1862
    }
1863
}}    // namespace hpx::naming
1864

1865
///////////////////////////////////////////////////////////////////////////////
1866
#if defined(HPX_HAVE_NETWORKING)
1867
namespace hpx { namespace parcelset {
1868

1869
    bool do_background_work(
80,214,086✔
1870
        std::size_t num_thread, parcelport_background_mode mode)
1871
    {
1872
        return get_runtime_distributed()
160,428,172✔
1873
            .get_parcel_handler()
80,216,837✔
1874
            .do_background_work(num_thread, mode);
80,216,837✔
1875
    }
1876

1877
    // shortcut for get_runtime().get_parcel_handler()
1878
    parcelhandler& get_parcel_handler()
142✔
1879
    {
1880
        return get_runtime_distributed().get_parcel_handler();
142✔
1881
    }
1882

1883
    // shortcut for get_runtime_ptr()->get_parcel_handler()
1884
    parcelhandler* get_parcel_handler_ptr()
×
1885
    {
1886
        auto* rtd = get_runtime_distributed_ptr();
×
1887
        return rtd ? &rtd->get_parcel_handler() : nullptr;
×
1888
    }
1889
}}    // namespace hpx::parcelset
1890
#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

© 2025 Coveralls, Inc