protected:
#ifndef DOXYGEN
+ friend surf::HostImpl;
friend Host;
friend Link;
friend Disk;
friend vm::VMModel; // Use the pimpl_cpu to compute the VM sharing
friend vm::VirtualMachineImpl; // creates the the pimpl_cpu
friend kernel::routing::NetZoneImpl;
+ friend surf::HostImpl; // call destructor from private implementation
+
+ // The private implementation, that never changes
+ surf::HostImpl* const pimpl_;
public:
- explicit Host(const std::string& name);
+ explicit Host(surf::HostImpl* pimpl) : pimpl_(pimpl) {}
protected:
virtual ~Host(); // Call destroy() instead of manually deleting it.
static Host* current();
/** Retrieves the name of that host as a C++ string */
- xbt::string const& get_name() const { return name_; }
+ xbt::string const& get_name() const;
/** Retrieves the name of that host as a C string */
- const char* get_cname() const { return name_.c_str(); }
+ const char* get_cname() const;
kernel::routing::NetPoint* get_netpoint() const { return pimpl_netpoint_; }
/** Block the calling actor on an execution located on the called host (with explicit priority) */
void execute(double flops, double priority) const;
+ surf::HostImpl* get_impl() const { return pimpl_; }
private:
- xbt::string name_{"noname"};
kernel::routing::NetPoint* pimpl_netpoint_ = nullptr;
public:
#ifndef DOXYGEN
/** DO NOT USE DIRECTLY (@todo: these should be protected, once our code is clean) */
kernel::resource::Cpu* pimpl_cpu = nullptr;
- // TODO, this could be a unique_ptr
- surf::HostImpl* pimpl_ = nullptr;
#endif
};
} // namespace s4u
actor->set_properties(*properties);
/* Add the actor to it's host actor list */
- host->pimpl_->add_actor(actor);
+ host->get_impl()->add_actor(actor);
/* Now insert it in the global actor list and in the actors to run list */
simix_global->process_list[actor->get_pid()] = actor;
const std::lock_guard<std::mutex> lock(simix_global->mutex);
simix_global->process_list.erase(pid_);
if (host_ && host_actor_list_hook.is_linked())
- host_->pimpl_->remove_actor(this);
+ host_->get_impl()->remove_actor(this);
if (not smx_destroy_list_hook.is_linked()) {
#if SIMGRID_HAVE_MC
xbt_dynar_push_as(simix_global->dead_actors_vector, ActorImpl*, this);
void ActorImpl::set_host(s4u::Host* dest)
{
- host_->pimpl_->remove_actor(this);
+ host_->get_impl()->remove_actor(this);
host_ = dest;
- dest->pimpl_->add_actor(this);
+ dest->get_impl()->add_actor(this);
}
ActorImplPtr ActorImpl::init(const std::string& name, s4u::Host* host) const
XBT_DEBUG("Start context '%s'", get_cname());
/* Add the actor to its host's actor list */
- host_->pimpl_->add_actor(this);
+ host_->get_impl()->add_actor(this);
simix_global->process_list[pid_] = this;
/* Now insert it in the global actor list and in the actor to run list */
if (hierarchy_ == RoutingMode::unset)
hierarchy_ = RoutingMode::base;
- auto* res = new s4u::Host(name);
+ auto* res = (new surf::HostImpl(name))->get_iface();
res->set_netpoint((new NetPoint(name, NetPoint::Type::Host))->set_englobing_zone(this));
cpu_model_pm_->create_cpu(res, speed_per_pstate)->set_core_count(core_amount)->seal();
* Resource *
************/
-VirtualMachineImpl::VirtualMachineImpl(simgrid::s4u::VirtualMachine* piface, simgrid::s4u::Host* host_PM,
- int core_amount, size_t ramsize)
- : HostImpl(piface), physical_host_(host_PM), core_amount_(core_amount), ramsize_(ramsize)
+VirtualMachineImpl::VirtualMachineImpl(const std::string& name, s4u::VirtualMachine* piface,
+ simgrid::s4u::Host* host_PM, int core_amount, size_t ramsize)
+ : HostImpl(name, piface), piface_(piface), physical_host_(host_PM), core_amount_(core_amount), ramsize_(ramsize)
{
/* Register this VM to the list of all VMs */
allVms_.push_back(piface);
-
/* We create cpu_action corresponding to a VM process on the host operating system. */
/* TODO: we have to periodically input GUESTOS_NOISE to the system? how ?
* The value for GUESTOS_NOISE corresponds to the cost of the global action associated to the VM. It corresponds to
// It's empty for now, so it should not request resources in the PM
update_action_weight();
- XBT_VERB("Create VM(%s)@PM(%s)", piface->get_cname(), physical_host_->get_cname());
+ XBT_VERB("Create VM(%s)@PM(%s)", name.c_str(), physical_host_->get_cname());
on_creation(*this);
}
static std::deque<s4u::VirtualMachine*> allVms_;
- explicit VirtualMachineImpl(s4u::VirtualMachine* piface, s4u::Host* host, int core_amount, size_t ramsize);
+ explicit VirtualMachineImpl(const std::string& name, s4u::VirtualMachine* piface, s4u::Host* host, int core_amount,
+ size_t ramsize);
~VirtualMachineImpl() override;
virtual void suspend(kernel::actor::ActorImpl* issuer);
unsigned int get_core_amount() const { return core_amount_; }
kernel::resource::Action* get_action() const { return action_; }
+ const s4u::VirtualMachine* get_iface() const override { return piface_; }
+ s4u::VirtualMachine* get_iface() override { return piface_; }
+
virtual void set_bound(double bound);
void update_action_weight();
bool is_migrating() const { return is_migrating_; }
private:
+ s4u::VirtualMachine* piface_;
kernel::resource::Action* action_ = nullptr;
unsigned int active_execs_ = 0;
s4u::Host* physical_host_;
return nullptr;
};
};
-}
-}
+} // namespace vm
+} // namespace simgrid
#endif /* VM_INTERFACE_HPP_ */
}
VirtualMachine::VirtualMachine(const std::string& name, s4u::Host* physical_host, int core_amount, size_t ramsize)
- : Host(name), pimpl_vm_(new vm::VirtualMachineImpl(this, physical_host, core_amount, ramsize))
+ : Host(new vm::VirtualMachineImpl(name, this, physical_host, core_amount, ramsize))
+ , pimpl_vm_(dynamic_cast<vm::VirtualMachineImpl*>(Host::get_impl()))
{
XBT_DEBUG("Create VM %s", get_cname());
for (int i = 0; i < physical_host->get_pstate_count(); i++)
speeds.push_back(physical_host->get_pstate_speed(i));
- physical_host->get_netpoint()->get_englobing_zone()->get_cpu_vm_model()->create_cpu(this, speeds)->set_core_count(core_amount)->seal();
+ physical_host->get_netpoint()
+ ->get_englobing_zone()
+ ->get_cpu_vm_model()
+ ->create_cpu(this, speeds)
+ ->set_core_count(core_amount)
+ ->seal();
if (physical_host->get_pstate() != 0)
set_pstate(physical_host->get_pstate());
shutdown();
/* Then, destroy the VM object */
- Host::destroy();
+ get_impl()->destroy();
+ delete this;
}
simgrid::s4u::Host* VirtualMachine::get_pm() const
return this;
}
-} // namespace simgrid
} // namespace s4u
+} // namespace simgrid
/* **************************** Public C interface *************************** */
/** @brief Immediately kills all processes within the given VM.
*
@beginrst
-
+
The memory allocated by these actors is leaked, unless you used :cpp:func:`simgrid::s4u::Actor::on_exit`.
-
+
@endrst
- *
- * No extra delay occurs by default. You may let your actor sleep by a specific amount to simulate any extra delay that you want.
+ *
+ * No extra delay occurs by default. You may let your actor sleep by a specific amount to simulate any extra delay that
+ you want.
*/
void sg_vm_shutdown(sg_vm_t vm)
{
auto* arg = new kernel::actor::ProcessArg(pimpl_->get_host(), pimpl_);
XBT_DEBUG("Adding %s to the actors_at_boot_ list of Host %s", arg->name.c_str(), arg->host->get_cname());
- pimpl_->get_host()->pimpl_->add_actor_at_boot(arg);
+ pimpl_->get_host()->get_impl()->add_actor_at_boot(arg);
});
}
xbt::signal<void(Host const&)> Host::on_state_change;
xbt::signal<void(Host const&)> Host::on_speed_change;
-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(name_, this);
- new surf::HostImpl(this);
-}
-
Host* Host::set_netpoint(kernel::routing::NetPoint* netpoint)
{
pimpl_netpoint_ = netpoint;
Host::~Host()
{
- delete pimpl_;
if (pimpl_netpoint_ != nullptr) // not removed yet by a children class
Engine::get_instance()->netpoint_unregister(pimpl_netpoint_);
delete pimpl_cpu;
*/
void Host::destroy()
{
- on_destruction(*this);
- Engine::get_instance()->host_unregister(std::string(name_));
- delete this;
+ kernel::actor::simcall([this] { this->pimpl_->destroy(); });
}
Host* Host::by_name(const std::string& name)
return self->get_host();
}
+xbt::string const& Host::get_name() const
+{
+ return this->pimpl_->get_name();
+}
+
+const char* Host::get_cname() const
+{
+ return this->pimpl_->get_cname();
+}
+
void Host::turn_on()
{
if (not is_on()) {
//get the indices of all processes sharing the same simix host
int intra_comm_size = 0;
int min_index = INT_MAX; // the minimum index will be the leader
- sg_host_self()->pimpl_->foreach_actor([this, &intra_comm_size, &min_index](auto& actor) {
+ sg_host_self()->get_impl()->foreach_actor([this, &intra_comm_size, &min_index](auto& actor) {
int index = actor.get_pid();
if (this->group()->rank(actor.get_ciface()) != MPI_UNDEFINED) { // Is this process in the current group?
intra_comm_size++;
XBT_DEBUG("number of processes deployed on my node : %d", intra_comm_size);
auto* group_intra = new Group(intra_comm_size);
int i = 0;
- sg_host_self()->pimpl_->foreach_actor([this, group_intra, &i](auto& actor) {
+ sg_host_self()->get_impl()->foreach_actor([this, group_intra, &i](auto& actor) {
if (this->group()->rank(actor.get_ciface()) != MPI_UNDEFINED) {
group_intra->set_mapping(actor.get_ciface(), i);
i++;
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
+#include "simgrid/s4u/Engine.hpp"
+#include "simgrid/s4u/Host.hpp"
#include "src/plugins/vm/VirtualMachineImpl.hpp"
#include "src/simix/smx_private.hpp"
/************
* Resource *
************/
-HostImpl::HostImpl(s4u::Host* host) : piface_(host)
+HostImpl::HostImpl(const std::string& name, s4u::Host* piface) : piface_(this), name_(name)
{
- /* The VM wants to reinstall a new HostImpl, but we don't want to leak the previously existing one */
- delete piface_->pimpl_;
- piface_->pimpl_ = this;
+ xbt_assert(s4u::Host::by_name_or_null(name_) == nullptr, "Refusing to create a second host named '%s'.", get_cname());
+ s4u::Engine::get_instance()->host_register(name_, piface);
+}
+
+HostImpl::HostImpl(const std::string& name) : piface_(this), name_(name)
+{
+ xbt_assert(s4u::Host::by_name_or_null(name_) == nullptr, "Refusing to create a second host named '%s'.", get_cname());
+ s4u::Engine::get_instance()->host_register(name_, &piface_);
}
HostImpl::~HostImpl()
d->destroy();
}
+/** @brief Fire the required callbacks and destroy the object
+ *
+ * Don't delete directly a Host, call h->destroy() instead.
+ */
+void HostImpl::destroy()
+{
+ s4u::Host::on_destruction(*this->get_iface());
+ s4u::Engine::get_instance()->host_unregister(std::string(name_));
+ delete this;
+}
+
/** Re-starts all the actors that are marked as restartable.
*
* Weird things will happen if you turn on a host that is already on. S4U is fool-proof, not this.
position++;
}
}
-
} // namespace surf
} // namespace simgrid
ActorList actor_list_;
std::vector<kernel::actor::ProcessArg*> actors_at_boot_;
- s4u::Host* piface_ = nullptr; // we must have a pointer there because the VM wants to change the piface in its ctor
+ s4u::Host piface_;
std::vector<kernel::resource::DiskImpl*> disks_;
+ xbt::string name_{"noname"};
+
+protected:
+ virtual ~HostImpl(); // Use destroy() instead of this destructor.
+ HostImpl(const std::string& name, s4u::Host* piface);
public:
friend simgrid::vm::VirtualMachineImpl;
- explicit HostImpl(s4u::Host* host);
- virtual ~HostImpl();
+ explicit HostImpl(const std::string& name);
+
+ void destroy(); // Must be called instead of the destructor
std::vector<s4u::Disk*> get_disks() const;
void set_disks(const std::vector<kernel::resource::DiskImpl*>& disks, s4u::Host* host);
void add_disk(const s4u::Disk* disk);
void remove_disk(const std::string& disk_name);
- s4u::Host* get_iface() const { return piface_; }
+ virtual const s4u::Host* get_iface() const { return &piface_; }
+ virtual s4u::Host* get_iface() { return &piface_; }
+
+ /** Retrieves the name of that host as a C++ string */
+ xbt::string const& get_name() const { return name_; }
+ /** Retrieves the name of that host as a C string */
+ const char* get_cname() const { return name_.c_str(); }
void turn_on() const;
void turn_off(const kernel::actor::ActorImpl* issuer);
function(actor);
}
};
-}
-}
+} // namespace surf
+} // namespace simgrid
#endif /* SURF_HOST_INTERFACE_HPP */
delete args->properties;
}
- host->pimpl_->set_disks(args->disks, host);
+ host->get_impl()->set_disks(args->disks, host);
/* Change from the defaults */
host->set_state_profile(args->state_trace)->set_speed_profile(args->speed_trace);
auto* arg =
new simgrid::kernel::actor::ProcessArg(actor_name, code, nullptr, host, kill_time, properties, auto_restart);
- host->pimpl_->add_actor_at_boot(arg);
+ host->get_impl()->add_actor_at_boot(arg);
if (start_time > SIMIX_get_clock()) {
arg = new simgrid::kernel::actor::ProcessArg(actor_name, code, nullptr, host, kill_time, properties, auto_restart);