• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

STEllAR-GROUP / hpx / #871

22 Jan 2023 11:22PM UTC coverage: 86.624% (+0.7%) from 85.97%
#871

push

StellarBot
Merge #6144

6144: General improvements to scheduling and related fixes r=hkaiser a=hkaiser

This is a collection of unrelated improvements applied to different parts of the code

Co-authored-by: Hartmut Kaiser <hartmut.kaiser@gmail.com>

152 of 152 new or added lines in 23 files covered. (100.0%)

174953 of 201969 relevant lines covered (86.62%)

1838882.76 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_pools/detail/scoped_background_timer.hpp>
61
#include <hpx/thread_support/set_thread_name.hpp>
62
#include <hpx/threading_base/external_timer.hpp>
63
#include <hpx/threading_base/scheduler_mode.hpp>
64
#include <hpx/timing/high_resolution_clock.hpp>
65
#include <hpx/type_support/unused.hpp>
66
#include <hpx/util/from_string.hpp>
67
#include <hpx/version.hpp>
68

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

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

91
///////////////////////////////////////////////////////////////////////////////
92
namespace hpx {
93

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

100
            return get_runtime_distributed().get_next_id(count);
1,071✔
101
        }
1,071✔
102

103
        ///////////////////////////////////////////////////////////////////////
104
#if defined(HPX_HAVE_NETWORKING)
105
        void dijkstra_make_black()
472,871✔
106
        {
107
            get_runtime_support_ptr()->dijkstra_make_black();
472,871✔
108
        }
472,871✔
109
#endif
110

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

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

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

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

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

148
            if (0 == num_thread)
149
                hpx::agas::garbage_collect_non_blocking();
150
            return result;
151
        }
152
#else
153
        bool network_background_callback(std::size_t num_thread)
71,054,902✔
154
        {
155
            bool result = false;
71,405,426✔
156

157
#if defined(HPX_HAVE_NETWORKING)
158
            if (hpx::parcelset::do_background_work(
71,405,426✔
159
                    num_thread, parcelset::parcelport_background_mode_all))
71,405,426✔
160
            {
161
                result = true;
×
162
            }
×
163
#endif
164

165
            if (0 == num_thread)
71,776,260✔
166
                hpx::agas::garbage_collect_non_blocking();
17,965,278✔
167
            return result;
71,402,249✔
168
        }
169
#endif
170
    }    // namespace detail
171

172
    ///////////////////////////////////////////////////////////////////////////
173
    components::server::runtime_support* get_runtime_support_ptr()
473,636✔
174
    {
175
        return static_cast<components::server::runtime_support*>(
473,639✔
176
            get_runtime_distributed().get_runtime_support_lva());
473,636✔
177
    }
178

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

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

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

222
        // This needs to happen first
223
        runtime::init();
595✔
224

225
        init_global_data();
595✔
226
        util::reinit_construct();
595✔
227

228
        LPROGRESS_;
595✔
229

230
        components::server::get_error_dispatcher().set_error_sink(
595✔
231
            &runtime_distributed::default_errorsink);
595✔
232

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

236
        applier_.initialize(std::uint64_t(runtime_support_.get()));
595✔
237
    }
595✔
238

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

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

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

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

258
            agas_client_.bootstrap(parcel_handler_.endpoints(), rtcfg_);
453✔
259

260
            init_id_pool_range();
453✔
261

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

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

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

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

314
    ///////////////////////////////////////////////////////////////////////////
315
    runtime_distributed::~runtime_distributed()
1,188✔
316
    {
1,188✔
317
        LRT_(debug).format("~runtime_distributed(entering)");
594✔
318

319
        // reset counter registry
320
        get_counter_registry().clear();
594✔
321

322
        runtime_support_->delete_function_lists();
594✔
323

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

331
        LRT_(debug).format("~runtime_distributed(finished)");
594✔
332

333
        LPROGRESS_;
594✔
334
    }
1,188✔
335

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

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

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

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

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

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

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

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

401
        auto result_value = runtime::run_helper(func, result, false);
595✔
402

403
        if (post_main_ != nullptr)
595✔
404
        {
405
            post_main_();
595✔
406
        }
595✔
407

408
        return result_value;
595✔
409
    }
595✔
410

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

544
        // wait for termination
545
        runtime_support_->wait();
595✔
546

547
        // stop main thread pool
548
        main_pool_.stop();
595✔
549
    }
595✔
550

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

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

560
        std::thread t(hpx::bind(&runtime_distributed::wait_helper, this,
1,190✔
561
            std::ref(mtx), std::ref(cond), std::ref(running)));
595✔
562

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

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

574
        // block main thread
575
        t.join();
595✔
576

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

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

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

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

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

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

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

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

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

622
            deinit_global_data();
595✔
623

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

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

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

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

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

678
        deinit_global_data();
×
679

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

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

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

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

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

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

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

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

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

730
            return report_exception;
×
731
        }
732

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

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

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

759
        return report_exception;
2✔
760
    }
2✔
761

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

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

775
        // now wait for everything to finish
776
        wait();
372✔
777
        stop();
372✔
778

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

783
        rethrow_exception();
372✔
784
        return result_;
372✔
785
    }
786

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

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

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

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

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

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

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

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

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

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

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

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

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

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

869
    naming::resolver_client& runtime_distributed::get_agas_client()
55,638,811✔
870
    {
871
        return agas_client_;
55,639,421✔
872
    }
873

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

881
    parcelset::parcelhandler& runtime_distributed::get_parcel_handler()
71,200,810✔
882
    {
883
        return parcel_handler_;
71,205,670✔
884
    }
885
#endif
886

887
    hpx::threads::threadmanager& runtime_distributed::get_thread_manager()
3,461,937✔
888
    {
889
        return *thread_manager_;
3,461,919✔
890
    }
891

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1332
        notification_policy_type notifier;
2,380✔
1333

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

1343
        return notifier;
2,380✔
1344
    }
2,380✔
1345

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1495
        HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
×
1496
            "runtime_distributed::get_thread_pool",
1497
            "unknown thread pool requested: {}", name ? name : "<unknown>");
1498
        return nullptr;
1499
    }
16,672✔
1500

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

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

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

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

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

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

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

1545
    std::uint32_t runtime_distributed::get_locality_id(error_code& ec) const
31,469,301✔
1546
    {
1547
        return agas::get_locality_id(ec);
31,469,419✔
1548
    }
1549

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

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

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

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

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

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

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

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

1600
        used_cores_map_type::iterator it =
1601
            used_cores_map_.find(locality_basename);
595✔
1602
        if (it == used_cores_map_.end())
595✔
1603
        {
1604
            used_cores_map_.insert(used_cores_map_type::value_type(
906✔
1605
                locality_basename, cores_needed));
453✔
1606
            return 0;
453✔
1607
        }
1608

1609
        std::uint32_t current = (*it).second;
142✔
1610
        (*it).second += cores_needed;
142✔
1611
        return current;
142✔
1612
    }
595✔
1613

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

1623
        return static_cast<std::uint32_t>(cores_needed);
737✔
1624
    }
1625

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

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

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

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

1653
    runtime_distributed& get_runtime_distributed()
127,175,570✔
1654
    {
1655
        HPX_ASSERT(get_runtime_distributed_ptr() != nullptr);
127,175,570✔
1656
        return *get_runtime_distributed_ptr();
126,923,947✔
1657
    }
1658

1659
    runtime_distributed*& get_runtime_distributed_ptr()
252,910,395✔
1660
    {
1661
        static runtime_distributed* runtime_distributed_ = nullptr;
1662
        return runtime_distributed_;
252,910,395✔
1663
    }
1664

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

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

1681
        runtime::deinit_global_data();
595✔
1682
    }
595✔
1683

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

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

1701
        static hpx::id_type here =
52,660✔
1702
            naming::get_id_from_locality_id(rt->get_locality_id(ec));
490✔
1703
        return here;
52,170✔
1704
    }
52,170✔
1705

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

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

1726
        if (&ec != &throws)
963✔
1727
            ec = make_success_code();
×
1728

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

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

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

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

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

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

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

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

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

1795
        return locality_ids;
43✔
1796
    }
43✔
1797

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

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

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

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

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

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

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

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

1849
///////////////////////////////////////////////////////////////////////////////
1850
namespace hpx::naming {
1851

1852
    // shortcut for get_runtime().get_agas_client()
1853
    resolver_client& get_agas_client()
55,666,432✔
1854
    {
1855
        return get_runtime_distributed().get_agas_client();
55,666,432✔
1856
    }
1857

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

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

1870
    bool do_background_work(
71,013,842✔
1871
        std::size_t num_thread, parcelport_background_mode mode)
1872
    {
1873
        return get_runtime_distributed()
142,027,684✔
1874
            .get_parcel_handler()
71,014,967✔
1875
            .do_background_work(num_thread, mode);
71,014,967✔
1876
    }
1877

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

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