X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/4485d715fa3a090c1dd38def83ab8239feebecb3..4dac6adc7601ff45e1bb458032c95fab5c73721d:/src/s4u/s4u_Host.cpp diff --git a/src/s4u/s4u_Host.cpp b/src/s4u/s4u_Host.cpp index 515f776f7f..db85aa3ec9 100644 --- a/src/s4u/s4u_Host.cpp +++ b/src/s4u/s4u_Host.cpp @@ -7,8 +7,12 @@ #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 #include XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_host, s4u, "Logging specific to the S4U hosts"); @@ -17,32 +21,31 @@ XBT_LOG_EXTERNAL_CATEGORY(surf_route); int USER_HOST_LEVEL = -1; namespace simgrid { - namespace xbt { -template class Extendable; -} +template class Extendable; +} // namespace xbt namespace s4u { -simgrid::xbt::signal Host::on_creation; -simgrid::xbt::signal Host::on_destruction; -simgrid::xbt::signal Host::on_state_change; -simgrid::xbt::signal Host::on_speed_change; +xbt::signal Host::on_creation; +xbt::signal Host::on_destruction; +xbt::signal Host::on_state_change; +xbt::signal Host::on_speed_change; -Host::Host(std::string name) : name_(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'.", name.c_str()); - Engine::get_instance()->host_register(std::string(name_), this); - new simgrid::surf::HostImpl(this); + xbt_assert(Host::by_name_or_null(name_) == nullptr, "Refusing to create a second host named '%s'.", get_cname()); + 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_; } @@ -51,41 +54,40 @@ 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; } } -Host* Host::by_name(std::string name) +Host* Host::by_name(const std::string& name) { return Engine::get_instance()->host_by_name(name); } -Host* Host::by_name_or_null(std::string name) +Host* Host::by_name_or_null(const std::string& name) { return Engine::get_instance()->host_by_name_or_null(name); } Host* Host::current() { - smx_actor_t smx_proc = SIMIX_process_self(); - if (smx_proc == nullptr) + kernel::actor::ActorImpl* self = SIMIX_process_self(); + if (self == nullptr) xbt_die("Cannot call Host::current() from the maestro context"); - return smx_proc->host_; + return self->get_host(); } void Host::turn_on() { if (not is_on()) { - simgrid::simix::simcall([this] { + simix::simcall([this] { this->pimpl_cpu->turn_on(); this->pimpl_->turn_on(); on_state_change(*this); @@ -97,7 +99,12 @@ void Host::turn_on() void Host::turn_off() { if (is_on()) { - simgrid::simix::simcall([this] { + simix::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(); @@ -132,22 +139,6 @@ int Host::get_actor_count() return pimpl_->get_actor_count(); } -/** @deprecated */ -void Host::getProcesses(std::vector* list) -{ - auto actors = get_all_actors(); - for (auto& actor : actors) - list->push_back(actor); -} - -/** @deprecated */ -void Host::actorList(std::vector* whereto) -{ - auto actors = get_all_actors(); - for (auto& actor : actors) - whereto->push_back(actor); -} - /** * @brief Find a route toward another host * @@ -171,7 +162,7 @@ void Host::route_to(Host* dest, std::vector& links, double* latency) /** @brief Just like Host::routeTo, but filling an array of link implementations */ void Host::route_to(Host* dest, std::vector& 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)); @@ -180,27 +171,47 @@ void Host::route_to(Host* dest, std::vector& 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 m_host_list = {this, dest}; + std::vector flops_amount = {0, 0}; + std::vector 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* Host::get_properties() +const std::unordered_map* 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) */ -const char* Host::get_property(std::string key) const +const char* Host::get_property(const std::string& key) const { return this->pimpl_->get_property(key); } -void Host::set_property(std::string key, std::string value) +void Host::set_property(const std::string& key, const std::string& value) +{ + simix::simcall([this, &key, &value] { this->pimpl_->set_property(key, value); }); +} + +void Host::set_properties(const std::map& properties) { - simgrid::simix::simcall([this, key, value] { this->pimpl_->set_property(key, value); }); + simix::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 simix::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. * @@ -210,13 +221,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 simix::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. @@ -265,7 +276,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); }); + simix::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 @@ -280,15 +291,7 @@ int Host::get_pstate() const */ std::vector Host::get_attached_storages() const { - return simgrid::simix::simcall([this] { return this->pimpl_->get_attached_storages(); }); -} - -void Host::getAttachedStorages(std::vector* storages) -{ - std::vector local_storages = - simgrid::simix::simcall([this] { return this->pimpl_->get_attached_storages(); }); - for (auto elm : local_storages) - storages->push_back(elm); + return simix::simcall([this] { return this->pimpl_->get_attached_storages(); }); } std::unordered_map const& Host::get_mounted_storages() @@ -304,7 +307,7 @@ std::unordered_map 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) @@ -314,7 +317,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 @@ -340,7 +343,7 @@ sg_host_t* sg_host_list() xbt_assert(sg_host_count() > 0, "There is no host!"); std::vector 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; @@ -366,23 +369,18 @@ sg_host_t sg_host_by_name(const char* name) return simgrid::s4u::Host::by_name_or_null(name); } -static int hostcmp_voidp(const void* pa, const void* pb) -{ - return strcmp((*static_cast(pa))->get_cname(), - (*static_cast(pb))->get_cname()); -} - xbt_dynar_t sg_hosts_as_dynar() { - xbt_dynar_t res = xbt_dynar_new(sizeof(sg_host_t), nullptr); - std::vector 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, hostcmp_voidp); + 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; } @@ -534,7 +532,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* props = host->get_properties(); + const std::unordered_map* props = host->get_properties(); if (props == nullptr) return nullptr; for (auto const& elm : *props) { @@ -607,13 +605,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* props = host->get_properties(); + const std::unordered_map* props = host->get_properties(); if (not props->empty()) { XBT_INFO(" - properties:"); @@ -638,7 +641,17 @@ void sg_host_get_actor_list(sg_host_t host, xbt_dynar_t whereto) sg_host_t sg_host_self() { smx_actor_t process = SIMIX_process_self(); - return (process == nullptr) ? nullptr : process->host_; + return (process == nullptr) ? nullptr : process->get_host(); +} + +/* needs to be public and without simcall for exceptions and logging events */ +const char* sg_host_self_get_name() +{ + sg_host_t host = sg_host_self(); + if (host == nullptr || SIMIX_process_self() == simix_global->maestro_process) + return ""; + + return host->get_cname(); } double sg_host_load(sg_host_t host)