/home/users/khuck/src/hpx-lsu/src/util/runtime_configuration.cpp

Line% of fetchesSource
1  
//  Copyright (c) 2005-2016 Hartmut Kaiser
2  
//  Copyright (c)      2011 Bryce Adelstein-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/util/runtime_configuration.hpp>
8  
9  
#include <hpx/config/defaults.hpp>
10  
// TODO: move parcel ports into plugins
11  
#include <hpx/runtime/parcelset/parcelhandler.hpp>
12  
#include <hpx/util/filesystem_compatibility.hpp>
13  
#include <hpx/util/find_prefix.hpp>
14  
#include <hpx/util/init_ini_data.hpp>
15  
#include <hpx/util/itt_notify.hpp>
16  
#include <hpx/util/register_locks.hpp>
17  
#include <hpx/util/register_locks_globally.hpp>
18  
#include <hpx/util/safe_lexical_cast.hpp>
19  
#include <hpx/version.hpp>
20  
21  
#include <boost/detail/endian.hpp>
22  
#include <boost/preprocessor/stringize.hpp>
23  
#include <boost/spirit/include/qi_parse.hpp>
24  
#include <boost/spirit/include/qi_string.hpp>
25  
#include <boost/spirit/include/qi_numeric.hpp>
26  
#include <boost/spirit/include/qi_alternative.hpp>
27  
#include <boost/spirit/include/qi_sequence.hpp>
28  
#include <boost/tokenizer.hpp>
29  
30  
#include <algorithm>
31  
#include <cstddef>
32  
#include <cstdint>
33  
#include <iterator>
34  
#include <map>
35  
#include <memory>
36  
#include <set>
37  
#include <string>
38  
#include <utility>
39  
#include <vector>
40  
41  
#if defined(HPX_WINDOWS)
42  
#  include <process.h>
43  
#elif defined(HPX_HAVE_UNISTD_H)
44  
#  include <unistd.h>
45  
#endif
46  
47  
#if (defined(__linux) || defined(linux) || defined(__linux__))
48  
#include <ifaddrs.h>
49  
#include <netinet/in.h>
50  
#include <arpa/inet.h>
51  
#include <sys/types.h>
52  
#endif
53  
54  
#if !defined(HPX_WINDOWS)
55  
#  if defined(HPX_DEBUG)
56  
#    define HPX_DLL_STRING  "libhpxd" HPX_SHARED_LIB_EXTENSION
57  
#  else
58  
#    define HPX_DLL_STRING  "libhpx" HPX_SHARED_LIB_EXTENSION
59  
#  endif
60  
#elif defined(HPX_DEBUG)
61  
#  define HPX_DLL_STRING   "hpxd" HPX_SHARED_LIB_EXTENSION
62  
#else
63  
#  define HPX_DLL_STRING   "hpx" HPX_SHARED_LIB_EXTENSION
64  
#endif
65  
66  
#include <limits>
67  
68  
///////////////////////////////////////////////////////////////////////////////
69  
#if defined(__linux) || defined(linux) || defined(__linux__)\
70  
         || defined(__FreeBSD__) || defined(__APPLE__)
71  
namespace hpx { namespace threads { namespace coroutines { namespace detail
72  
{
73  
    namespace posix
74  
    {
75  
        ///////////////////////////////////////////////////////////////////////
76  
        // this global (urghhh) variable is used to control whether guard pages
77  
        // will be used or not
78  
        HPX_EXPORT bool use_guard_pages = true;
79  
    }
80  
}}}}
81  
#endif
82  
83  
namespace hpx { namespace threads { namespace policies
84  
{
85  
#ifdef HPX_HAVE_THREAD_MINIMAL_DEADLOCK_DETECTION
86  
    ///////////////////////////////////////////////////////////////////////////
87  
    // We globally control whether to do minimal deadlock detection using this
88  
    // global bool variable. It will be set once by the runtime configuration
89  
    // startup code
90  
    bool minimal_deadlock_detection = true;
91  
#endif
92  
}}}
93  
94  
namespace hpx { namespace lcos { namespace local
95  
{
96  
#ifdef HPX_HAVE_SPINLOCK_DEADLOCK_DETECTION
97  
    ///////////////////////////////////////////////////////////////////////////
98  
    // We globally control whether to do minimal deadlock detection in
99  
    // spin-locks using this global bool variable. It will be set once by the
100  
    // runtime configuration startup code
101  
    bool spinlock_break_on_deadlock = false;
102  
    std::size_t spinlock_deadlock_detection_limit =
103  
        HPX_SPINLOCK_DEADLOCK_DETECTION_LIMIT;
104  
#endif
105  
}}}
106  
107  
///////////////////////////////////////////////////////////////////////////////
108  
namespace hpx { namespace util
109  
{
110  
    // pre-initialize entries with compile time based values
111  
    void runtime_configuration::pre_initialize_ini()
112  
    {
113  
        if (!need_to_call_pre_initialize)
114  
            return;
115  
116  
        std::vector<std::string> lines = {
117  
            // create an empty application section
118  
            "[application]",
119  
120  
            // create system and application instance specific entries
121  
            "[system]",
122  
            "pid = " + std::to_string(getpid()),
123  
            "prefix = " + find_prefix(),
124  
#if defined(__linux) || defined(linux) || defined(__linux__)
125  
            "executable_prefix = " + get_executable_prefix(argv0),
126  
#else
127  
            "executable_prefix = " + get_executable_prefix(),
128  
#endif
129  
            // create default installation location and logging settings
130  
            "[hpx]",
131  
            "location = ${HPX_LOCATION:$[system.prefix]}",
132  
            "component_path = $[hpx.location]"
133  
                HPX_INI_PATH_DELIMITER "$[system.executable_prefix]",
134  
            "component_path_suffixes = /lib/hpx" HPX_INI_PATH_DELIMITER
135  
                                      "/bin/hpx",
136  
            "master_ini_path = $[hpx.location]" HPX_INI_PATH_DELIMITER
137  
                              "$[system.executable_prefix]/",
138  
            "master_ini_path_suffixes = /share/" HPX_BASE_DIR_NAME
139  
                HPX_INI_PATH_DELIMITER "/../share/" HPX_BASE_DIR_NAME,
140  
#ifdef HPX_HAVE_ITTNOTIFY
141  
            "use_itt_notify = ${HPX_HAVE_ITTNOTIFY:0}",
142  
#endif
143  
            "finalize_wait_time = ${HPX_FINALIZE_WAIT_TIME:-1.0}",
144  
            "shutdown_timeout = ${HPX_SHUTDOWN_TIMEOUT:-1.0}",
145  
#ifdef HPX_HAVE_VERIFY_LOCKS
146  
#if defined(HPX_DEBUG)
147  
            "lock_detection = ${HPX_LOCK_DETECTION:1}",
148  
#else
149  
            "lock_detection = ${HPX_LOCK_DETECTION:0}",
150  
#endif
151  
            "throw_on_held_lock = ${HPX_THROW_ON_HELD_LOCK:1}",
152  
#endif
153  
#ifdef HPX_HAVE_VERIFY_LOCKS_GLOBALLY
154  
#if defined(HPX_DEBUG)
155  
            "global_lock_detection = ${HPX_GLOBAL_LOCK_DETECTION:1}",
156  
#else
157  
            "global_lock_detection = ${HPX_GLOBAL_LOCK_DETECTION:0}",
158  
#endif
159  
#endif
160  
#ifdef HPX_HAVE_THREAD_MINIMAL_DEADLOCK_DETECTION
161  
#ifdef HPX_DEBUG
162  
            "minimal_deadlock_detection = ${HPX_MINIMAL_DEADLOCK_DETECTION:1}",
163  
#else
164  
            "minimal_deadlock_detection = ${HPX_MINIMAL_DEADLOCK_DETECTION:0}",
165  
#endif
166  
#endif
167  
#ifdef HPX_HAVE_SPINLOCK_DEADLOCK_DETECTION
168  
#ifdef HPX_DEBUG
169  
            "spinlick_deadlock_detection = ${HPX_SPINLOCK_DEADLOCK_DETECTION:1}",
170  
#else
171  
            "spinlick_deadlock_detection = ${HPX_SPINLOCK_DEADLOCK_DETECTION:0}",
172  
#endif
173  
            "spinlick_deadlock_detection_limit = "
174  
                "${HPX_SPINLOCK_DEADLOCK_DETECTION_LIMIT:1000000}",
175  
#endif
176  
            "expect_connecting_localities = ${HPX_EXPECT_CONNECTING_LOCALITIES:0}",
177  
178  
            // add placeholders for keys to be added by command line handling
179  
            "os_threads = 1",
180  
            "cores = all",
181  
            "localities = 1",
182  
            "first_pu = 0",
183  
            "runtime_mode = console",
184  
            "scheduler = local-priority",
185  
            "affinity = pu",
186  
            "pu_step = 1",
187  
            "pu_offset = 0",
188  
            "numa_sensitive = 0",
189  
            "max_background_threads = ${MAX_BACKGROUND_THREADS:$[hpx.os_threads]}",
190  
191  
            // arity for collective operations implemented in a tree fashion
192  
            "[hpx.lcos.collectives]",
193  
            "arity = ${HPX_LCOS_COLLECTIVES_ARITY:32}",
194  
            "cut_off = ${HPX_LCOS_COLLECTIVES_CUT_OFF:256}",
195  
196  
            // connect back to the given latch if specified
197  
            "[hpx.on_startup]",
198  
            "wait_on_latch = ${HPX_ON_STARTUP_WAIT_ON_LATCH}",
199  
200  
            "[hpx.stacks]",
201  
            "small_size = ${HPX_SMALL_STACK_SIZE:"
202  
                BOOST_PP_STRINGIZE(HPX_SMALL_STACK_SIZE) "}",
203  
            "medium_size = ${HPX_MEDIUM_STACK_SIZE:"
204  
                BOOST_PP_STRINGIZE(HPX_MEDIUM_STACK_SIZE) "}",
205  
            "large_size = ${HPX_LARGE_STACK_SIZE:"
206  
                BOOST_PP_STRINGIZE(HPX_LARGE_STACK_SIZE) "}",
207  
            "huge_size = ${HPX_HUGE_STACK_SIZE:"
208  
                BOOST_PP_STRINGIZE(HPX_HUGE_STACK_SIZE) "}",
209  
#if defined(__linux) || defined(linux) || defined(__linux__) || defined(__FreeBSD__)
210  
            "use_guard_pages = ${HPX_USE_GUARD_PAGES:1}",
211  
#endif
212  
213  
            "[hpx.threadpools]",
214  
            "io_pool_size = ${HPX_NUM_IO_POOL_SIZE:"
215  
                BOOST_PP_STRINGIZE(HPX_NUM_IO_POOL_SIZE) "}",
216  
            "parcel_pool_size = ${HPX_NUM_PARCEL_POOL_SIZE:"
217  
                BOOST_PP_STRINGIZE(HPX_NUM_PARCEL_POOL_SIZE) "}",
218  
            "timer_pool_size = ${HPX_NUM_TIMER_POOL_SIZE:"
219  
                BOOST_PP_STRINGIZE(HPX_NUM_TIMER_POOL_SIZE) "}",
220  
221  
            "[hpx.commandline]",
222  
            // enable aliasing
223  
            "aliasing = ${HPX_COMMANDLINE_ALIASING:1}",
224  
225  
            // allow for unknown options to be passed through
226  
            "allow_unknown = ${HPX_COMMANDLINE_ALLOW_UNKNOWN:0}",
227  
228  
            // predefine command line aliases
229  
            "[hpx.commandline.aliases]",
230  
            "-a = --hpx:agas",
231  
            "-c = --hpx:console",
232  
            "-h = --hpx:help",
233  
            "-I = --hpx:ini",
234  
            "-l = --hpx:localities",
235  
            "-p = --hpx:app-config",
236  
            "-q = --hpx:queuing",
237  
            "-r = --hpx:run-agas-server",
238  
            "-t = --hpx:threads",
239  
            "-v = --hpx:version",
240  
            "-w = --hpx:worker",
241  
            "-x = --hpx:hpx",
242  
            "-0 = --hpx:node=0",
243  
            "-1 = --hpx:node=1",
244  
            "-2 = --hpx:node=2",
245  
            "-3 = --hpx:node=3",
246  
            "-4 = --hpx:node=4",
247  
            "-5 = --hpx:node=5",
248  
            "-6 = --hpx:node=6",
249  
            "-7 = --hpx:node=7",
250  
            "-8 = --hpx:node=8",
251  
            "-9 = --hpx:node=9",
252  
253  
            "[hpx.agas]",
254  
            // 'address' has deliberately no default, see
255  
            // command_line_handling.cpp
256  
            "address = ${HPX_AGAS_SERVER_ADDRESS}",
257  
            "port = ${HPX_AGAS_SERVER_PORT:"
258  
                BOOST_PP_STRINGIZE(HPX_INITIAL_IP_PORT) "}",
259  
            "max_pending_refcnt_requests = "
260  
                "${HPX_AGAS_MAX_PENDING_REFCNT_REQUESTS:"
261  
                BOOST_PP_STRINGIZE(HPX_INITIAL_AGAS_MAX_PENDING_REFCNT_REQUESTS)
262  
                "}",
263  
            "service_mode = hosted",
264  
            "dedicated_server = 0",
265  
            "local_cache_size = ${HPX_AGAS_LOCAL_CACHE_SIZE:"
266  
                BOOST_PP_STRINGIZE(HPX_AGAS_LOCAL_CACHE_SIZE) "}",
267  
            "use_range_caching = ${HPX_AGAS_USE_RANGE_CACHING:1}",
268  
            "use_caching = ${HPX_AGAS_USE_CACHING:1}",
269  
270  
            "[hpx.components]",
271  
            "load_external = ${HPX_LOAD_EXTERNAL_COMPONENTS:1}",
272  
273  
            "[hpx.components.barrier]",
274  
            "name = hpx",
275  
            "path = $[hpx.location]/bin/" HPX_DLL_STRING,
276  
            "enabled = 1",
277  
278  
            "[hpx.components.hpx_lcos_server_latch]",
279  
            "name = hpx",
280  
            "path = $[hpx.location]/bin/" HPX_DLL_STRING,
281  
            "enabled = 1",
282  
283  
            "[hpx.components.raw_counter]",
284  
            "name = hpx",
285  
            "path = $[hpx.location]/bin/" HPX_DLL_STRING,
286  
            "enabled = 1",
287  
288  
            "[hpx.components.average_count_counter]",
289  
            "name = hpx",
290  
            "path = $[hpx.location]/bin/" HPX_DLL_STRING,
291  
            "enabled = 1",
292  
293  
            "[hpx.components.elapsed_time_counter]",
294  
            "name = hpx",
295  
            "path = $[hpx.location]/bin/" HPX_DLL_STRING,
296  
            "enabled = 1"
297  
        };
298  
299  
        std::vector<std::string> lines_pp =
300  
            hpx::parcelset::parcelhandler::load_runtime_configuration();
301  
302  
        lines.insert(lines.end(), lines_pp.begin(), lines_pp.end());
303  
304  
        // don't overload user overrides
305  
        this->parse("<static defaults>", lines, false, false);
306  
307  
        need_to_call_pre_initialize = false;
308  
    }
309  
310  
    void runtime_configuration::post_initialize_ini(
311  
        std::string& hpx_ini_file_,
312  
        std::vector<std::string> const& cmdline_ini_defs_)
313  
    {
314  
        // add explicit configuration information if its provided
315  
        if (!hpx_ini_file_.empty()) {
316  
            util::init_ini_data_base(*this, hpx_ini_file_);
317  
            need_to_call_pre_initialize = true;
318  
        }
319  
320  
        // let the command line override the config file.
321  
        if (!cmdline_ini_defs_.empty()) {
322  
            // do not weed out comments
323  
            this->parse("<command line definitions>", cmdline_ini_defs_,
324  
                true, false);
325  
            need_to_call_pre_initialize = true;
326  
        }
327  
    }
328  
329  
    ///////////////////////////////////////////////////////////////////////////
330  
    // load information about statically known components
331  
    void runtime_configuration::load_components_static(std::vector<
332  
        components::static_factory_load_data_type> const& static_modules)
333  
    {
334  
        for (components::static_factory_load_data_type const& d : static_modules)
335  
        {
336  
            util::load_component_factory_static(*this, d.name, d.get_factory);
337  
        }
338  
339  
        // read system and user ini files _again_, to allow the user to
340  
        // overwrite the settings from the default component ini's.
341  
        util::init_ini_data_base(*this, hpx_ini_file);
342  
343  
        // let the command line override the config file.
344  
        if (!cmdline_ini_defs.empty())
345  
            parse("<command line definitions>", cmdline_ini_defs, true, false);
346  
347  
        // merge all found ini files of all components
348  
        util::merge_component_inis(*this);
349  
350  
        need_to_call_pre_initialize = true;
351  
352  
        // invoke last reconfigure
353  
        reconfigure();
354  
    }
355  
356  
    // load information about dynamically discovered plugins
357  
    std::vector<std::shared_ptr<plugins::plugin_registry_base> >
358  
    runtime_configuration::load_modules()
359  
    {
360  
        typedef std::vector<std::shared_ptr<plugins::plugin_registry_base> >
361  
            plugin_list_type;
362  
363  
        namespace fs = boost::filesystem;
364  
365  
        // try to build default ini structure from shared libraries in default
366  
        // installation location, this allows to install simple components
367  
        // without the need to install an ini file
368  
        // split of the separate paths from the given path list
369  
        typedef boost::tokenizer<boost::char_separator<char> > tokenizer_type;
370  
371  
        std::string component_path(
372  
            get_entry("hpx.component_path", HPX_DEFAULT_COMPONENT_PATH));
373  
374  
        std::string component_path_suffixes(
375  
            get_entry("hpx.component_path_suffixes", "/lib/hpx"));
376  
377  
        // protect against duplicate paths
378  
        std::set<std::string> component_paths;
379  
380  
        // list of base names avoiding to load a module more than once
381  
        std::map<std::string, fs::path> basenames;
382  
383  
        boost::char_separator<char> sep (HPX_INI_PATH_DELIMITER);
384  
        tokenizer_type tok_path(component_path, sep);
385  
        tokenizer_type tok_suffixes(component_path_suffixes, sep);
386  
        tokenizer_type::iterator end_path = tok_path.end();
387  
        tokenizer_type::iterator end_suffixes = tok_suffixes.end();
388  
        plugin_list_type plugin_registries;
389  
390  
        for (tokenizer_type::iterator it = tok_path.begin(); it != end_path; ++it)
391  
        {
392  
            std::string p = *it;
393  
            for(tokenizer_type::iterator jt = tok_suffixes.begin();
394  
                jt != end_suffixes; ++jt)
395  
            {
396  
                std::string path(p);
397  
                path += *jt;
398  
399  
                if (!path.empty()) {
400  
                    fs::path this_p(path);
401  
                    boost::system::error_code fsec;
402  
                    fs::path canonical_p = util::canonical_path(this_p, fsec);
403  
                    if (fsec)
404  
                        canonical_p = this_p;
405  
406  
                    std::pair<std::set<std::string>::iterator, bool> p =
407  
                        component_paths.insert(
408  
                            util::native_file_string(canonical_p));
409  
410  
                    if (p.second) {
411  
                        // have all path elements, now find ini files in there...
412  
                        fs::path this_path (hpx::util::create_path(*p.first));
413  
                        if (fs::exists(this_path, fsec) && !fsec) {
414  
                            plugin_list_type tmp_regs =
415  
                                util::init_ini_data_default(
416  
                                    this_path.string(), *this, basenames, modules_);
417  
418  
                            std::copy(tmp_regs.begin(), tmp_regs.end(),
419  
                                std::back_inserter(plugin_registries));
420  
                        }
421  
                    }
422  
                }
423  
            }
424  
        }
425  
426  
        // read system and user ini files _again_, to allow the user to
427  
        // overwrite the settings from the default component ini's.
428  
        util::init_ini_data_base(*this, hpx_ini_file);
429  
430  
        // let the command line override the config file.
431  
        if (!cmdline_ini_defs.empty())
432  
            parse("<command line definitions>", cmdline_ini_defs, true, false);
433  
434  
        // merge all found ini files of all components
435  
        util::merge_component_inis(*this);
436  
437  
        need_to_call_pre_initialize = true;
438  
439  
        // invoke reconfigure
440  
        reconfigure();
441  
442  
        return plugin_registries;
443  
    }
444  
445  
    ///////////////////////////////////////////////////////////////////////////
446  
    runtime_configuration::runtime_configuration(char const* argv0_)
447  
      : num_localities(0),
448  
        small_stacksize(HPX_SMALL_STACK_SIZE),
449  
        medium_stacksize(HPX_MEDIUM_STACK_SIZE),
450  
        large_stacksize(HPX_LARGE_STACK_SIZE),
451  
        huge_stacksize(HPX_HUGE_STACK_SIZE),
452  
        need_to_call_pre_initialize(true)
453  
#if defined(__linux) || defined(linux) || defined(__linux__)
454  
      , argv0(argv0_)
455  
#endif
456  
    {
457  
        pre_initialize_ini();
458  
459  
        // set global config options
460  
#ifdef HPX_HAVE_ITTNOTIFY
461  
        use_ittnotify_api = get_itt_notify_mode();
462  
#endif
463  
        HPX_ASSERT(init_small_stack_size() >= HPX_SMALL_STACK_SIZE);
464  
465  
        small_stacksize = init_small_stack_size();
466  
        medium_stacksize = init_medium_stack_size();
467  
        large_stacksize = init_large_stack_size();
468  
        HPX_ASSERT(init_huge_stack_size() <= HPX_HUGE_STACK_SIZE);
469  
        huge_stacksize = init_huge_stack_size();
470  
471  
#if defined(__linux) || defined(linux) || defined(__linux__) || defined(__FreeBSD__)
472  
        threads::coroutines::detail::posix::use_guard_pages =
473  
            init_use_stack_guard_pages();
474  
#endif
475  
#ifdef HPX_HAVE_VERIFY_LOCKS
476  
        if (enable_lock_detection())
477  
            util::enable_lock_detection();
478  
#endif
479  
#ifdef HPX_HAVE_VERIFY_LOCKS_GLOBALLY
480  
        if (enable_global_lock_detection())
481  
            util::enable_global_lock_detection();
482  
#endif
483  
#ifdef HPX_HAVE_THREAD_MINIMAL_DEADLOCK_DETECTION
484  
        threads::policies::minimal_deadlock_detection =
485  
            enable_minimal_deadlock_detection();
486  
#endif
487  
#ifdef HPX_HAVE_SPINLOCK_DEADLOCK_DETECTION
488  
        lcos::local::spinlock_break_on_deadlock =
489  
            enable_spinlock_deadlock_detection();
490  
        lcos::local::spinlock_deadlock_detection_limit =
491  
            get_spinlock_deadlock_detection_limit();
492  
#endif
493  
    }
494  
495  
    ///////////////////////////////////////////////////////////////////////////
496  
    void runtime_configuration::reconfigure(
497  
        std::string const& hpx_ini_file_)
498  
    {
499  
        hpx_ini_file = hpx_ini_file_;
500  
        reconfigure();
501  
    }
502  
503  
    void runtime_configuration::reconfigure(
504  
        std::vector<std::string> const& cmdline_ini_defs_)
505  
    {
506  
        cmdline_ini_defs = cmdline_ini_defs_;
507  
        reconfigure();
508  
    }
509  
510  
    void runtime_configuration::reconfigure()
511  
    {
512  
        pre_initialize_ini();
513  
514  
        std::vector<std::string> const& prefill =
515  
            util::detail::get_logging_data();
516  
        if (!prefill.empty())
517  
            this->parse("<static prefill defaults>", prefill, false, false);
518  
519  
        post_initialize_ini(hpx_ini_file, cmdline_ini_defs);
520  
521  
        // set global config options
522  
#ifdef HPX_HAVE_ITTNOTIFY
523  
        use_ittnotify_api = get_itt_notify_mode();
524  
#endif
525  
        HPX_ASSERT(init_small_stack_size() >= HPX_SMALL_STACK_SIZE);
526  
527  
        small_stacksize = init_small_stack_size();
528  
        medium_stacksize = init_medium_stack_size();
529  
        large_stacksize = init_large_stack_size();
530  
        huge_stacksize = init_huge_stack_size();
531  
532  
#if defined(__linux) || defined(linux) || defined(__linux__) || defined(__FreeBSD__)
533  
        threads::coroutines::detail::posix::use_guard_pages =
534  
            init_use_stack_guard_pages();
535  
#endif
536  
#ifdef HPX_HAVE_VERIFY_LOCKS
537  
        if (enable_lock_detection())
538  
            util::enable_lock_detection();
539  
#endif
540  
#ifdef HPX_HAVE_VERIFY_LOCKS_GLOBALLY
541  
        if (enable_global_lock_detection())
542  
            util::enable_global_lock_detection();
543  
#endif
544  
#ifdef HPX_HAVE_THREAD_MINIMAL_DEADLOCK_DETECTION
545  
        threads::policies::minimal_deadlock_detection =
546  
            enable_minimal_deadlock_detection();
547  
#endif
548  
#ifdef HPX_HAVE_SPINLOCK_DEADLOCK_DETECTION
549  
        lcos::local::spinlock_break_on_deadlock =
550  
            enable_spinlock_deadlock_detection();
551  
        lcos::local::spinlock_deadlock_detection_limit =
552  
            get_spinlock_deadlock_detection_limit();
553  
#endif
554  
    }
555  
556  
    std::size_t runtime_configuration::get_ipc_data_buffer_cache_size() const
557  
    {
558  
        if (has_section("hpx.parcel"))
559  
        {
560  
            util::section const * sec = get_section("hpx.parcel.ipc");
561  
            if(nullptr != sec)
562  
            {
563  
                return hpx::util::get_entry_as<std::size_t>(
564  
                    *sec, "data_buffer_cache_size",
565  
                    HPX_PARCEL_IPC_DATA_BUFFER_CACHE_SIZE);
566  
            }
567  
        }
568  
        return HPX_PARCEL_IPC_DATA_BUFFER_CACHE_SIZE;
569  
    }
570  
571  
    agas::service_mode runtime_configuration::get_agas_service_mode() const
572  
    {
573  
        // load all components as described in the configuration information
574  
        if (has_section("hpx.agas"))
575  
        {
576  
            util::section const* sec = get_section("hpx.agas");
577  
            if (nullptr != sec)
578  
            {
579  
                std::string const m = sec->get_entry("service_mode", "hosted");
580  
581  
                if (m == "hosted")
582  
                    return agas::service_mode_hosted;
583  
                else if (m == "bootstrap")
584  
                    return agas::service_mode_bootstrap;
585  
                else {
586  
                    // REVIEW: exception type is overused
587  
                    HPX_THROW_EXCEPTION(bad_parameter,
588  
                        "runtime_configuration::get_agas_service_mode",
589  
                        std::string("invalid AGAS router mode \"") + m + "\"");
590  
                }
591  
            }
592  
        }
593  
        return agas::service_mode_hosted;
594  
    }
595  
596  
    std::uint32_t runtime_configuration::get_num_localities() const
597  
    {
598  
        if (num_localities == 0) {
599  
            if (has_section("hpx")) {
600  
                util::section const* sec = get_section("hpx");
601  
                if (nullptr != sec) {
602  
                    num_localities = hpx::util::get_entry_as<std::uint32_t>(
603  
                        *sec, "localities", 1);
604  
                }
605  
            }
606  
        }
607  
608  
        HPX_ASSERT(num_localities != 0);
609  
        return num_localities;
610  
    }
611  
612  
    void runtime_configuration::set_num_localities(std::uint32_t num_localities_)
613  
    {
614  
        // this function should not be called on the AGAS server
615  
        HPX_ASSERT(agas::service_mode_bootstrap != get_agas_service_mode());
616  
        num_localities = num_localities_;
617  
618  
        if (has_section("hpx")) {
619  
            util::section* sec = get_section("hpx");
620  
            if (nullptr != sec) {
621  
                sec->add_entry("localities",
622  
                    std::to_string(num_localities));
623  
            }
624  
        }
625  
    }
626  
627  
    std::uint32_t runtime_configuration::get_first_used_core() const
628  
    {
629  
        if (has_section("hpx")) {
630  
            util::section const* sec = get_section("hpx");
631  
            if (nullptr != sec) {
632  
                return hpx::util::get_entry_as<std::uint32_t>(
633  
                    *sec, "first_used_core", 0);
634  
            }
635  
        }
636  
        return 0;
637  
    }
638  
639  
    void runtime_configuration::set_first_used_core(
640  
        std::uint32_t first_used_core)
641  
    {
642  
        if (has_section("hpx")) {
643  
            util::section* sec = get_section("hpx");
644  
            if (nullptr != sec) {
645  
                sec->add_entry("first_used_core",
646  
                    std::to_string(first_used_core));
647  
            }
648  
        }
649  
    }
650  
651  
    std::size_t runtime_configuration::get_agas_local_cache_size(std::size_t dflt) const
652  
    {
653  
        std::size_t cache_size = dflt;
654  
655  
        if (has_section("hpx.agas")) {
656  
            util::section const* sec = get_section("hpx.agas");
657  
            if (nullptr != sec) {
658  
                cache_size = hpx::util::get_entry_as<std::size_t>(
659  
                    *sec, "local_cache_size", cache_size);
660  
            }
661  
        }
662  
663  
        if (cache_size != std::size_t(~0x0ul) && cache_size < 16ul)
664  
            cache_size = 16;      // limit lower bound
665  
        return cache_size;
666  
    }
667  
668  
    bool runtime_configuration::get_agas_caching_mode() const
669  
    {
670  
        if (has_section("hpx.agas")) {
671  
            util::section const* sec = get_section("hpx.agas");
672  
            if (nullptr != sec) {
673  
                return hpx::util::get_entry_as<int>(
674  
                    *sec, "use_caching", "1") != 0;
675  
            }
676  
        }
677  
        return false;
678  
    }
679  
680  
    bool runtime_configuration::get_agas_range_caching_mode() const
681  
    {
682  
        if (has_section("hpx.agas")) {
683  
            util::section const* sec = get_section("hpx.agas");
684  
            if (nullptr != sec) {
685  
                return hpx::util::get_entry_as<int>(
686  
                    *sec, "use_range_caching", "1") != 0;
687  
            }
688  
        }
689  
        return false;
690  
    }
691  
692  
    std::size_t
693  
    runtime_configuration::get_agas_max_pending_refcnt_requests() const
694  
    {
695  
        if (has_section("hpx.agas")) {
696  
            util::section const* sec = get_section("hpx.agas");
697  
            if (nullptr != sec) {
698  
                return hpx::util::get_entry_as<std::size_t>(
699  
                    *sec, "max_pending_refcnt_requests",
700  
                    HPX_INITIAL_AGAS_MAX_PENDING_REFCNT_REQUESTS);
701  
            }
702  
        }
703  
        return HPX_INITIAL_AGAS_MAX_PENDING_REFCNT_REQUESTS;
704  
    }
705  
706  
    // Get whether the AGAS server is running as a dedicated runtime.
707  
    // This decides whether the AGAS actions are executed with normal
708  
    // priority (if dedicated) or with high priority (non-dedicated)
709  
    bool runtime_configuration::get_agas_dedicated_server() const
710  
    {
711  
        if (has_section("hpx.agas")) {
712  
            util::section const* sec = get_section("hpx.agas");
713  
            if (nullptr != sec) {
714  
                return hpx::util::get_entry_as<int>(
715  
                    *sec, "dedicated_server", 0) != 0;
716  
            }
717  
        }
718  
        return false;
719  
    }
720  
721  
    bool runtime_configuration::get_itt_notify_mode() const
722  
    {
723  
#if HPX_HAVE_ITTNOTIFY != 0
724  
        if (has_section("hpx")) {
725  
            util::section const* sec = get_section("hpx");
726  
            if (nullptr != sec) {
727  
                return hpx::util::get_entry_as<int>(
728  
                    *sec, "use_itt_notify", "0") != 0;
729  
            }
730  
        }
731  
#endif
732  
        return false;
733  
    }
734  
735  
    // Enable lock detection during suspension
736  
    bool runtime_configuration::enable_lock_detection() const
737  
    {
738  
#ifdef HPX_HAVE_VERIFY_LOCKS
739  
        if (has_section("hpx")) {
740  
            util::section const* sec = get_section("hpx");
741  
            if (nullptr != sec) {
742  
                return hpx::util::get_entry_as<int>(
743  
                    *sec, "lock_detection", "0") != 0;
744  
            }
745  
        }
746  
#endif
747  
        return false;
748  
    }
749  
750  
    // Enable global lock tracking
751  
    bool runtime_configuration::enable_global_lock_detection() const
752  
    {
753  
#ifdef HPX_HAVE_VERIFY_LOCKS_GLOBALLY
754  
        if (has_section("hpx")) {
755  
            util::section const* sec = get_section("hpx");
756  
            if (nullptr != sec) {
757  
                return hpx::util::get_entry_as<int>(
758  
                    *sec, "global_lock_detection", "0") != 0;
759  
            }
760  
        }
761  
#endif
762  
        return false;
763  
    }
764  
765  
    // Enable minimal deadlock detection for HPX threads
766  
    bool runtime_configuration::enable_minimal_deadlock_detection() const
767  
    {
768  
#ifdef HPX_HAVE_THREAD_MINIMAL_DEADLOCK_DETECTION
769  
        if (has_section("hpx")) {
770  
            util::section const* sec = get_section("hpx");
771  
            if (nullptr != sec) {
772  
#ifdef HPX_DEBUG
773  
                return hpx::util::get_entry_as<int>(
774  
                    *sec, "minimal_deadlock_detection", "1") != 0;
775  
#else
776  
                return hpx::util::get_entry_as<int>(
777  
                    *sec, "minimal_deadlock_detection", "0") != 0;
778  
#endif
779  
            }
780  
        }
781  
782  
#ifdef HPX_DEBUG
783  
        return true;
784  
#else
785  
        return false;
786  
#endif
787  
788  
#else
789  
        return false;
790  
#endif
791  
    }
792  
793  
    ///////////////////////////////////////////////////////////////////////////
794  
    bool runtime_configuration::enable_spinlock_deadlock_detection() const
795  
    {
796  
#ifdef HPX_HAVE_SPINLOCK_DEADLOCK_DETECTION
797  
        if (has_section("hpx")) {
798  
            util::section const* sec = get_section("hpx");
799  
            if (nullptr != sec) {
800  
#ifdef HPX_DEBUG
801  
                return hpx::util::get_entry_as<int>(
802  
                    *sec, "spinlock_deadlock_detection", "1") != 0;
803  
#else
804  
                return hpx::util::get_entry_as<int>(
805  
                    *sec, "spinlock_deadlock_detection", "0") != 0;
806  
#endif
807  
            }
808  
        }
809  
810  
#ifdef HPX_DEBUG
811  
        return true;
812  
#else
813  
        return false;
814  
#endif
815  
816  
#else
817  
        return false;
818  
#endif
819  
    }
820  
821  
    ///////////////////////////////////////////////////////////////////////////
822  
    std::size_t runtime_configuration::get_spinlock_deadlock_detection_limit() const
823  
    {
824  
#ifdef HPX_HAVE_SPINLOCK_DEADLOCK_DETECTION
825  
        if (has_section("hpx")) {
826  
            util::section const* sec = get_section("hpx");
827  
            if (nullptr != sec) {
828  
                return hpx::util::get_entry_as<std::size_t>(
829  
                    *sec, "spinlick_deadlock_detection_limit", "1000000");
830  
            }
831  
        }
832  
        return HPX_SPINLOCK_DEADLOCK_DETECTION_LIMIT;
833  
#else
834  
        return std::size_t(-1);
835  
#endif
836  
    }
837  
838  
    std::size_t runtime_configuration::get_os_thread_count() const
839  
    {
840  
        if (has_section("hpx")) {
841  
            util::section const* sec = get_section("hpx");
842  
            if (nullptr != sec) {
843  
                return hpx::util::get_entry_as<std::size_t>(
844  
                    *sec, "os_threads", 1);
845  
            }
846  
        }
847  
        return 1;
848  
    }
849  
850  
    std::string runtime_configuration::get_cmd_line() const
851  
    {
852  
        if (has_section("hpx")) {
853  
            util::section const* sec = get_section("hpx");
854  
            if (nullptr != sec) {
855  
                return sec->get_entry("cmd_line", "");
856  
            }
857  
        }
858  
        return "";
859  
    }
860  
861  
    // Return the configured sizes of any of the know thread pools
862  
    std::size_t runtime_configuration::get_thread_pool_size(char const* poolname) const
863  
    {
864  
        if (has_section("hpx.threadpools")) {
865  
            util::section const* sec = get_section("hpx.threadpools");
866  
            if (nullptr != sec) {
867  
                return hpx::util::get_entry_as<std::size_t>(
868  
                    *sec, std::string(poolname) + "_size", "2");
869  
            }
870  
        }
871  
        return 2;     // the default size for all pools is 2
872  
    }
873  
874  
    // Return the endianess to be used for out-serialization
875  
    std::string runtime_configuration::get_endian_out() const
876  
    {
877  
        if (has_section("hpx.parcel")) {
878  
            util::section const* sec = get_section("hpx.parcel");
879  
            if (nullptr != sec) {
880  
#ifdef BOOST_BIG_ENDIAN
881  
                return sec->get_entry("endian_out", "big");
882  
#else
883  
                return sec->get_entry("endian_out", "little");
884  
#endif
885  
            }
886  
        }
887  
#ifdef BOOST_BIG_ENDIAN
888  
        return "big";
889  
#else
890  
        return "little";
891  
#endif
892  
    }
893  
894  
    // Will return the stack size to use for all HPX-threads.
895  
    std::ptrdiff_t runtime_configuration::init_stack_size(
896  
        char const* entryname, char const* defaultvaluestr,
897  
        std::ptrdiff_t defaultvalue) const
898  
    {
899  
        if (has_section("hpx")) {
900  
            util::section const* sec = get_section("hpx.stacks");
901  
            if (nullptr != sec) {
902  
                std::string entry = sec->get_entry(entryname, defaultvaluestr);
903  
                std::ptrdiff_t val = defaultvalue;
904  
905  
                namespace qi = boost::spirit::qi;
906  
                qi::parse(entry.begin(), entry.end(),
907  
                    "0x" >> qi::hex | "0" >> qi::oct | qi::int_, val);
908  
                return val;
909  
            }
910  
        }
911  
        return defaultvalue;
912  
    }
913  
914  
#if defined(__linux) || defined(linux) || defined(__linux__) || defined(__FreeBSD__)
915  
    bool runtime_configuration::init_use_stack_guard_pages() const
916  
    {
917  
        if (has_section("hpx")) {
918  
            util::section const* sec = get_section("hpx.stacks");
919  
            if (nullptr != sec) {
920  
                return hpx::util::get_entry_as<int>(
921  
                    *sec, "use_guard_pages", "1") != 0;
922  
            }
923  
        }
924  
        return true;    // default is true
925  
    }
926  
#endif
927  
928  
    std::ptrdiff_t runtime_configuration::init_small_stack_size() const
929  
    {
930  
        return init_stack_size("small_size",
931  
            BOOST_PP_STRINGIZE(HPX_SMALL_STACK_SIZE), HPX_SMALL_STACK_SIZE);
932  
    }
933  
934  
    std::ptrdiff_t runtime_configuration::init_medium_stack_size() const
935  
    {
936  
        return init_stack_size("medium_size",
937  
            BOOST_PP_STRINGIZE(HPX_MEDIUM_STACK_SIZE), HPX_MEDIUM_STACK_SIZE);
938  
    }
939  
940  
    std::ptrdiff_t runtime_configuration::init_large_stack_size() const
941  
    {
942  
        return init_stack_size("large_size",
943  
            BOOST_PP_STRINGIZE(HPX_LARGE_STACK_SIZE), HPX_LARGE_STACK_SIZE);
944  
    }
945  
946  
    std::ptrdiff_t runtime_configuration::init_huge_stack_size() const
947  
    {
948  
        return init_stack_size("huge_size",
949  
            BOOST_PP_STRINGIZE(HPX_HUGE_STACK_SIZE), HPX_HUGE_STACK_SIZE);
950  
    }
951  
952  
    ///////////////////////////////////////////////////////////////////////////
953  
    // Return maximally allowed message size
954  
    std::uint64_t runtime_configuration::get_max_inbound_message_size() const
955  
    {
956  
        if (has_section("hpx")) {
957  
            util::section const* sec = get_section("hpx.parcel");
958  
            if (nullptr != sec) {
959  
                std::uint64_t maxsize =
960  
                    hpx::util::get_entry_as<std::uint64_t>(
961  
                        *sec, "max_message_size", HPX_PARCEL_MAX_MESSAGE_SIZE);
962  
                if (maxsize > 0)
963  
                    return maxsize;
964  
            }
965  
        }
966  
        return HPX_PARCEL_MAX_MESSAGE_SIZE;    // default is 1GByte
967  
    }
968  
969  
    std::uint64_t runtime_configuration::get_max_outbound_message_size() const
970  
    {
971  
        if (has_section("hpx")) {
972  
            util::section const* sec = get_section("hpx.parcel");
973  
            if (nullptr != sec) {
974  
                std::uint64_t maxsize =
975  
                    hpx::util::get_entry_as<std::uint64_t>(
976  
                        *sec, "max_outbound_message_size",
977  
                        HPX_PARCEL_MAX_OUTBOUND_MESSAGE_SIZE);
978  
                if (maxsize > 0)
979  
                    return maxsize;
980  
            }
981  
        }
982  
        return HPX_PARCEL_MAX_OUTBOUND_MESSAGE_SIZE;    // default is 1GByte
983  
    }
984  
985  
    ///////////////////////////////////////////////////////////////////////////
986  
    bool runtime_configuration::load_application_configuration(
987  
        char const* filename, error_code& ec)
988  
    {
989  
        try {
990  
            section appcfg(filename);
991  
            section applroot;
992  
            applroot.add_section("application", appcfg);
993  
            this->section::merge(applroot);
994  
        }
995  
        catch (hpx::exception const& e) {
996  
            // file doesn't exist or is ill-formed
997  
            if (&ec == &throws)
998  
                throw;
999  
            ec = make_error_code(e.get_error(), e.what(), hpx::rethrow);
1000  
            return false;
1001  
        }
1002  
        return true;
1003  
    }
1004  
1005  
    ///////////////////////////////////////////////////////////////////////////
1006  
    std::ptrdiff_t runtime_configuration::get_stack_size(
1007  
        threads::thread_stacksize stacksize) const
1008  
    {
1009  
        switch (stacksize) {
1010  
        case threads::thread_stacksize_medium:
1011  
            return medium_stacksize;
1012  
1013  
        case threads::thread_stacksize_large:
1014  
            return large_stacksize;
1015  
1016  
        case threads::thread_stacksize_huge:
1017  
            return huge_stacksize;
1018  
1019  
        default:
1020  
        case threads::thread_stacksize_small:
1021  
            break;
1022  
        }
1023  
        return small_stacksize;
1024  
    }
1025  
}}
1026  
1027  

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