/home/users/khuck/src/hpx-lsu/src/runtime.cpp

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

Copyright (c) 2006-2012 Rogue Wave Software, Inc. All Rights Reserved.
Patents pending.