Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix a doc error about actors (Tutorial_algorithms)
[simgrid.git] / src / s4u / s4u_Host.cpp
index 68698e8..5cb23b1 100644 (file)
@@ -7,43 +7,43 @@
 #include "simgrid/s4u/Actor.hpp"
 #include "simgrid/s4u/Engine.hpp"
 #include "simgrid/s4u/Exec.hpp"
+#include "simgrid/s4u/VirtualMachine.hpp"
+#include "src/plugins/vm/VirtualMachineImpl.hpp"
 #include "src/simix/smx_private.hpp"
 #include "src/surf/HostImpl.hpp"
 
+#include <algorithm>
 #include <string>
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_host, s4u, "Logging specific to the S4U hosts");
 XBT_LOG_EXTERNAL_CATEGORY(surf_route);
 
-int USER_HOST_LEVEL = -1;
-
 namespace simgrid {
-
 namespace xbt {
-template class Extendable<simgrid::s4u::Host>;
-}
+template class Extendable<s4u::Host>;
+} // namespace xbt
 
 namespace s4u {
 
-simgrid::xbt::signal<void(Host&)> Host::on_creation;
-simgrid::xbt::signal<void(Host&)> Host::on_destruction;
-simgrid::xbt::signal<void(Host&)> Host::on_state_change;
-simgrid::xbt::signal<void(Host&)> Host::on_speed_change;
+xbt::signal<void(Host&)> Host::on_creation;
+xbt::signal<void(Host const&)> Host::on_destruction;
+xbt::signal<void(Host const&)> Host::on_state_change;
+xbt::signal<void(Host const&)> Host::on_speed_change;
 
-Host::Host(std::string name) : name_(std::move(name))
+Host::Host(const std::string& name) : name_(name)
 {
   xbt_assert(Host::by_name_or_null(name_) == nullptr, "Refusing to create a second host named '%s'.", get_cname());
-  Engine::get_instance()->host_register(std::string(name_), this);
-  new simgrid::surf::HostImpl(this);
+  Engine::get_instance()->host_register(name_, this);
+  new surf::HostImpl(this);
 }
 
 Host::~Host()
 {
-  xbt_assert(currentlyDestroying_, "Please call h->destroy() instead of manually deleting it.");
+  xbt_assert(currently_destroying_, "Please call h->destroy() instead of manually deleting it.");
 
   delete pimpl_;
   if (pimpl_netpoint != nullptr) // not removed yet by a children class
-    simgrid::s4u::Engine::get_instance()->netpoint_unregister(pimpl_netpoint);
+    Engine::get_instance()->netpoint_unregister(pimpl_netpoint);
   delete pimpl_cpu;
   delete mounts_;
 }
@@ -52,14 +52,13 @@ Host::~Host()
  *
  * Don't delete directly a host, call h->destroy() instead.
  *
- * This is cumbersome but this is the simplest solution to ensure that the
- * onDestruction() callback receives a valid object (because of the destructor
- * order in a class hierarchy).
+ * This is cumbersome but this is the simplest solution to ensure that the onDestruction() callback receives a valid
+ * object (because of the destructor order in a class hierarchy).
  */
 void Host::destroy()
 {
-  if (not currentlyDestroying_) {
-    currentlyDestroying_ = true;
+  if (not currently_destroying_) {
+    currently_destroying_ = true;
     on_destruction(*this);
     Engine::get_instance()->host_unregister(std::string(name_));
     delete this;
@@ -77,7 +76,7 @@ Host* Host::by_name_or_null(const std::string& name)
 
 Host* Host::current()
 {
-  smx_actor_t self = SIMIX_process_self();
+  kernel::actor::ActorImpl* self = SIMIX_process_self();
   if (self == nullptr)
     xbt_die("Cannot call Host::current() from the maestro context");
   return self->get_host();
@@ -86,7 +85,7 @@ Host* Host::current()
 void Host::turn_on()
 {
   if (not is_on()) {
-    simgrid::simix::simcall([this] {
+    kernel::actor::simcall([this] {
       this->pimpl_cpu->turn_on();
       this->pimpl_->turn_on();
       on_state_change(*this);
@@ -98,7 +97,12 @@ void Host::turn_on()
 void Host::turn_off()
 {
   if (is_on()) {
-    simgrid::simix::simcall([this] {
+    kernel::actor::simcall([this] {
+      for (VirtualMachine* const& vm : vm::VirtualMachineImpl::allVms_)
+        if (vm->get_pm() == this) {
+          vm->shutdown();
+          vm->turn_off();
+        }
       this->pimpl_cpu->turn_off();
       this->pimpl_->turn_off();
 
@@ -133,22 +137,6 @@ int Host::get_actor_count()
   return pimpl_->get_actor_count();
 }
 
-/** @deprecated */
-void Host::getProcesses(std::vector<ActorPtr>* list)
-{
-  auto actors = get_all_actors();
-  for (auto& actor : actors)
-    list->push_back(actor);
-}
-
-/** @deprecated */
-void Host::actorList(std::vector<ActorPtr>* whereto)
-{
-  auto actors = get_all_actors();
-  for (auto& actor : actors)
-    whereto->push_back(actor);
-}
-
 /**
  * @brief Find a route toward another host
  *
@@ -172,7 +160,7 @@ void Host::route_to(Host* dest, std::vector<Link*>& links, double* latency)
 /** @brief Just like Host::routeTo, but filling an array of link implementations */
 void Host::route_to(Host* dest, std::vector<kernel::resource::LinkImpl*>& links, double* latency)
 {
-  simgrid::kernel::routing::NetZoneImpl::get_global_route(pimpl_netpoint, dest->pimpl_netpoint, links, latency);
+  kernel::routing::NetZoneImpl::get_global_route(pimpl_netpoint, dest->pimpl_netpoint, links, latency);
   if (XBT_LOG_ISENABLED(surf_route, xbt_log_priority_debug)) {
     XBT_CDEBUG(surf_route, "Route from '%s' to '%s' (latency: %f):", get_cname(), dest->get_cname(),
                (latency == nullptr ? -1 : *latency));
@@ -181,10 +169,24 @@ void Host::route_to(Host* dest, std::vector<kernel::resource::LinkImpl*>& links,
   }
 }
 
+/** @brief Returns the networking zone englobing that host */
+NetZone* Host::get_englobing_zone()
+{
+  return pimpl_netpoint->get_englobing_zone()->get_iface();
+}
+
+void Host::send_to(Host* dest, double byte_amount)
+{
+  std::vector<Host*> m_host_list   = {this, dest};
+  std::vector<double> flops_amount = {0, 0};
+  std::vector<double> bytes_amount = {0, byte_amount, 0, 0};
+  this_actor::parallel_execute(m_host_list, flops_amount, bytes_amount);
+}
+
 /** Get the properties assigned to a host */
-std::unordered_map<std::string, std::string>* Host::get_properties()
+const std::unordered_map<std::string, std::string>* Host::get_properties() const
 {
-  return simgrid::simix::simcall([this] { return this->pimpl_->get_properties(); });
+  return this->pimpl_->get_properties();
 }
 
 /** Retrieve the property value (or nullptr if not set) */
@@ -193,15 +195,21 @@ const char* Host::get_property(const std::string& key) const
   return this->pimpl_->get_property(key);
 }
 
-void Host::set_property(const std::string& key, std::string value)
+void Host::set_property(const std::string& key, const std::string& value)
 {
-  simgrid::simix::simcall([this, key, value] { this->pimpl_->set_property(key, std::move(value)); });
+  kernel::actor::simcall([this, &key, &value] { this->pimpl_->set_property(key, value); });
 }
+
+void Host::set_properties(const std::map<std::string, std::string>& properties)
+{
+  kernel::actor::simcall([this, &properties] { this->pimpl_->set_properties(properties); });
+}
+
 /** Specify a profile turning the host on and off according to a exhaustive list or a stochastic law.
  * The profile must contain boolean values. */
 void Host::set_state_profile(kernel::profile::Profile* p)
 {
-  return simgrid::simix::simcall([this, p] { pimpl_cpu->set_state_profile(p); });
+  return kernel::actor::simcall([this, p] { pimpl_cpu->set_state_profile(p); });
 }
 /** Specify a profile modeling the external load according to a exhaustive list or a stochastic law.
  *
@@ -211,13 +219,13 @@ void Host::set_state_profile(kernel::profile::Profile* p)
  */
 void Host::set_speed_profile(kernel::profile::Profile* p)
 {
-  return simgrid::simix::simcall([this, p] { pimpl_cpu->set_speed_profile(p); });
+  return kernel::actor::simcall([this, p] { pimpl_cpu->set_speed_profile(p); });
 }
 
 /** @brief Get the peak processor speed (in flops/s), at the specified pstate  */
 double Host::get_pstate_speed(int pstate_index) const
 {
-  return simgrid::simix::simcall([this, pstate_index] { return this->pimpl_cpu->get_pstate_peak_speed(pstate_index); });
+  return this->pimpl_cpu->get_pstate_peak_speed(pstate_index);
 }
 
 /** @brief Get the peak computing speed in flops/s at the current pstate, NOT taking the external load into account.
@@ -266,7 +274,7 @@ int Host::get_core_count() const
 /** @brief Set the pstate at which the host should run */
 void Host::set_pstate(int pstate_index)
 {
-  simgrid::simix::simcall([this, pstate_index] { this->pimpl_cpu->set_pstate(pstate_index); });
+  kernel::actor::simcall([this, pstate_index] { this->pimpl_cpu->set_pstate(pstate_index); });
 }
 /** @brief Retrieve the pstate at which the host is currently running */
 int Host::get_pstate() const
@@ -274,6 +282,20 @@ int Host::get_pstate() const
   return this->pimpl_cpu->get_pstate();
 }
 
+std::vector<Disk*> Host::get_disks() const
+{
+  return kernel::actor::simcall([this] { return this->pimpl_->get_disks(); });
+}
+
+void Host::add_disk(Disk* disk)
+{
+  kernel::actor::simcall([this, disk] { this->pimpl_->add_disk(disk); });
+}
+
+void Host::remove_disk(const std::string& disk_name)
+{
+  kernel::actor::simcall([this, disk_name] { this->pimpl_->remove_disk(disk_name); });
+}
 /**
  * @ingroup simix_storage_management
  * @brief Returns the list of storages attached to a host.
@@ -281,15 +303,7 @@ int Host::get_pstate() const
  */
 std::vector<const char*> Host::get_attached_storages() const
 {
-  return simgrid::simix::simcall([this] { return this->pimpl_->get_attached_storages(); });
-}
-
-void Host::getAttachedStorages(std::vector<const char*>* storages)
-{
-  std::vector<const char*> local_storages =
-      simgrid::simix::simcall([this] { return this->pimpl_->get_attached_storages(); });
-  for (auto elm : local_storages)
-    storages->push_back(elm);
+  return kernel::actor::simcall([this] { return this->pimpl_->get_attached_storages(); });
 }
 
 std::unordered_map<std::string, Storage*> const& Host::get_mounted_storages()
@@ -305,7 +319,7 @@ std::unordered_map<std::string, Storage*> const& Host::get_mounted_storages()
 
 ExecPtr Host::exec_async(double flops)
 {
-  return this_actor::exec_init(flops)->set_host(this);
+  return this_actor::exec_init(flops);
 }
 
 void Host::execute(double flops)
@@ -315,7 +329,7 @@ void Host::execute(double flops)
 
 void Host::execute(double flops, double priority)
 {
-  this_actor::exec_init(flops)->set_host(this)->set_priority(1 / priority)->start()->wait();
+  this_actor::exec_init(flops)->set_priority(1 / priority)->start()->wait();
 }
 
 } // namespace s4u
@@ -341,7 +355,7 @@ sg_host_t* sg_host_list()
   xbt_assert(sg_host_count() > 0, "There is no host!");
   std::vector<simgrid::s4u::Host*> hosts = simgrid::s4u::Engine::get_instance()->get_all_hosts();
 
-  sg_host_t* res = (sg_host_t*)malloc(sizeof(sg_host_t) * hosts.size());
+  sg_host_t* res = xbt_new(sg_host_t, hosts.size());
   memcpy(res, hosts.data(), sizeof(sg_host_t) * hosts.size());
 
   return res;
@@ -369,36 +383,41 @@ sg_host_t sg_host_by_name(const char* name)
 
 xbt_dynar_t sg_hosts_as_dynar()
 {
-  xbt_dynar_t res = xbt_dynar_new(sizeof(sg_host_t), nullptr);
-
   std::vector<simgrid::s4u::Host*> list = simgrid::s4u::Engine::get_instance()->get_all_hosts();
 
-  for (auto const& host : list) {
-    if (host && host->pimpl_netpoint && host->pimpl_netpoint->is_host())
-      xbt_dynar_push(res, &host);
-  }
-  xbt_dynar_sort(res, [](const void* pa, const void* pb) {
-    const std::string& na = (*static_cast<simgrid::s4u::Host* const*>(pa))->get_name();
-    const std::string& nb = (*static_cast<simgrid::s4u::Host* const*>(pb))->get_name();
-    return na.compare(nb);
+  auto last = std::remove_if(begin(list), end(list), [](const simgrid::s4u::Host* host) {
+    return not host || not host->pimpl_netpoint || not host->pimpl_netpoint->is_host();
   });
+  std::sort(begin(list), last,
+            [](const simgrid::s4u::Host* a, const simgrid::s4u::Host* b) { return a->get_name() < b->get_name(); });
+
+  xbt_dynar_t res = xbt_dynar_new(sizeof(sg_host_t), nullptr);
+  std::for_each(begin(list), last, [res](sg_host_t host) { xbt_dynar_push_as(res, sg_host_t, host); });
   return res;
 }
 
 // ========= Layering madness ==============*
 
 // ========== User data Layer ==========
-void* sg_host_user(sg_host_t host)
+void* sg_host_data(sg_host_t host)
+{
+  return host->get_data();
+}
+void sg_host_data_set(sg_host_t host, void* userdata)
 {
-  return host->extension(USER_HOST_LEVEL);
+  host->set_data(userdata);
 }
-void sg_host_user_set(sg_host_t host, void* userdata)
+void* sg_host_user(sg_host_t host) // deprecated
 {
-  host->extension_set(USER_HOST_LEVEL, userdata);
+  return host->get_data();
 }
-void sg_host_user_destroy(sg_host_t host)
+void sg_host_user_set(sg_host_t host, void* userdata) // deprecated
 {
-  host->extension_set(USER_HOST_LEVEL, nullptr);
+  host->set_data(userdata);
+}
+void sg_host_user_destroy(sg_host_t host) // deprecated
+{
+  host->set_data(nullptr);
 }
 
 // ========= storage related functions ============
@@ -533,7 +552,7 @@ int sg_host_is_off(sg_host_t host)
 xbt_dict_t sg_host_get_properties(sg_host_t host)
 {
   xbt_dict_t as_dict = xbt_dict_new_homogeneous(xbt_free_f);
-  std::unordered_map<std::string, std::string>* props = host->get_properties();
+  const std::unordered_map<std::string, std::string>* props = host->get_properties();
   if (props == nullptr)
     return nullptr;
   for (auto const& elm : *props) {
@@ -606,13 +625,18 @@ double sg_host_route_bandwidth(sg_host_t from, sg_host_t to)
   return min_bandwidth;
 }
 
+void sg_host_send_to(sg_host_t from, sg_host_t to, double byte_amount)
+{
+  from->send_to(to, byte_amount);
+}
+
 /** @brief Displays debugging information about a host */
 void sg_host_dump(sg_host_t host)
 {
   XBT_INFO("Displaying host %s", host->get_cname());
   XBT_INFO("  - speed: %.0f", host->get_speed());
   XBT_INFO("  - available speed: %.2f", sg_host_get_available_speed(host));
-  std::unordered_map<std::string, std::string>* props = host->get_properties();
+  const std::unordered_map<std::string, std::string>* props = host->get_properties();
 
   if (not props->empty()) {
     XBT_INFO("  - properties:");