1 //  Copyright (c)      2014 Thomas Heller
2 //  Copyright (c) 2007-2017 Hartmut Kaiser
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 // make inspect happy: hpxinspect:nodeprecatedname:boost::is_any_of
8 
9 #if !defined(HPX_PLUGINS_PARCELPORT_FACTORY_HPP)
10 #define HPX_PLUGINS_PARCELPORT_FACTORY_HPP
11 
12 #include <hpx/config.hpp>
13 #include <hpx/plugins/parcelport_factory_base.hpp>
14 #include <hpx/plugins/plugin_factory_base.hpp>
15 #include <hpx/plugins/unique_plugin_name.hpp>
16 #include <hpx/runtime/parcelset/parcelhandler.hpp>
17 #include <hpx/traits/plugin_config_data.hpp>
18 #include <hpx/util/detail/pp/cat.hpp>
19 #include <hpx/util/find_prefix.hpp>
20 #include <hpx/util/runtime_configuration.hpp>
21 
22 #include <boost/algorithm/string/classification.hpp>
23 #include <boost/algorithm/string/split.hpp>
24 #include <boost/assign/std/vector.hpp>
25 
26 #include <cstddef>
27 #include <string>
28 #include <vector>
29 
30 ///////////////////////////////////////////////////////////////////////////////
31 namespace hpx { namespace plugins
32 {
33     ///////////////////////////////////////////////////////////////////////////
34     /// The \a parcelport_factory provides a minimal implementation of a
35     /// parcelport's factory. If no additional functionality is required
36     /// this type can be used to implement the full set of minimally required
37     /// functions to be exposed by a parcelports's factory instance.
38     ///
39     /// \tparam Parcelport The parcelport type this factory should be
40     ///                        responsible for.
41     template <typename Parcelport>
42     struct parcelport_factory : public parcelport_factory_base
43     {
44         /// \brief Construct a new factory instance
45         ///
46         /// \param global   [in] The pointer to a \a hpx#util#section instance
47         ///                 referencing the settings read from the [settings]
48         ///                 section of the global configuration file (hpx.ini)
49         ///                 This pointer may be nullptr if no such section has
50         ///                 been found.
51         /// \param local    [in] The pointer to a \a hpx#util#section instance
52         ///                 referencing the settings read from the section
53         ///                 describing this component type:
54         ///                 [hpx.components.\<name\>], where \<name\> is the
55         ///                 instance name of the component as given in the
56         ///                 configuration files.
57         ///
58         /// \note The contents of both sections has to be cloned in order to
59         ///       save the configuration setting for later use.
parcelport_factoryhpx::plugins::parcelport_factory60         parcelport_factory()
61         {
62             parcelset::parcelhandler::add_parcelport_factory(this);
63         }
64 
parcelport_factoryhpx::plugins::parcelport_factory65         parcelport_factory(
66             std::vector<plugins::parcelport_factory_base*>& factories)
67         {
68             factories.push_back(this);
69         }
70 
71         ///
~parcelport_factoryhpx::plugins::parcelport_factory72         ~parcelport_factory() override {}
73 
get_plugin_infohpx::plugins::parcelport_factory74         void get_plugin_info(std::vector<std::string> & fillini) override
75         {
76             using namespace boost::assign;
77             std::string name = unique_plugin_name<parcelport_factory>::call();
78             fillini += std::string("[hpx.parcel.") + name + "]";
79             fillini += "name = " HPX_PLUGIN_STRING;
80             fillini += std::string("path = ") +
81                 util::find_prefixes("/hpx", HPX_PLUGIN_STRING);
82             fillini += "enable = $[hpx.parcel.enable]";
83 
84             std::string name_uc = boost::to_upper_copy(name);
85             // basic parcelport configuration ...
86             fillini +=
87                 "parcel_pool_size = ${HPX_PARCEL_" + name_uc + "_PARCEL_POOL_SIZE:"
88                     "$[hpx.threadpools.parcel_pool_size]}",
89                 "max_connections =  ${HPX_PARCEL_" + name_uc + "_MAX_CONNECTIONS:"
90                     "$[hpx.parcel.max_connections]}",
91                 "max_connections_per_locality = "
92                     "${HPX_PARCEL_" + name_uc + "_MAX_CONNECTIONS_PER_LOCALITY:"
93                     "$[hpx.parcel.max_connections_per_locality]}",
94                 "max_message_size =  ${HPX_PARCEL_" + name_uc +
95                     "_MAX_MESSAGE_SIZE:$[hpx.parcel.max_message_size]}",
96                 "max_outbound_message_size =  ${HPX_PARCEL_" + name_uc +
97                     "_MAX_OUTBOUND_MESSAGE_SIZE"
98                     + ":$[hpx.parcel.max_outbound_message_size]}",
99                 "array_optimization = ${HPX_PARCEL_" + name_uc +
100                     "_ARRAY_OPTIMIZATION:$[hpx.parcel.array_optimization]}",
101                 "zero_copy_optimization = ${HPX_PARCEL_" + name_uc +
102                     "_ZERO_COPY_OPTIMIZATION:"
103                     "$[hpx.parcel.zero_copy_optimization]}",
104                 "async_serialization = ${HPX_PARCEL_" + name_uc +
105                     "_ASYNC_SERIALIZATION:"
106                     "$[hpx.parcel.async_serialization]}",
107                 "priority = ${HPX_PARCEL_" + name_uc +
108                     "_PRIORITY:" + traits::plugin_config_data<Parcelport>::priority()
109                                  + "}"
110                 ;
111 
112             // get the parcelport specific information ...
113             char const* more = traits::plugin_config_data<Parcelport>::call();
114             if (more) {
115                 std::vector<std::string> data;
116                 boost::split(data, more, boost::is_any_of("\n"));
117                 std::copy(data.begin(), data.end(), std::back_inserter(fillini));
118             }
119         }
120 
inithpx::plugins::parcelport_factory121         void init(int* argc, char*** argv,
122             util::command_line_handling& cfg) override
123         {
124             // initialize the parcelport with the parameters we got passed in at start
125             traits::plugin_config_data<Parcelport>::init(argc, argv, cfg);
126         }
127 
128         /// Create a new instance of a message handler
129         ///
130         /// return Returns the newly created instance of the message handler
131         ///        supported by this factory
createhpx::plugins::parcelport_factory132         parcelset::parcelport* create(
133             hpx::util::runtime_configuration const& cfg,
134             hpx::util::function_nonser<void(std::size_t, char const*)> const&
135                 on_start_thread,
136             hpx::util::function_nonser<void(std::size_t, char const*)> const&
137                 on_stop_thread) override
138         {
139             return new Parcelport(cfg, on_start_thread, on_stop_thread);
140         }
141     };
142 }}
143 
144 ///////////////////////////////////////////////////////////////////////////////
145 /// This macro is used create and to register a minimal component factory with
146 /// Hpx.Plugin.
147 #define HPX_REGISTER_PARCELPORT_(Parcelport, pluginname, pp)                  \
148     typedef hpx::plugins::parcelport_factory<Parcelport>                      \
149         HPX_PP_CAT(pluginname, _plugin_factory_type);                         \
150     HPX_DEF_UNIQUE_PLUGIN_NAME(                                               \
151         HPX_PP_CAT(pluginname, _plugin_factory_type), pp)                     \
152     template struct hpx::plugins::parcelport_factory<Parcelport>;             \
153     HPX_EXPORT hpx::plugins::parcelport_factory_base*                         \
154     HPX_PP_CAT(pluginname, _factory_init)                                     \
155     (std::vector<hpx::plugins::parcelport_factory_base *>& factories)         \
156     {                                                                         \
157         static HPX_PP_CAT(pluginname, _plugin_factory_type) factory(factories);\
158         return &factory;                                                      \
159     }                                                                         \
160 /**/
161 
162 #define HPX_REGISTER_PARCELPORT(Parcelport, pluginname)                       \
163         HPX_REGISTER_PARCELPORT_(Parcelport,                                  \
164             HPX_PP_CAT(parcelport_, pluginname), pluginname)                  \
165 
166 #endif
167 
168