Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Convert some config flags to C++ API.
[simgrid.git] / src / simgrid / host.cpp
1 /* Copyright (c) 2013-2018. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include <algorithm>
7 #include <vector>
8
9 #include "simgrid/host.h"
10 #include "simgrid/s4u/Engine.hpp"
11 #include "simgrid/s4u/Host.hpp"
12 #include "xbt/Extendable.hpp"
13 #include "xbt/dict.h"
14
15 #include "simgrid/kernel/routing/NetPoint.hpp"
16 #include "src/simix/smx_host_private.hpp"
17 #include "src/surf/HostImpl.hpp"
18 #include "src/surf/cpu_interface.hpp"
19
20 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(sg_host, sd, "Logging specific to sg_hosts");
21
22 size_t sg_host_count()
23 {
24   return simgrid::s4u::Engine::getInstance()->getHostCount();
25 }
26 /** @brief Returns the host list
27  *
28  * Uses sg_host_count() to know the array size.
29  *
30  * \return an array of \ref sg_host_t containing all the hosts in the platform.
31  * \remark The host order in this array is generally different from the
32  * creation/declaration order in the XML platform (we use a hash table
33  * internally).
34  * \see sg_host_count()
35  */
36 sg_host_t *sg_host_list() {
37   xbt_assert(sg_host_count() > 0, "There is no host!");
38   std::vector<simgrid::s4u::Host*> hosts = simgrid::s4u::Engine::getInstance()->getAllHosts();
39
40   sg_host_t* res = (sg_host_t*)malloc(sizeof(sg_host_t) * hosts.size());
41   memcpy(res, hosts.data(), sizeof(sg_host_t) * hosts.size());
42
43   return res;
44 }
45
46 const char *sg_host_get_name(sg_host_t host)
47 {
48   return host->get_cname();
49 }
50
51 void* sg_host_extension_get(sg_host_t host, size_t ext)
52 {
53   return host->extension(ext);
54 }
55
56 size_t sg_host_extension_create(void(*deleter)(void*))
57 {
58   return simgrid::s4u::Host::extension_create(deleter);
59 }
60
61 sg_host_t sg_host_by_name(const char *name)
62 {
63   return simgrid::s4u::Host::by_name_or_null(name);
64 }
65
66 static int hostcmp_voidp(const void* pa, const void* pb)
67 {
68   return strcmp((*static_cast<simgrid::s4u::Host* const*>(pa))->get_cname(),
69                 (*static_cast<simgrid::s4u::Host* const*>(pb))->get_cname());
70 }
71
72 xbt_dynar_t sg_hosts_as_dynar()
73 {
74   xbt_dynar_t res = xbt_dynar_new(sizeof(sg_host_t),nullptr);
75
76   std::vector<simgrid::s4u::Host*> list = simgrid::s4u::Engine::getInstance()->getAllHosts();
77
78   for (auto const& host : list) {
79     if (host && host->pimpl_netpoint && host->pimpl_netpoint->is_host())
80       xbt_dynar_push(res, &host);
81   }
82   xbt_dynar_sort(res, hostcmp_voidp);
83   return res;
84 }
85
86 // ========= Layering madness ==============*
87
88 // ========== User data Layer ==========
89 void *sg_host_user(sg_host_t host) {
90   return host->extension(USER_HOST_LEVEL);
91 }
92 void sg_host_user_set(sg_host_t host, void* userdata) {
93   host->extension_set(USER_HOST_LEVEL,userdata);
94 }
95 void sg_host_user_destroy(sg_host_t host) {
96   host->extension_set(USER_HOST_LEVEL, nullptr);
97 }
98
99 // ========= storage related functions ============
100 xbt_dict_t sg_host_get_mounted_storage_list(sg_host_t host){
101   xbt_assert((host != nullptr), "Invalid parameters");
102   xbt_dict_t res = xbt_dict_new_homogeneous(nullptr);
103   for (auto const& elm : host->getMountedStorages()) {
104     const char* mount_name = elm.first.c_str();
105     sg_storage_t storage   = elm.second;
106     xbt_dict_set(res, mount_name, (void*)storage->get_cname(), nullptr);
107   }
108
109   return res;
110 }
111
112 xbt_dynar_t sg_host_get_attached_storage_list(sg_host_t host){
113   xbt_dynar_t storage_dynar = xbt_dynar_new(sizeof(const char*), nullptr);
114   std::vector<const char*> storage_vector = host->get_attached_storages();
115   for (auto const& name : storage_vector)
116     xbt_dynar_push(storage_dynar, &name);
117   return storage_dynar;
118 }
119
120 // =========== user-level functions ===============
121 // ================================================
122 /** @brief Returns the total speed of a host */
123 double sg_host_speed(sg_host_t host)
124 {
125   return host->getSpeed();
126 }
127
128 /** \brief Return the speed of the processor (in flop/s) at a given pstate. See also @ref plugin_energy.
129  *
130  * \param  host host to test
131  * \param pstate_index pstate to test
132  * \return Returns the processor speed associated with pstate_index
133  */
134 double sg_host_get_pstate_speed(sg_host_t host, int pstate_index)
135 {
136   return host->getPstateSpeed(pstate_index);
137 }
138
139 /** \ingroup m_host_management
140  * \brief Return the number of cores.
141  *
142  * \param host a host
143  * \return the number of cores
144  */
145 int sg_host_core_count(sg_host_t host)
146 {
147   return host->getCoreCount();
148 }
149
150 double sg_host_get_available_speed(sg_host_t host)
151 {
152   return host->pimpl_cpu->get_available_speed();
153 }
154
155 /** @brief Returns the number of power states for a host.
156  *
157  *  See also @ref plugin_energy.
158  */
159 int sg_host_get_nb_pstates(sg_host_t host) {
160   return host->getPstatesCount();
161 }
162
163 /** @brief Gets the pstate at which that host currently runs.
164  *
165  *  See also @ref plugin_energy.
166  */
167 int sg_host_get_pstate(sg_host_t host) {
168   return host->getPstate();
169 }
170 /** @brief Sets the pstate at which that host should run.
171  *
172  *  See also @ref plugin_energy.
173  */
174 void sg_host_set_pstate(sg_host_t host,int pstate) {
175   host->setPstate(pstate);
176 }
177
178 /** \ingroup m_host_management
179  *
180  * \brief Start the host if it is off
181  *
182  * See also #sg_host_is_on() and #sg_host_is_off() to test the current state of the host and @ref plugin_energy
183  * for more info on DVFS.
184  */
185 void sg_host_turn_on(sg_host_t host)
186 {
187   host->turnOn();
188 }
189
190 /** \ingroup m_host_management
191  *
192  * \brief Stop the host if it is on
193  *
194  * See also #MSG_host_is_on() and #MSG_host_is_off() to test the current state of the host and @ref plugin_energy
195  * for more info on DVFS.
196  */
197 void sg_host_turn_off(sg_host_t host)
198 {
199   host->turnOff();
200 }
201
202 /** @ingroup m_host_management
203  * @brief Determine if a host is up and running.
204  *
205  * See also #sg_host_turn_on() and #sg_host_turn_off() to switch the host ON and OFF and @ref plugin_energy for more
206  * info on DVFS.
207  *
208  * @param host host to test
209  * @return Returns true if the host is up and running, and false if it's currently down
210  */
211 int sg_host_is_on(sg_host_t host)
212 {
213   return host->isOn();
214 }
215
216 /** @ingroup m_host_management
217  * @brief Determine if a host is currently off.
218  *
219  * See also #sg_host_turn_on() and #sg_host_turn_off() to switch the host ON and OFF and @ref plugin_energy for more
220  * info on DVFS.
221  */
222 int sg_host_is_off(sg_host_t host)
223 {
224   return host->isOff();
225 }
226
227 /** @brief Get the properties of an host */
228 xbt_dict_t sg_host_get_properties(sg_host_t host) {
229   xbt_dict_t as_dict = xbt_dict_new_homogeneous(xbt_free_f);
230   std::map<std::string, std::string>* props = host->getProperties();
231   if (props == nullptr)
232     return nullptr;
233   for (auto const& elm : *props) {
234     xbt_dict_set(as_dict, elm.first.c_str(), xbt_strdup(elm.second.c_str()), nullptr);
235   }
236   return as_dict;
237 }
238
239 /** \ingroup m_host_management
240  * \brief Returns the value of a given host property
241  *
242  * \param host a host
243  * \param name a property name
244  * \return value of a property (or nullptr if property not set)
245 */
246 const char *sg_host_get_property_value(sg_host_t host, const char *name)
247 {
248   return host->getProperty(name);
249 }
250
251 void sg_host_set_property_value(sg_host_t host, const char* name, const char* value)
252 {
253   host->setProperty(name, value);
254 }
255
256 /**
257  * \brief Find a route between two hosts
258  *
259  * \param from where from
260  * \param to where to
261  * \param links [OUT] where to store the list of links (must exist, cannot be nullptr).
262  */
263 void sg_host_route(sg_host_t from, sg_host_t to, xbt_dynar_t links)
264 {
265   std::vector<simgrid::s4u::Link*> vlinks;
266   from->routeTo(to, vlinks, nullptr);
267   for (auto const& link : vlinks)
268     xbt_dynar_push(links, &link);
269 }
270 /**
271  * \brief Find the latency of the route between two hosts
272  *
273  * \param from where from
274  * \param to where to
275  */
276 double sg_host_route_latency(sg_host_t from, sg_host_t to)
277 {
278   std::vector<simgrid::s4u::Link*> vlinks;
279   double res = 0;
280   from->routeTo(to, vlinks, &res);
281   return res;
282 }
283 /**
284  * \brief Find the bandwitdh of the route between two hosts
285  *
286  * \param from where from
287  * \param to where to
288  */
289 double sg_host_route_bandwidth(sg_host_t from, sg_host_t to)
290 {
291   double min_bandwidth = -1.0;
292
293   std::vector<simgrid::s4u::Link*> vlinks;
294   from->routeTo(to, vlinks, nullptr);
295   for (auto const& link : vlinks) {
296     double bandwidth = link->bandwidth();
297     if (bandwidth < min_bandwidth || min_bandwidth < 0.0)
298       min_bandwidth = bandwidth;
299   }
300   return min_bandwidth;
301 }
302
303 /** @brief Displays debugging information about a host */
304 void sg_host_dump(sg_host_t host)
305 {
306   XBT_INFO("Displaying host %s", host->get_cname());
307   XBT_INFO("  - speed: %.0f", host->getSpeed());
308   XBT_INFO("  - available speed: %.2f", sg_host_get_available_speed(host));
309   std::map<std::string, std::string>* props = host->getProperties();
310
311   if (not props->empty()) {
312     XBT_INFO("  - properties:");
313     for (auto const& elm : *props) {
314       XBT_INFO("    %s->%s", elm.first.c_str(), elm.second.c_str());
315     }
316   }
317 }
318
319 /** \brief Return the list of actors attached to an host.
320  *
321  * \param host a host
322  * \param whereto a dynar in which we should push actors living on that host
323  */
324 void sg_host_get_actor_list(sg_host_t host, xbt_dynar_t whereto)
325 {
326   for (auto& actor : host->extension<simgrid::simix::Host>()->process_list) {
327     s4u_Actor* p = actor.ciface();
328     xbt_dynar_push(whereto, &p);
329   }
330 }
331
332 sg_host_t sg_host_self()
333 {
334   smx_actor_t process = SIMIX_process_self();
335   return (process == nullptr) ? nullptr : process->host;
336 }