1 ////////////////////////////////////////////////////////////////////////////////
2 //  Copyright (c) 2011 Bryce Adelstein-Lelbach
3 //  Copyright (c) 2012-2013 Hartmut Kaiser
4 //  Copyright (c) 2016 Thomas Heller
5 //
6 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
7 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 ////////////////////////////////////////////////////////////////////////////////
9 
10 #if !defined(HPX_AGAS_LOCALITY_NAMESPACE_APR_04_2013_1107AM)
11 #define HPX_AGAS_LOCALITY_NAMESPACE_APR_04_2013_1107AM
12 
13 #include <hpx/config.hpp>
14 #include <hpx/exception_fwd.hpp>
15 #include <hpx/lcos/local/spinlock.hpp>
16 #include <hpx/runtime/actions/component_action.hpp>
17 #include <hpx/runtime/components/server/fixed_component_base.hpp>
18 #include <hpx/runtime/parcelset/locality.hpp>
19 
20 #include <atomic>
21 #include <cstdint>
22 #include <map>
23 #include <string>
24 #include <vector>
25 
26 #include <hpx/config/warnings_prefix.hpp>
27 
28 namespace hpx { namespace agas
29 {
30 
31 HPX_EXPORT naming::gid_type bootstrap_locality_namespace_gid();
32 HPX_EXPORT naming::id_type bootstrap_locality_namespace_id();
33 
34 namespace server
35 {
36 
37 // Base name used to register the component
38 char const* const locality_namespace_service_name = "locality/";
39 
40 struct HPX_EXPORT locality_namespace
41   : components::fixed_component_base<locality_namespace>
42 {
43     // {{{ nested types
44     typedef lcos::local::spinlock mutex_type;
45     typedef components::fixed_component_base<locality_namespace> base_type;
46 
47     typedef std::int32_t component_type;
48 
49     // stores the locality endpoints, and number of OS-threads running on this locality
50     typedef hpx::util::tuple<
51         parcelset::endpoints_type, std::uint32_t>
52     partition_type;
53 
54     typedef std::map<std::uint32_t, partition_type> partition_table_type;
55     // }}}
56 
57   private:
58     // REVIEW: Separate mutexes might reduce contention here. This has to be
59     // investigated carefully.
60     mutex_type mutex_;
61     std::string instance_name_;
62 
63     partition_table_type partitions_;
64     std::uint32_t prefix_counter_;
65     primary_namespace* primary_;
66 
67     struct update_time_on_exit;
68 
69     // data structure holding all counters for the omponent_namespace component
70     struct counter_data
71     {
72     public:
73         HPX_NON_COPYABLE(counter_data);
74 
75     public:
76         typedef lcos::local::spinlock mutex_type;
77 
78         struct api_counter_data
79         {
api_counter_datahpx::agas::server::locality_namespace::counter_data::api_counter_data80             api_counter_data()
81               : count_(0)
82               , time_(0)
83               , enabled_(false)
84             {}
85 
86             std::atomic<std::int64_t> count_;
87             std::atomic<std::int64_t> time_;
88             bool enabled_;
89         };
90 
91         counter_data() = default;
92 
93     public:
94         // access current counter values
95         std::int64_t get_allocate_count(bool);
96         std::int64_t get_resolve_locality_count(bool);
97         std::int64_t get_free_count(bool);
98         std::int64_t get_localities_count(bool);
99         std::int64_t get_num_localities_count(bool);
100         std::int64_t get_num_threads_count(bool);
101         std::int64_t get_resolved_localities_count(bool);
102         std::int64_t get_overall_count(bool);
103 
104         std::int64_t get_allocate_time(bool);
105         std::int64_t get_resolve_locality_time(bool);
106         std::int64_t get_free_time(bool);
107         std::int64_t get_localities_time(bool);
108         std::int64_t get_num_localities_time(bool);
109         std::int64_t get_num_threads_time(bool);
110         std::int64_t get_resolved_localities_time(bool);
111         std::int64_t get_overall_time(bool);
112 
113         // increment counter values
114         void increment_allocate_count();
115         void increment_resolve_locality_count();
116         void increment_free_count();
117         void increment_localities_count();
118         void increment_num_localities_count();
119         void increment_num_threads_count();
120 
121         void enable_all();
122 
123     private:
124         friend struct update_time_on_exit;
125         friend struct locality_namespace;
126 
127         api_counter_data allocate_;             // locality_ns_allocate
128         api_counter_data resolve_locality_;     // locality_ns_resolve_locality
129         api_counter_data free_;                 // locality_ns_free
130         api_counter_data localities_;           // locality_ns_localities
131         api_counter_data num_localities_;       // locality_ns_num_localities
132         api_counter_data num_threads_;          // locality_ns_num_threads
133     };
134     counter_data counter_data_;
135 
136   public:
locality_namespacehpx::agas::server::locality_namespace137     locality_namespace(primary_namespace* primary)
138       : base_type(HPX_AGAS_LOCALITY_NS_MSB, HPX_AGAS_LOCALITY_NS_LSB)
139       , prefix_counter_(HPX_AGAS_BOOTSTRAP_PREFIX)
140       , primary_(primary)
141     {}
142 
143     void finalize();
144 
145     // register all performance counter types exposed by this component
146     static void register_counter_types(
147         error_code& ec = throws
148         );
149     static void register_global_counter_types(
150         error_code& ec = throws
151         );
152 
153     void register_server_instance(
154         char const* servicename
155       , error_code& ec = throws
156         );
157 
158     void unregister_server_instance(
159         error_code& ec = throws
160         );
161 
162     std::uint32_t allocate(
163         parcelset::endpoints_type const& endpoints
164       , std::uint64_t count
165       , std::uint32_t num_threads
166       , naming::gid_type suggested_prefix
167         );
168 
169     parcelset::endpoints_type resolve_locality(
170         naming::gid_type locality);
171 
172     void free(naming::gid_type locality);
173 
174     std::vector<std::uint32_t> localities();
175 
176     std::uint32_t get_num_localities();
177 
178     std::vector<std::uint32_t> get_num_threads();
179 
180     std::uint32_t get_num_overall_threads();
181 
182     naming::gid_type statistics_counter(std::string name);
183 
184   public:
185     HPX_DEFINE_COMPONENT_ACTION(locality_namespace, allocate);
186     HPX_DEFINE_COMPONENT_ACTION(locality_namespace, free);
187     HPX_DEFINE_COMPONENT_ACTION(locality_namespace, localities);
188     HPX_DEFINE_COMPONENT_ACTION(locality_namespace, resolve_locality);
189     HPX_DEFINE_COMPONENT_ACTION(locality_namespace, get_num_localities);
190     HPX_DEFINE_COMPONENT_ACTION(locality_namespace, get_num_threads);
191     HPX_DEFINE_COMPONENT_ACTION(locality_namespace, get_num_overall_threads);
192     HPX_DEFINE_COMPONENT_ACTION(locality_namespace, statistics_counter);
193 };
194 
195 }}}
196 
197 HPX_ACTION_USES_MEDIUM_STACK(
198     hpx::agas::server::locality_namespace::allocate_action)
199 
200 HPX_REGISTER_ACTION_DECLARATION(
201     hpx::agas::server::locality_namespace::allocate_action,
202     locality_namespace_allocate_action)
203 
204 HPX_ACTION_USES_MEDIUM_STACK(
205     hpx::agas::server::locality_namespace::free_action)
206 
207 HPX_REGISTER_ACTION_DECLARATION(
208     hpx::agas::server::locality_namespace::free_action,
209     locality_namespace_allocate_action)
210 
211 HPX_ACTION_USES_MEDIUM_STACK(
212     hpx::agas::server::locality_namespace::localities_action)
213 
214 HPX_REGISTER_ACTION_DECLARATION(
215     hpx::agas::server::locality_namespace::localities_action,
216     locality_namespace_localities_action)
217 
218 HPX_ACTION_USES_MEDIUM_STACK(
219     hpx::agas::server::locality_namespace::resolve_locality_action)
220 
221 HPX_REGISTER_ACTION_DECLARATION(
222     hpx::agas::server::locality_namespace::resolve_locality_action,
223     locality_namespace_resolve_locality_action)
224 
225 HPX_ACTION_USES_MEDIUM_STACK(
226     hpx::agas::server::locality_namespace::get_num_localities_action)
227 
228 HPX_REGISTER_ACTION_DECLARATION(
229     hpx::agas::server::locality_namespace::get_num_localities_action,
230     locality_namespace_get_num_localities_action)
231 
232 HPX_ACTION_USES_MEDIUM_STACK(
233     hpx::agas::server::locality_namespace::get_num_threads_action)
234 
235 HPX_REGISTER_ACTION_DECLARATION(
236     hpx::agas::server::locality_namespace::get_num_threads_action,
237     locality_namespace_get_num_threads_action)
238 
239 HPX_ACTION_USES_MEDIUM_STACK(
240     hpx::agas::server::locality_namespace::get_num_overall_threads_action)
241 
242 HPX_REGISTER_ACTION_DECLARATION(
243     hpx::agas::server::locality_namespace::get_num_overall_threads_action,
244     locality_namespace_get_num_overall_threads_action)
245 
246 HPX_ACTION_USES_MEDIUM_STACK(
247     hpx::agas::server::locality_namespace::statistics_counter_action)
248 
249 HPX_REGISTER_ACTION_DECLARATION(
250     hpx::agas::server::locality_namespace::statistics_counter_action,
251     locality_namespace_statistics_counter_action)
252 
253 #include <hpx/config/warnings_suffix.hpp>
254 
255 #endif
256 
257