1 // Copyright (c) 2007-2018 Hartmut Kaiser 2 // Copyright (c) 2011 Bryce Lelbach 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 7 #include <hpx/config.hpp> 8 #include <hpx/compat/mutex.hpp> 9 #include <hpx/exception.hpp> 10 #include <hpx/performance_counters/counter_creators.hpp> 11 #include <hpx/performance_counters/counters.hpp> 12 #include <hpx/performance_counters/manage_counter_type.hpp> 13 #include <hpx/performance_counters/registry.hpp> 14 #include <hpx/runtime.hpp> 15 #include <hpx/runtime/thread_hooks.hpp> 16 #include <hpx/runtime/agas/addressing_service.hpp> 17 #include <hpx/runtime/applier/applier.hpp> 18 #include <hpx/runtime/components/server/memory.hpp> 19 #include <hpx/runtime/components/server/runtime_support.hpp> 20 #include <hpx/runtime/components/server/simple_component_base.hpp> // EXPORTS get_next_id 21 #include <hpx/runtime/config_entry.hpp> 22 #include <hpx/runtime/launch_policy.hpp> 23 #include <hpx/runtime/parcelset/parcelhandler.hpp> 24 #include <hpx/runtime/threads/coroutines/coroutine.hpp> 25 #include <hpx/runtime/threads/policies/scheduler_mode.hpp> 26 #include <hpx/runtime/threads/threadmanager.hpp> 27 #include <hpx/runtime/threads/topology.hpp> 28 #include <hpx/state.hpp> 29 #include <hpx/util/assert.hpp> 30 #include <hpx/util/backtrace.hpp> 31 #include <hpx/util/command_line_handling.hpp> 32 #include <hpx/util/debugging.hpp> 33 #include <hpx/util/high_resolution_clock.hpp> 34 #include <hpx/util/logging.hpp> 35 #include <hpx/util/query_counters.hpp> 36 #include <hpx/util/static_reinit.hpp> 37 #include <hpx/util/thread_mapper.hpp> 38 #include <hpx/version.hpp> 39 40 #include <atomic> 41 #include <cstddef> 42 #include <cstdint> 43 #include <exception> 44 #include <iostream> 45 #include <memory> 46 #include <mutex> 47 #include <string> 48 #include <utility> 49 #include <vector> 50 51 #if defined(_WIN64) && defined(_DEBUG) && !defined(HPX_HAVE_FIBER_BASED_COROUTINES) 52 #include <io.h> 53 #endif 54 55 /////////////////////////////////////////////////////////////////////////////// 56 // Make sure the system gets properly shut down while handling Ctrl-C and other 57 // system signals 58 #if defined(HPX_WINDOWS) 59 60 namespace hpx 61 { 62 /////////////////////////////////////////////////////////////////////////// handle_termination(char const * reason)63 void handle_termination(char const* reason) 64 { 65 if (get_config_entry("hpx.attach_debugger", "") == "exception") 66 { 67 util::attach_debugger(); 68 } 69 70 if (get_config_entry("hpx.diagnostics_on_terminate", "1") == "1") 71 { 72 std::cerr 73 #if defined(HPX_HAVE_STACKTRACES) 74 << "{stack-trace}: " << hpx::util::trace() << "\n" 75 #endif 76 << "{what}: " << (reason ? reason : "Unknown reason") << "\n" 77 << full_build_string(); // add full build information 78 } 79 } 80 termination_handler(DWORD ctrl_type)81 HPX_EXPORT BOOL WINAPI termination_handler(DWORD ctrl_type) 82 { 83 switch (ctrl_type) { 84 case CTRL_C_EVENT: 85 handle_termination("Ctrl-C"); 86 return TRUE; 87 88 case CTRL_BREAK_EVENT: 89 handle_termination("Ctrl-Break"); 90 return TRUE; 91 92 case CTRL_CLOSE_EVENT: 93 handle_termination("Ctrl-Close"); 94 return TRUE; 95 96 case CTRL_LOGOFF_EVENT: 97 handle_termination("Logoff"); 98 return TRUE; 99 100 case CTRL_SHUTDOWN_EVENT: 101 handle_termination("Shutdown"); 102 return TRUE; 103 104 default: 105 break; 106 } 107 return FALSE; 108 } 109 } 110 111 #else 112 113 #include <signal.h> 114 #include <stdlib.h> 115 #include <string.h> 116 117 namespace hpx 118 { 119 /////////////////////////////////////////////////////////////////////////// termination_handler(int signum)120 HPX_EXPORT HPX_NORETURN void termination_handler(int signum) 121 { 122 if (signum != SIGINT && 123 get_config_entry("hpx.attach_debugger", "") == "exception") 124 { 125 util::attach_debugger(); 126 } 127 128 if (get_config_entry("hpx.diagnostics_on_terminate", "1") == "1") 129 { 130 char* reason = strsignal(signum); 131 std::cerr 132 #if defined(HPX_HAVE_STACKTRACES) 133 << "{stack-trace}: " << hpx::util::trace() << "\n" 134 #endif 135 << "{what}: " << (reason ? reason : "Unknown signal") << "\n" 136 << full_build_string(); // add full build information 137 } 138 std::abort(); 139 } 140 } 141 142 #endif 143 144 /////////////////////////////////////////////////////////////////////////////// 145 namespace hpx 146 { 147 /////////////////////////////////////////////////////////////////////////// 148 // There is no need to protect these global from thread concurrent access 149 // as they are access during early startup only. 150 std::vector<hpx::util::tuple<char const*, char const*> > 151 message_handler_registrations; 152 153 /////////////////////////////////////////////////////////////////////////// new_handler()154 HPX_EXPORT void HPX_CDECL new_handler() 155 { 156 HPX_THROW_EXCEPTION(out_of_memory, "new_handler", 157 "new allocator failed to allocate memory"); 158 } 159 set_error_handlers()160 void set_error_handlers() 161 { 162 #if defined(HPX_WINDOWS) 163 // Set console control handler to allow server to be stopped. 164 SetConsoleCtrlHandler(hpx::termination_handler, TRUE); 165 #else 166 struct sigaction new_action; 167 new_action.sa_handler = hpx::termination_handler; 168 sigemptyset(&new_action.sa_mask); 169 new_action.sa_flags = 0; 170 171 sigaction(SIGINT, &new_action, nullptr); // Interrupted 172 sigaction(SIGBUS, &new_action, nullptr); // Bus error 173 sigaction(SIGFPE, &new_action, nullptr); // Floating point exception 174 sigaction(SIGILL, &new_action, nullptr); // Illegal instruction 175 sigaction(SIGPIPE, &new_action, nullptr); // Bad pipe 176 sigaction(SIGSEGV, &new_action, nullptr); // Segmentation fault 177 sigaction(SIGSYS, &new_action, nullptr); // Bad syscall 178 #endif 179 180 std::set_new_handler(hpx::new_handler); 181 } 182 183 184 /////////////////////////////////////////////////////////////////////////// 185 namespace strings 186 { 187 char const* const runtime_mode_names[] = 188 { 189 "invalid", // -1 190 "console", // 0 191 "worker", // 1 192 "connect", // 2 193 "default", // 3 194 }; 195 } 196 get_runtime_mode_name(runtime_mode state)197 char const* get_runtime_mode_name(runtime_mode state) 198 { 199 if (state < runtime_mode_invalid || state >= runtime_mode_last) 200 return "invalid (value out of bounds)"; 201 return strings::runtime_mode_names[state+1]; 202 } 203 get_runtime_mode_from_name(std::string const & mode)204 runtime_mode get_runtime_mode_from_name(std::string const& mode) 205 { 206 for (std::size_t i = 0; i < runtime_mode_last; ++i) { 207 if (mode == strings::runtime_mode_names[i]) 208 return static_cast<runtime_mode>(i-1); 209 } 210 return runtime_mode_invalid; 211 } 212 213 namespace strings 214 { 215 char const* const runtime_state_names[] = 216 { 217 "state_invalid", // -1 218 "state_initialized", // 0 219 "state_pre_startup", // 1 220 "state_startup", // 2 221 "state_pre_main", // 3 222 "state_starting", // 4 223 "state_running", // 5 224 "state_suspended", // 6 225 "state_pre_sleep", // 7 226 "state_sleeping", // 8 227 "state_pre_shutdown", // 9 228 "state_shutdown", // 10 229 "state_stopping", // 11 230 "state_terminating", // 12 231 "state_stopped" // 13 232 }; 233 } 234 get_runtime_state_name(state st)235 char const* get_runtime_state_name(state st) 236 { 237 if (st < state_invalid || st >= last_valid_runtime_state) 238 return "invalid (value out of bounds)"; 239 return strings::runtime_state_names[st+1]; 240 } 241 242 /////////////////////////////////////////////////////////////////////////// 243 threads::policies::callback_notifier::on_startstop_type global_on_start_func; 244 threads::policies::callback_notifier::on_startstop_type global_on_stop_func; 245 threads::policies::callback_notifier::on_error_type global_on_error_func; 246 247 /////////////////////////////////////////////////////////////////////////// runtime(util::runtime_configuration & rtcfg)248 runtime::runtime(util::runtime_configuration & rtcfg) 249 : ini_(rtcfg), 250 instance_number_(++instance_number_counter_), 251 thread_support_(new util::thread_mapper), 252 topology_(resource::get_partitioner().get_topology()), 253 state_(state_invalid), 254 memory_(new components::server::memory), 255 runtime_support_(new components::server::runtime_support(ini_)), 256 on_start_func_(global_on_start_func), 257 on_stop_func_(global_on_stop_func), 258 on_error_func_(global_on_error_func) 259 { 260 LPROGRESS_; 261 262 // initialize our TSS 263 runtime::init_tss(); 264 util::reinit_construct(); // call only after TLS was initialized 265 266 counters_ = std::make_shared<performance_counters::registry>(); 267 } 268 ~runtime()269 runtime::~runtime() 270 { 271 // allow to reuse instance number if this was the only instance 272 if (0 == instance_number_counter_) 273 --instance_number_counter_; 274 275 util::reinit_destruct(); 276 resource::detail::delete_partitioner(); 277 } 278 set_state(state s)279 void runtime::set_state(state s) 280 { 281 LPROGRESS_ << get_runtime_state_name(s); 282 state_.store(s); 283 } 284 285 /////////////////////////////////////////////////////////////////////////// 286 std::atomic<int> runtime::instance_number_counter_(-1); 287 288 /////////////////////////////////////////////////////////////////////////// 289 util::thread_specific_ptr<runtime*, runtime::tls_tag> runtime::runtime_; 290 util::thread_specific_ptr<std::string, runtime::tls_tag> runtime::thread_name_; 291 util::thread_specific_ptr<std::uint64_t, runtime::tls_tag> runtime::uptime_; 292 init_tss()293 void runtime::init_tss() 294 { 295 // initialize our TSS 296 if (nullptr == runtime::runtime_.get()) 297 { 298 HPX_ASSERT(nullptr == threads::thread_self::get_self()); 299 300 runtime::runtime_.reset(new runtime* (this)); 301 runtime::uptime_.reset(new std::uint64_t); 302 *runtime::uptime_.get() = util::high_resolution_clock::now(); 303 304 threads::thread_self::init_self(); // done in resource_partitioner 305 } 306 } 307 deinit_tss()308 void runtime::deinit_tss() 309 { 310 // reset our TSS 311 threads::thread_self::reset_self(); 312 runtime::uptime_.reset(); 313 runtime::runtime_.reset(); 314 util::reset_held_lock_data(); 315 316 threads::reset_continuation_recursion_count(); 317 } 318 get_thread_name()319 std::string runtime::get_thread_name() 320 { 321 std::string const* str = runtime::thread_name_.get(); 322 return str ? *str : "<unknown>"; 323 } 324 get_system_uptime()325 std::uint64_t runtime::get_system_uptime() 326 { 327 std::int64_t diff = 328 util::high_resolution_clock::now() - *runtime::uptime_.get(); 329 return diff < 0LL ? 0ULL : static_cast<std::uint64_t>(diff); 330 } 331 get_counter_registry()332 performance_counters::registry& runtime::get_counter_registry() 333 { 334 return *counters_; 335 } 336 get_counter_registry() const337 performance_counters::registry const& runtime::get_counter_registry() const 338 { 339 return *counters_; 340 } 341 get_thread_mapper()342 util::thread_mapper& runtime::get_thread_mapper() 343 { 344 return *thread_support_; 345 } 346 347 /////////////////////////////////////////////////////////////////////////// register_query_counters(std::shared_ptr<util::query_counters> const & active_counters)348 void runtime::register_query_counters( 349 std::shared_ptr<util::query_counters> const& active_counters) 350 { 351 active_counters_ = active_counters; 352 } 353 start_active_counters(error_code & ec)354 void runtime::start_active_counters(error_code& ec) 355 { 356 if (active_counters_.get()) 357 active_counters_->start_counters(ec); 358 } 359 stop_active_counters(error_code & ec)360 void runtime::stop_active_counters(error_code& ec) 361 { 362 if (active_counters_.get()) 363 active_counters_->stop_counters(ec); 364 } 365 reset_active_counters(error_code & ec)366 void runtime::reset_active_counters(error_code& ec) 367 { 368 if (active_counters_.get()) 369 active_counters_->reset_counters(ec); 370 } 371 reinit_active_counters(bool reset,error_code & ec)372 void runtime::reinit_active_counters(bool reset, error_code& ec) 373 { 374 if (active_counters_.get()) 375 active_counters_->reinit_counters(reset, ec); 376 } 377 evaluate_active_counters(bool reset,char const * description,error_code & ec)378 void runtime::evaluate_active_counters(bool reset, 379 char const* description, error_code& ec) 380 { 381 if (active_counters_.get()) 382 active_counters_->evaluate_counters(reset, description, ec); 383 } 384 stop_evaluating_counters()385 void runtime::stop_evaluating_counters() 386 { 387 if (active_counters_.get()) 388 active_counters_->stop_evaluating_counters(); 389 } 390 register_message_handler(char const * message_handler_type,char const * action,error_code & ec)391 void runtime::register_message_handler(char const* message_handler_type, 392 char const* action, error_code& ec) 393 { 394 return runtime_support_->register_message_handler( 395 message_handler_type, action, ec); 396 } 397 create_message_handler(char const * message_handler_type,char const * action,parcelset::parcelport * pp,std::size_t num_messages,std::size_t interval,error_code & ec)398 parcelset::policies::message_handler* runtime::create_message_handler( 399 char const* message_handler_type, char const* action, 400 parcelset::parcelport* pp, std::size_t num_messages, 401 std::size_t interval, error_code& ec) 402 { 403 return runtime_support_->create_message_handler(message_handler_type, 404 action, pp, num_messages, interval, ec); 405 } 406 create_binary_filter(char const * binary_filter_type,bool compress,serialization::binary_filter * next_filter,error_code & ec)407 serialization::binary_filter* runtime::create_binary_filter( 408 char const* binary_filter_type, bool compress, 409 serialization::binary_filter* next_filter, error_code& ec) 410 { 411 return runtime_support_->create_binary_filter(binary_filter_type, 412 compress, next_filter, ec); 413 } 414 415 /// \brief Register all performance counter types related to this runtime 416 /// instance register_counter_types()417 void runtime::register_counter_types() 418 { 419 performance_counters::generic_counter_type_data statistic_counter_types[] = 420 { 421 // averaging counter 422 { "/statistics/average", performance_counters::counter_aggregating, 423 "returns the averaged value of its base counter over " 424 "an arbitrary time line; pass required base counter as the instance " 425 "name: /statistics{<base_counter_name>}/average", 426 HPX_PERFORMANCE_COUNTER_V1, 427 &performance_counters::detail::statistics_counter_creator, 428 &performance_counters::default_counter_discoverer, 429 "" 430 }, 431 432 // stddev counter 433 { "/statistics/stddev", performance_counters::counter_aggregating, 434 "returns the standard deviation value of its base counter over " 435 "an arbitrary time line; pass required base counter as the instance " 436 "name: /statistics{<base_counter_name>}/stddev", 437 HPX_PERFORMANCE_COUNTER_V1, 438 &performance_counters::detail::statistics_counter_creator, 439 &performance_counters::default_counter_discoverer, 440 "" 441 }, 442 443 // rolling_averaging counter 444 { "/statistics/rolling_average", performance_counters::counter_aggregating, 445 "returns the rolling average value of its base counter over " 446 "an arbitrary time line; pass required base counter as the instance " 447 "name: /statistics{<base_counter_name>}/rolling_averaging", 448 HPX_PERFORMANCE_COUNTER_V1, 449 &performance_counters::detail::statistics_counter_creator, 450 &performance_counters::default_counter_discoverer, 451 "" 452 }, 453 454 // rolling stddev counter 455 { "/statistics/rolling_stddev", performance_counters::counter_aggregating, 456 "returns the rolling standard deviation value of its base counter over " 457 "an arbitrary time line; pass required base counter as the instance " 458 "name: /statistics{<base_counter_name>}/rolling_stddev", 459 HPX_PERFORMANCE_COUNTER_V1, 460 &performance_counters::detail::statistics_counter_creator, 461 &performance_counters::default_counter_discoverer, 462 "" 463 }, 464 465 // median counter 466 { "/statistics/median", performance_counters::counter_aggregating, 467 "returns the median value of its base counter over " 468 "an arbitrary time line; pass required base counter as the instance " 469 "name: /statistics{<base_counter_name>}/median", 470 HPX_PERFORMANCE_COUNTER_V1, 471 &performance_counters::detail::statistics_counter_creator, 472 &performance_counters::default_counter_discoverer, 473 "" 474 }, 475 476 // max counter 477 { "/statistics/max", performance_counters::counter_aggregating, 478 "returns the maximum value of its base counter over " 479 "an arbitrary time line; pass required base counter as the instance " 480 "name: /statistics{<base_counter_name>}/max", 481 HPX_PERFORMANCE_COUNTER_V1, 482 &performance_counters::detail::statistics_counter_creator, 483 &performance_counters::default_counter_discoverer, 484 "" 485 }, 486 487 // min counter 488 { "/statistics/min", performance_counters::counter_aggregating, 489 "returns the minimum value of its base counter over " 490 "an arbitrary time line; pass required base counter as the instance " 491 "name: /statistics{<base_counter_name>}/min", 492 HPX_PERFORMANCE_COUNTER_V1, 493 &performance_counters::detail::statistics_counter_creator, 494 &performance_counters::default_counter_discoverer, 495 "" 496 }, 497 498 // rolling max counter 499 { "/statistics/rolling_max", performance_counters::counter_aggregating, 500 "returns the rolling maximum value of its base counter over " 501 "an arbitrary time line; pass required base counter as the instance " 502 "name: /statistics{<base_counter_name>}/rolling_max", 503 HPX_PERFORMANCE_COUNTER_V1, 504 &performance_counters::detail::statistics_counter_creator, 505 &performance_counters::default_counter_discoverer, 506 "" 507 }, 508 509 // rolling min counter 510 { "/statistics/rolling_min", performance_counters::counter_aggregating, 511 "returns the rolling minimum value of its base counter over " 512 "an arbitrary time line; pass required base counter as the instance " 513 "name: /statistics{<base_counter_name>}/rolling_min", 514 HPX_PERFORMANCE_COUNTER_V1, 515 &performance_counters::detail::statistics_counter_creator, 516 &performance_counters::default_counter_discoverer, 517 "" 518 }, 519 520 // uptime counters 521 { "/runtime/uptime", performance_counters::counter_elapsed_time, 522 "returns the up time of the runtime instance for the referenced " 523 "locality", 524 HPX_PERFORMANCE_COUNTER_V1, 525 &performance_counters::detail::uptime_counter_creator, 526 &performance_counters::locality_counter_discoverer, 527 "s" // unit of measure is seconds 528 }, 529 530 // component instance counters 531 { "/runtime/count/component", performance_counters::counter_raw, 532 "returns the number of component instances currently alive on " 533 "this locality (the component type has to be specified as the " 534 "counter parameter)", 535 HPX_PERFORMANCE_COUNTER_V1, 536 &performance_counters::detail::component_instance_counter_creator, 537 &performance_counters::locality_counter_discoverer, 538 "" 539 }, 540 541 // action invocation counters 542 { "/runtime/count/action-invocation", performance_counters::counter_raw, 543 "returns the number of (local) invocations of a specific action " 544 "on this locality (the action type has to be specified as the " 545 "counter parameter)", 546 HPX_PERFORMANCE_COUNTER_V1, 547 &performance_counters::local_action_invocation_counter_creator, 548 &performance_counters::local_action_invocation_counter_discoverer, 549 "" 550 }, 551 552 { "/runtime/count/remote-action-invocation", 553 performance_counters::counter_raw, 554 "returns the number of (remote) invocations of a specific action " 555 "on this locality (the action type has to be specified as the " 556 "counter parameter)", 557 HPX_PERFORMANCE_COUNTER_V1, 558 &performance_counters::remote_action_invocation_counter_creator, 559 &performance_counters::remote_action_invocation_counter_discoverer, 560 "" 561 } 562 }; 563 performance_counters::install_counter_types( 564 statistic_counter_types, 565 sizeof(statistic_counter_types)/sizeof(statistic_counter_types[0])); 566 567 performance_counters::generic_counter_type_data arithmetic_counter_types[] = 568 { 569 // adding counter 570 { "/arithmetics/add", performance_counters::counter_aggregating, 571 "returns the sum of the values of the specified base counters; " 572 "pass required base counters as the parameters: " 573 "/arithmetics/add@<base_counter_name1>,<base_counter_name2>", 574 HPX_PERFORMANCE_COUNTER_V1, 575 &performance_counters::detail::arithmetics_counter_creator, 576 &performance_counters::default_counter_discoverer, 577 "" 578 }, 579 // minus counter 580 { "/arithmetics/subtract", performance_counters::counter_aggregating, 581 "returns the difference of the values of the specified base counters; " 582 "pass the required base counters as the parameters: " 583 "/arithmetics/subtract@<base_counter_name1>,<base_counter_name2>", 584 HPX_PERFORMANCE_COUNTER_V1, 585 &performance_counters::detail::arithmetics_counter_creator, 586 &performance_counters::default_counter_discoverer, 587 "" 588 }, 589 // multiply counter 590 { "/arithmetics/multiply", performance_counters::counter_aggregating, 591 "returns the product of the values of the specified base counters; " 592 "pass the required base counters as the parameters: " 593 "/arithmetics/multiply@<base_counter_name1>,<base_counter_name2>", 594 HPX_PERFORMANCE_COUNTER_V1, 595 &performance_counters::detail::arithmetics_counter_creator, 596 &performance_counters::default_counter_discoverer, 597 "" 598 }, 599 // divide counter 600 { "/arithmetics/divide", performance_counters::counter_aggregating, 601 "returns the result of division of the values of the specified " 602 "base counters; pass the required base counters as the parameters: " 603 "/arithmetics/divide@<base_counter_name1>,<base_counter_name2>", 604 HPX_PERFORMANCE_COUNTER_V1, 605 &performance_counters::detail::arithmetics_counter_creator, 606 &performance_counters::default_counter_discoverer, 607 "" 608 }, 609 610 // arithmetics mean counter 611 { "/arithmetics/mean", performance_counters::counter_aggregating, 612 "returns the average value of all values of the specified " 613 "base counters; pass the required base counters as the parameters: " 614 "/arithmetics/mean@<base_counter_name1>,<base_counter_name2>", 615 HPX_PERFORMANCE_COUNTER_V1, 616 &performance_counters::detail::arithmetics_counter_extended_creator, 617 &performance_counters::default_counter_discoverer, 618 "" 619 }, 620 // arithmetics variance counter 621 { "/arithmetics/variance", performance_counters::counter_aggregating, 622 "returns the standard deviation of all values of the specified " 623 "base counters; pass the required base counters as the parameters: " 624 "/arithmetics/variance@<base_counter_name1>,<base_counter_name2>", 625 HPX_PERFORMANCE_COUNTER_V1, 626 &performance_counters::detail::arithmetics_counter_extended_creator, 627 &performance_counters::default_counter_discoverer, 628 "" 629 }, 630 // arithmetics median counter 631 { "/arithmetics/median", performance_counters::counter_aggregating, 632 "returns the median of all values of the specified " 633 "base counters; pass the required base counters as the parameters: " 634 "/arithmetics/median@<base_counter_name1>,<base_counter_name2>", 635 HPX_PERFORMANCE_COUNTER_V1, 636 &performance_counters::detail::arithmetics_counter_extended_creator, 637 &performance_counters::default_counter_discoverer, 638 "" 639 }, 640 // arithmetics min counter 641 { "/arithmetics/min", performance_counters::counter_aggregating, 642 "returns the minimum value of all values of the specified " 643 "base counters; pass the required base counters as the parameters: " 644 "/arithmetics/min@<base_counter_name1>,<base_counter_name2>", 645 HPX_PERFORMANCE_COUNTER_V1, 646 &performance_counters::detail::arithmetics_counter_extended_creator, 647 &performance_counters::default_counter_discoverer, 648 "" 649 }, 650 // arithmetics max counter 651 { "/arithmetics/max", performance_counters::counter_aggregating, 652 "returns the maximum value of all values of the specified " 653 "base counters; pass the required base counters as the parameters: " 654 "/arithmetics/max@<base_counter_name1>,<base_counter_name2>", 655 HPX_PERFORMANCE_COUNTER_V1, 656 &performance_counters::detail::arithmetics_counter_extended_creator, 657 &performance_counters::default_counter_discoverer, 658 "" 659 }, 660 // arithmetics count counter 661 { "/arithmetics/count", performance_counters::counter_aggregating, 662 "returns the count value of all values of the specified " 663 "base counters; pass the required base counters as the parameters: " 664 "/arithmetics/count@<base_counter_name1>,<base_counter_name2>", 665 HPX_PERFORMANCE_COUNTER_V1, 666 &performance_counters::detail::arithmetics_counter_extended_creator, 667 &performance_counters::default_counter_discoverer, 668 "" 669 }, 670 }; 671 performance_counters::install_counter_types( 672 arithmetic_counter_types, 673 sizeof(arithmetic_counter_types)/sizeof(arithmetic_counter_types[0])); 674 } 675 assign_cores(std::string const & locality_basename,std::uint32_t cores_needed)676 std::uint32_t runtime::assign_cores(std::string const& locality_basename, 677 std::uint32_t cores_needed) 678 { 679 std::lock_guard<compat::mutex> l(mtx_); 680 681 used_cores_map_type::iterator it = used_cores_map_.find(locality_basename); 682 if (it == used_cores_map_.end()) 683 { 684 used_cores_map_.insert( 685 used_cores_map_type::value_type(locality_basename, cores_needed)); 686 return 0; 687 } 688 689 std::uint32_t current = (*it).second; 690 (*it).second += cores_needed; 691 return current; 692 } 693 assign_cores()694 std::uint32_t runtime::assign_cores() 695 { 696 // adjust thread assignments to allow for more than one locality per 697 // node 698 std::size_t first_core = this->get_config().get_first_used_core(); 699 std::size_t cores_needed = 700 hpx::resource::get_partitioner().assign_cores(first_core); 701 702 return static_cast<std::uint32_t>(cores_needed); 703 } 704 705 /////////////////////////////////////////////////////////////////////////// 706 threads::policies::callback_notifier::on_startstop_type on_start_func() const707 runtime::on_start_func() const 708 { 709 return on_start_func_; 710 } 711 712 threads::policies::callback_notifier::on_startstop_type on_stop_func() const713 runtime::on_stop_func() const 714 { 715 return on_stop_func_; 716 } 717 718 threads::policies::callback_notifier::on_error_type on_error_func() const719 runtime::on_error_func() const 720 { 721 return on_error_func_; 722 } 723 724 threads::policies::callback_notifier::on_startstop_type on_start_func(threads::policies::callback_notifier::on_startstop_type && f)725 runtime::on_start_func( 726 threads::policies::callback_notifier::on_startstop_type&& f) 727 { 728 threads::policies::callback_notifier::on_startstop_type newf = 729 std::move(f); 730 std::swap(on_start_func_, newf); 731 return newf; 732 } 733 734 threads::policies::callback_notifier::on_startstop_type on_stop_func(threads::policies::callback_notifier::on_startstop_type && f)735 runtime::on_stop_func( 736 threads::policies::callback_notifier::on_startstop_type&& f) 737 { 738 threads::policies::callback_notifier::on_startstop_type newf = 739 std::move(f); 740 std::swap(on_stop_func_, newf); 741 return newf; 742 } 743 744 threads::policies::callback_notifier::on_error_type on_error_func(threads::policies::callback_notifier::on_error_type && f)745 runtime::on_error_func( 746 threads::policies::callback_notifier::on_error_type&& f) 747 { 748 threads::policies::callback_notifier::on_error_type newf = 749 std::move(f); 750 std::swap(on_error_func_, newf); 751 return newf; 752 } 753 754 /////////////////////////////////////////////////////////////////////////// 755 threads::policies::callback_notifier::on_startstop_type get_thread_on_start_func()756 get_thread_on_start_func() 757 { 758 runtime* rt = get_runtime_ptr(); 759 if (nullptr != rt) 760 { 761 return rt->on_start_func(); 762 } 763 else 764 { 765 return global_on_start_func; 766 } 767 } 768 769 threads::policies::callback_notifier::on_startstop_type get_thread_on_stop_func()770 get_thread_on_stop_func() 771 { 772 runtime* rt = get_runtime_ptr(); 773 if (nullptr != rt) 774 { 775 return rt->on_stop_func(); 776 } 777 else 778 { 779 return global_on_stop_func; 780 } 781 } 782 783 threads::policies::callback_notifier::on_error_type get_thread_on_error_func()784 get_thread_on_error_func() 785 { 786 runtime* rt = get_runtime_ptr(); 787 if (nullptr != rt) 788 { 789 return rt->on_error_func(); 790 } 791 else 792 { 793 return global_on_error_func; 794 } 795 } 796 797 threads::policies::callback_notifier::on_startstop_type register_thread_on_start_func(threads::policies::callback_notifier::on_startstop_type && f)798 register_thread_on_start_func( 799 threads::policies::callback_notifier::on_startstop_type&& f) 800 { 801 runtime* rt = get_runtime_ptr(); 802 if (nullptr != rt) 803 { 804 return rt->on_start_func(std::move(f)); 805 } 806 807 threads::policies::callback_notifier::on_startstop_type newf = 808 std::move(f); 809 std::swap(global_on_start_func, newf); 810 return newf; 811 } 812 813 threads::policies::callback_notifier::on_startstop_type register_thread_on_stop_func(threads::policies::callback_notifier::on_startstop_type && f)814 register_thread_on_stop_func( 815 threads::policies::callback_notifier::on_startstop_type&& f) 816 { 817 runtime* rt = get_runtime_ptr(); 818 if (nullptr != rt) 819 { 820 return rt->on_stop_func(std::move(f)); 821 } 822 823 threads::policies::callback_notifier::on_startstop_type newf = 824 std::move(f); 825 std::swap(global_on_stop_func, newf); 826 return newf; 827 } 828 829 threads::policies::callback_notifier::on_error_type register_thread_on_error_func(threads::policies::callback_notifier::on_error_type && f)830 register_thread_on_error_func( 831 threads::policies::callback_notifier::on_error_type&& f) 832 { 833 runtime* rt = get_runtime_ptr(); 834 if (nullptr != rt) 835 { 836 return rt->on_error_func(std::move(f)); 837 } 838 839 threads::policies::callback_notifier::on_error_type newf = 840 std::move(f); 841 std::swap(global_on_error_func, newf); 842 return newf; 843 } 844 845 /////////////////////////////////////////////////////////////////////////// get_runtime()846 runtime& get_runtime() 847 { 848 HPX_ASSERT(nullptr != runtime::runtime_.get()); // should have been initialized 849 return **runtime::runtime_; 850 } 851 get_runtime_ptr()852 runtime* get_runtime_ptr() 853 { 854 runtime** rt = runtime::runtime_.get(); 855 return rt ? *rt : nullptr; 856 } 857 get_locality()858 naming::gid_type const & get_locality() 859 { 860 return get_runtime().get_agas_client().get_local_locality(); 861 } 862 863 /// Register the current kernel thread with HPX, this should be done once 864 /// for each external OS-thread intended to invoke HPX functionality. 865 /// Calling this function more than once will silently fail 866 /// (will return false). register_thread(runtime * rt,char const * name,error_code & ec)867 bool register_thread(runtime* rt, char const* name, error_code& ec) 868 { 869 HPX_ASSERT(rt); 870 return rt->register_thread(name, 0, true, ec); 871 } 872 873 /// Unregister the thread from HPX, this should be done once in 874 /// the end before the external thread exists. unregister_thread(runtime * rt)875 void unregister_thread(runtime* rt) 876 { 877 HPX_ASSERT(rt); 878 rt->unregister_thread(); 879 } 880 report_error(std::size_t num_thread,std::exception_ptr const & e)881 void report_error(std::size_t num_thread, std::exception_ptr const& e) 882 { 883 // Early and late exceptions 884 if (!threads::threadmanager_is(state_running)) 885 { 886 hpx::runtime* rt = hpx::get_runtime_ptr(); 887 if (rt) 888 rt->report_error(num_thread, e); 889 else 890 detail::report_exception_and_terminate(e); 891 return; 892 } 893 894 hpx::applier::get_applier().get_thread_manager().report_error(num_thread, e); 895 } 896 report_error(std::exception_ptr const & e)897 void report_error(std::exception_ptr const& e) 898 { 899 // Early and late exceptions 900 if (!threads::threadmanager_is(state_running)) 901 { 902 hpx::runtime* rt = hpx::get_runtime_ptr(); 903 if (rt) 904 rt->report_error(std::size_t(-1), e); 905 else 906 detail::report_exception_and_terminate(e); 907 return; 908 } 909 910 std::size_t num_thread = hpx::get_worker_thread_num(); 911 hpx::applier::get_applier().get_thread_manager().report_error(num_thread, e); 912 } 913 register_on_exit(util::function_nonser<void ()> const & f)914 bool register_on_exit(util::function_nonser<void()> const& f) 915 { 916 runtime* rt = get_runtime_ptr(); 917 if (nullptr == rt) 918 return false; 919 920 rt->on_exit(f); 921 return true; 922 } 923 get_runtime_instance_number()924 std::size_t get_runtime_instance_number() 925 { 926 runtime* rt = get_runtime_ptr(); 927 return (nullptr == rt) ? 0 : rt->get_instance_number(); 928 } 929 930 /////////////////////////////////////////////////////////////////////////// get_config_entry(std::string const & key,std::string const & dflt)931 std::string get_config_entry(std::string const& key, std::string const& dflt) 932 { 933 //! FIXME runtime_configuration should probs be a member of 934 // hpx::runtime only, not command_line_handling 935 //! FIXME change functions in this section accordingly 936 if (get_runtime_ptr() != nullptr) 937 { 938 return get_runtime().get_config().get_entry(key, dflt); 939 } 940 if (!resource::is_partitioner_valid()) 941 { 942 return dflt; 943 } 944 return resource::get_partitioner() 945 .get_command_line_switches().rtcfg_.get_entry(key, dflt); 946 } 947 get_config_entry(std::string const & key,std::size_t dflt)948 std::string get_config_entry(std::string const& key, std::size_t dflt) 949 { 950 if (get_runtime_ptr() != nullptr) 951 { 952 return get_runtime().get_config().get_entry(key, dflt); 953 } 954 if (!resource::is_partitioner_valid()) 955 { 956 return std::to_string(dflt); 957 } 958 return resource::get_partitioner() 959 .get_command_line_switches().rtcfg_.get_entry(key, dflt); 960 } 961 962 // set entries set_config_entry(std::string const & key,std::string const & value)963 void set_config_entry(std::string const& key, std::string const& value) 964 { 965 if (get_runtime_ptr() != nullptr) 966 { 967 get_runtime_ptr()->get_config().add_entry(key, value); 968 return; 969 } 970 if (resource::is_partitioner_valid()) 971 { 972 resource::get_partitioner() 973 .get_command_line_switches().rtcfg_.add_entry(key, value); 974 return; 975 } 976 } 977 set_config_entry(std::string const & key,std::size_t value)978 void set_config_entry(std::string const& key, std::size_t value) 979 { 980 if (get_runtime_ptr() != nullptr) 981 { 982 get_runtime_ptr()->get_config().add_entry( 983 key, std::to_string(value)); 984 return; 985 } 986 if (resource::is_partitioner_valid()) 987 { 988 resource::get_partitioner() 989 .get_command_line_switches().rtcfg_. 990 add_entry(key, std::to_string(value)); 991 return; 992 } 993 } 994 set_config_entry_callback(std::string const & key,util::function_nonser<void (std::string const &,std::string const &)> const & callback)995 void set_config_entry_callback(std::string const& key, 996 util::function_nonser<void( 997 std::string const&, std::string const&)> const& callback) 998 { 999 if (get_runtime_ptr() != nullptr) 1000 { 1001 get_runtime_ptr()->get_config().add_notification_callback( 1002 key, callback); 1003 return; 1004 } 1005 if (resource::is_partitioner_valid()) 1006 { 1007 resource::get_partitioner() 1008 .get_command_line_switches() 1009 .rtcfg_.add_notification_callback(key, callback); 1010 return; 1011 } 1012 } 1013 1014 /////////////////////////////////////////////////////////////////////////// 1015 // Helpers find_here(error_code & ec)1016 naming::id_type find_here(error_code& ec) 1017 { 1018 if (nullptr == hpx::applier::get_applier_ptr()) 1019 { 1020 HPX_THROWS_IF(ec, invalid_status, "hpx::find_here", 1021 "the runtime system is not available at this time"); 1022 return naming::invalid_id; 1023 } 1024 1025 return naming::id_type(hpx::applier::get_applier().get_raw_locality(ec), 1026 naming::id_type::unmanaged); 1027 } 1028 find_root_locality(error_code & ec)1029 naming::id_type find_root_locality(error_code& ec) 1030 { 1031 runtime* rt = hpx::get_runtime_ptr(); 1032 if (nullptr == rt) 1033 { 1034 HPX_THROWS_IF(ec, invalid_status, "hpx::find_root_locality", 1035 "the runtime system is not available at this time"); 1036 return naming::invalid_id; 1037 } 1038 1039 naming::gid_type console_locality; 1040 if (!rt->get_agas_client().get_console_locality(console_locality)) 1041 { 1042 HPX_THROWS_IF(ec, invalid_status, "hpx::find_root_locality", 1043 "the root locality is not available at this time"); 1044 return naming::invalid_id; 1045 } 1046 1047 if (&ec != &throws) 1048 ec = make_success_code(); 1049 1050 return naming::id_type(console_locality, naming::id_type::unmanaged); 1051 } 1052 1053 std::vector<naming::id_type> find_all_localities(components::component_type type,error_code & ec)1054 find_all_localities(components::component_type type, error_code& ec) 1055 { 1056 std::vector<naming::id_type> locality_ids; 1057 if (nullptr == hpx::applier::get_applier_ptr()) 1058 { 1059 HPX_THROWS_IF(ec, invalid_status, "hpx::find_all_localities", 1060 "the runtime system is not available at this time"); 1061 return locality_ids; 1062 } 1063 1064 hpx::applier::get_applier().get_localities(locality_ids, type, ec); 1065 return locality_ids; 1066 } 1067 find_all_localities(error_code & ec)1068 std::vector<naming::id_type> find_all_localities(error_code& ec) 1069 { 1070 std::vector<naming::id_type> locality_ids; 1071 if (nullptr == hpx::applier::get_applier_ptr()) 1072 { 1073 HPX_THROWS_IF(ec, invalid_status, "hpx::find_all_localities", 1074 "the runtime system is not available at this time"); 1075 return locality_ids; 1076 } 1077 1078 hpx::applier::get_applier().get_localities(locality_ids, ec); 1079 return locality_ids; 1080 } 1081 1082 std::vector<naming::id_type> find_remote_localities(components::component_type type,error_code & ec)1083 find_remote_localities(components::component_type type, error_code& ec) 1084 { 1085 std::vector<naming::id_type> locality_ids; 1086 if (nullptr == hpx::applier::get_applier_ptr()) 1087 { 1088 HPX_THROWS_IF(ec, invalid_status, "hpx::find_remote_localities", 1089 "the runtime system is not available at this time"); 1090 return locality_ids; 1091 } 1092 1093 hpx::applier::get_applier().get_remote_localities(locality_ids, type, ec); 1094 return locality_ids; 1095 } 1096 find_remote_localities(error_code & ec)1097 std::vector<naming::id_type> find_remote_localities(error_code& ec) 1098 { 1099 std::vector<naming::id_type> locality_ids; 1100 if (nullptr == hpx::applier::get_applier_ptr()) 1101 { 1102 HPX_THROWS_IF(ec, invalid_status, "hpx::find_remote_localities", 1103 "the runtime system is not available at this time"); 1104 return locality_ids; 1105 } 1106 1107 hpx::applier::get_applier().get_remote_localities(locality_ids, 1108 components::component_invalid, ec); 1109 1110 return locality_ids; 1111 } 1112 1113 // find a locality supporting the given component find_locality(components::component_type type,error_code & ec)1114 naming::id_type find_locality(components::component_type type, error_code& ec) 1115 { 1116 if (nullptr == hpx::applier::get_applier_ptr()) 1117 { 1118 HPX_THROWS_IF(ec, invalid_status, "hpx::find_locality", 1119 "the runtime system is not available at this time"); 1120 return naming::invalid_id; 1121 } 1122 1123 std::vector<naming::id_type> locality_ids; 1124 hpx::applier::get_applier().get_localities(locality_ids, type, ec); 1125 1126 if (ec || locality_ids.empty()) 1127 return naming::invalid_id; 1128 1129 // chose first locality to host the object 1130 return locality_ids.front(); 1131 } 1132 1133 /// \brief Return the number of localities which are currently registered 1134 /// for the running application. get_num_localities(hpx::launch::sync_policy,error_code & ec)1135 std::uint32_t get_num_localities(hpx::launch::sync_policy, error_code& ec) 1136 { 1137 if (nullptr == hpx::get_runtime_ptr()) 1138 return 0; 1139 1140 return get_runtime().get_agas_client().get_num_localities(ec); 1141 } 1142 get_initial_num_localities()1143 std::uint32_t get_initial_num_localities() 1144 { 1145 if (nullptr == hpx::get_runtime_ptr()) 1146 return 0; 1147 1148 return get_runtime().get_config().get_num_localities(); 1149 } 1150 get_num_localities(hpx::launch::sync_policy,components::component_type type,error_code & ec)1151 std::uint32_t get_num_localities(hpx::launch::sync_policy, 1152 components::component_type type, error_code& ec) 1153 { 1154 if (nullptr == hpx::get_runtime_ptr()) 1155 return 0; 1156 1157 return get_runtime().get_agas_client().get_num_localities(type, ec); 1158 } 1159 get_num_localities()1160 lcos::future<std::uint32_t> get_num_localities() 1161 { 1162 if (nullptr == hpx::get_runtime_ptr()) 1163 return lcos::make_ready_future<std::uint32_t>(0); 1164 1165 return get_runtime().get_agas_client().get_num_localities_async(); 1166 } 1167 get_num_localities(components::component_type type)1168 lcos::future<std::uint32_t> get_num_localities( 1169 components::component_type type) 1170 { 1171 if (nullptr == hpx::get_runtime_ptr()) 1172 return lcos::make_ready_future<std::uint32_t>(0); 1173 1174 return get_runtime().get_agas_client().get_num_localities_async(type); 1175 } 1176 1177 /////////////////////////////////////////////////////////////////////////// 1178 namespace detail 1179 { get_next_id(std::size_t count)1180 naming::gid_type get_next_id(std::size_t count) 1181 { 1182 if (nullptr == get_runtime_ptr()) 1183 return naming::invalid_gid; 1184 1185 return get_runtime().get_next_id(count); 1186 } 1187 1188 /////////////////////////////////////////////////////////////////////////// dijkstra_make_black()1189 void dijkstra_make_black() 1190 { 1191 get_runtime_support_ptr()->dijkstra_make_black(); 1192 } 1193 } 1194 1195 /////////////////////////////////////////////////////////////////////////// get_os_thread_count()1196 std::size_t get_os_thread_count() 1197 { 1198 runtime* rt = get_runtime_ptr(); 1199 if (nullptr == rt) 1200 { 1201 HPX_THROW_EXCEPTION( 1202 invalid_status, 1203 "hpx::get_os_thread_count()", 1204 "the runtime system has not been initialized yet"); 1205 return std::size_t(0); 1206 } 1207 return rt->get_config().get_os_thread_count(); 1208 } 1209 get_os_thread_count(threads::executor const & exec)1210 std::size_t get_os_thread_count(threads::executor const& exec) 1211 { 1212 runtime* rt = get_runtime_ptr(); 1213 if (nullptr == rt) 1214 { 1215 HPX_THROW_EXCEPTION( 1216 invalid_status, 1217 "hpx::get_os_thread_count(exec)", 1218 "the runtime system has not been initialized yet"); 1219 return std::size_t(0); 1220 } 1221 1222 if (!exec) 1223 return rt->get_config().get_os_thread_count(); 1224 1225 error_code ec(lightweight); 1226 return exec.executor_data_->get_policy_element( 1227 threads::detail::current_concurrency, ec); 1228 } 1229 get_worker_thread_num()1230 std::size_t get_worker_thread_num() 1231 { 1232 return get_worker_thread_num(throws); 1233 } 1234 get_worker_thread_num(error_code & ec)1235 std::size_t get_worker_thread_num(error_code& ec) 1236 { 1237 runtime* rt = get_runtime_ptr(); 1238 if (nullptr == rt) 1239 { 1240 HPX_THROWS_IF( 1241 ec, invalid_status, 1242 "hpx::get_worker_thread_num", 1243 "the runtime system has not been initialized yet"); 1244 return std::size_t(-1); 1245 } 1246 return rt->get_thread_manager().get_worker_thread_num(); 1247 } 1248 get_num_worker_threads()1249 std::size_t get_num_worker_threads() 1250 { 1251 runtime* rt = get_runtime_ptr(); 1252 if (nullptr == rt) 1253 { 1254 HPX_THROW_EXCEPTION( 1255 invalid_status, 1256 "hpx::get_num_worker_threads", 1257 "the runtime system has not been initialized yet"); 1258 return std::size_t(0); 1259 } 1260 1261 error_code ec(lightweight); 1262 return static_cast<std::size_t>( 1263 rt->get_agas_client().get_num_overall_threads(ec)); 1264 } 1265 is_scheduler_numa_sensitive()1266 bool is_scheduler_numa_sensitive() 1267 { 1268 runtime* rt = get_runtime_ptr(); 1269 if (nullptr == rt) 1270 { 1271 HPX_THROW_EXCEPTION( 1272 invalid_status, 1273 "hpx::is_scheduler_numa_sensitive", 1274 "the runtime system has not been initialized yet"); 1275 return false; 1276 } 1277 1278 bool numa_sensitive = false; 1279 if (std::size_t(-1) != 1280 rt->get_thread_manager().get_worker_thread_num(&numa_sensitive)) 1281 return numa_sensitive; 1282 return false; 1283 } 1284 1285 /////////////////////////////////////////////////////////////////////////// get_runtime_support_ptr()1286 components::server::runtime_support* get_runtime_support_ptr() 1287 { 1288 return reinterpret_cast<components::server::runtime_support*>( 1289 get_runtime().get_runtime_support_lva()); 1290 } 1291 1292 /////////////////////////////////////////////////////////////////////////// is_running()1293 bool is_running() 1294 { 1295 runtime* rt = get_runtime_ptr(); 1296 if (nullptr != rt) 1297 return rt->get_state() == state_running; 1298 return false; 1299 } 1300 is_stopped()1301 bool is_stopped() 1302 { 1303 runtime* rt = get_runtime_ptr(); 1304 if (nullptr != rt) 1305 return rt->get_state() == state_stopped; 1306 return true; // assume stopped 1307 } 1308 is_stopped_or_shutting_down()1309 bool is_stopped_or_shutting_down() 1310 { 1311 runtime* rt = get_runtime_ptr(); 1312 if (nullptr != rt) 1313 { 1314 state st = rt->get_state(); 1315 return st >= state_shutdown; 1316 } 1317 return true; // assume stopped 1318 } 1319 tolerate_node_faults()1320 bool HPX_EXPORT tolerate_node_faults() 1321 { 1322 #ifdef HPX_HAVE_FAULT_TOLERANCE 1323 return true; 1324 #else 1325 return false; 1326 #endif 1327 } 1328 is_starting()1329 bool HPX_EXPORT is_starting() 1330 { 1331 runtime* rt = get_runtime_ptr(); 1332 return nullptr != rt ? rt->get_state() <= state_startup : true; 1333 } 1334 is_pre_startup()1335 bool HPX_EXPORT is_pre_startup() 1336 { 1337 runtime* rt = get_runtime_ptr(); 1338 return nullptr != rt ? rt->get_state() < state_startup : true; 1339 } 1340 } 1341 1342 /////////////////////////////////////////////////////////////////////////////// 1343 namespace hpx { namespace util 1344 { expand(std::string const & in)1345 std::string expand(std::string const& in) 1346 { 1347 return get_runtime().get_config().expand(in); 1348 } 1349 expand(std::string & in)1350 void expand(std::string& in) 1351 { 1352 get_runtime().get_config().expand(in, std::string::size_type(-1)); 1353 } 1354 }} 1355 1356 /////////////////////////////////////////////////////////////////////////////// 1357 namespace hpx { namespace naming 1358 { 1359 // shortcut for get_runtime().get_agas_client() get_agas_client()1360 resolver_client& get_agas_client() 1361 { 1362 return get_runtime().get_agas_client(); 1363 } 1364 }} 1365 1366 /////////////////////////////////////////////////////////////////////////////// 1367 namespace hpx { namespace parcelset 1368 { do_background_work(std::size_t num_thread)1369 bool do_background_work(std::size_t num_thread) 1370 { 1371 return get_runtime().get_parcel_handler().do_background_work(num_thread); 1372 } 1373 }} 1374 1375 /////////////////////////////////////////////////////////////////////////////// 1376 namespace hpx { namespace threads 1377 { 1378 // shortcut for get_applier().get_thread_manager() get_thread_manager()1379 threadmanager& get_thread_manager() 1380 { 1381 return get_runtime().get_thread_manager(); 1382 } 1383 1384 // shortcut for runtime_configuration::get_default_stack_size get_default_stack_size()1385 std::ptrdiff_t get_default_stack_size() 1386 { 1387 return get_runtime().get_config().get_default_stack_size(); 1388 } 1389 1390 // shortcut for runtime_configuration::get_stack_size get_stack_size(threads::thread_stacksize stacksize)1391 std::ptrdiff_t get_stack_size(threads::thread_stacksize stacksize) 1392 { 1393 if (stacksize == threads::thread_stacksize_current) 1394 return threads::get_self_stacksize(); 1395 1396 return get_runtime().get_config().get_stack_size(stacksize); 1397 } 1398 reset_thread_distribution()1399 HPX_API_EXPORT void reset_thread_distribution() 1400 { 1401 get_runtime().get_thread_manager().reset_thread_distribution(); 1402 } 1403 set_scheduler_mode(threads::policies::scheduler_mode m)1404 HPX_API_EXPORT void set_scheduler_mode(threads::policies::scheduler_mode m) 1405 { 1406 get_runtime().get_thread_manager().set_scheduler_mode(m); 1407 } 1408 1409 }} 1410 1411 /////////////////////////////////////////////////////////////////////////////// 1412 namespace hpx 1413 { get_locality_id(error_code & ec)1414 std::uint32_t get_locality_id(error_code& ec) 1415 { 1416 return agas::get_locality_id(ec); 1417 } 1418 get_thread_name()1419 std::string get_thread_name() 1420 { 1421 return runtime::get_thread_name(); 1422 } 1423 get_system_uptime()1424 std::uint64_t get_system_uptime() 1425 { 1426 return runtime::get_system_uptime(); 1427 } 1428 get_config()1429 util::runtime_configuration const& get_config() 1430 { 1431 return get_runtime().get_config(); 1432 } 1433 get_thread_pool(char const * name,char const * name_suffix)1434 hpx::util::io_service_pool* get_thread_pool( 1435 char const* name, char const* name_suffix) 1436 { 1437 std::string full_name(name); 1438 full_name += name_suffix; 1439 return get_runtime().get_thread_pool(full_name.c_str()); 1440 } 1441 1442 /////////////////////////////////////////////////////////////////////////// start_active_counters(error_code & ec)1443 void start_active_counters(error_code& ec) 1444 { 1445 runtime* rt = get_runtime_ptr(); 1446 if (nullptr != rt) { 1447 rt->start_active_counters(ec); 1448 } 1449 else { 1450 HPX_THROWS_IF(ec, invalid_status, "start_active_counters", 1451 "the runtime system is not available at this time"); 1452 } 1453 } 1454 stop_active_counters(error_code & ec)1455 void stop_active_counters(error_code& ec) 1456 { 1457 runtime* rt = get_runtime_ptr(); 1458 if (nullptr != rt) { 1459 rt->stop_active_counters(ec); 1460 } 1461 else { 1462 HPX_THROWS_IF(ec, invalid_status, "stop_active_counters", 1463 "the runtime system is not available at this time"); 1464 } 1465 } 1466 reset_active_counters(error_code & ec)1467 void reset_active_counters(error_code& ec) 1468 { 1469 runtime* rt = get_runtime_ptr(); 1470 if (nullptr != rt) { 1471 rt->reset_active_counters(ec); 1472 } 1473 else { 1474 HPX_THROWS_IF(ec, invalid_status, "reset_active_counters", 1475 "the runtime system is not available at this time"); 1476 } 1477 } 1478 reinit_active_counters(bool reset,error_code & ec)1479 void reinit_active_counters(bool reset, error_code& ec) 1480 { 1481 runtime* rt = get_runtime_ptr(); 1482 if (nullptr != rt) { 1483 rt->reinit_active_counters(reset, ec); 1484 } 1485 else { 1486 HPX_THROWS_IF(ec, invalid_status, "reinit_active_counters", 1487 "the runtime system is not available at this time"); 1488 } 1489 } 1490 evaluate_active_counters(bool reset,char const * description,error_code & ec)1491 void evaluate_active_counters(bool reset, char const* description, error_code& ec) 1492 { 1493 runtime* rt = get_runtime_ptr(); 1494 if (nullptr != rt) { 1495 rt->evaluate_active_counters(reset, description, ec); 1496 } 1497 else { 1498 HPX_THROWS_IF(ec, invalid_status, "evaluate_active_counters", 1499 "the runtime system is not available at this time"); 1500 } 1501 } 1502 1503 /////////////////////////////////////////////////////////////////////////// 1504 // Create an instance of a message handler plugin register_message_handler(char const * message_handler_type,char const * action,error_code & ec)1505 void register_message_handler(char const* message_handler_type, 1506 char const* action, error_code& ec) 1507 { 1508 runtime* rt = get_runtime_ptr(); 1509 if (nullptr != rt) { 1510 return rt->register_message_handler(message_handler_type, action, ec); 1511 } 1512 1513 // store the request for later 1514 message_handler_registrations.push_back( 1515 hpx::util::make_tuple(message_handler_type, action)); 1516 } 1517 create_message_handler(char const * message_handler_type,char const * action,parcelset::parcelport * pp,std::size_t num_messages,std::size_t interval,error_code & ec)1518 parcelset::policies::message_handler* create_message_handler( 1519 char const* message_handler_type, char const* action, 1520 parcelset::parcelport* pp, std::size_t num_messages, 1521 std::size_t interval, error_code& ec) 1522 { 1523 runtime* rt = get_runtime_ptr(); 1524 if (nullptr != rt) { 1525 return rt->create_message_handler(message_handler_type, action, 1526 pp, num_messages, interval, ec); 1527 } 1528 1529 HPX_THROWS_IF(ec, invalid_status, "create_message_handler", 1530 "the runtime system is not available at this time"); 1531 return nullptr; 1532 } 1533 1534 /////////////////////////////////////////////////////////////////////////// 1535 // Create an instance of a binary filter plugin create_binary_filter(char const * binary_filter_type,bool compress,serialization::binary_filter * next_filter,error_code & ec)1536 serialization::binary_filter* create_binary_filter(char const* binary_filter_type, 1537 bool compress, serialization::binary_filter* next_filter, error_code& ec) 1538 { 1539 runtime* rt = get_runtime_ptr(); 1540 if (nullptr != rt) 1541 return rt->create_binary_filter 1542 (binary_filter_type, compress, next_filter, ec); 1543 1544 HPX_THROWS_IF(ec, invalid_status, "create_binary_filter", 1545 "the runtime system is not available at this time"); 1546 return nullptr; 1547 } 1548 1549 // helper function to stop evaluating counters during shutdown stop_evaluating_counters()1550 void stop_evaluating_counters() 1551 { 1552 runtime* rt = get_runtime_ptr(); 1553 if (nullptr != rt) rt->stop_evaluating_counters(); 1554 } 1555 } 1556