X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/4d02714ee138a3bd9b02e0064b7a2aa26407e9e8..f9521627fe1cef73bb8eccd5b11735dcbd906dbd:/src/s4u/s4u_Actor.cpp diff --git a/src/s4u/s4u_Actor.cpp b/src/s4u/s4u_Actor.cpp index b20d8c6d37..33d319a022 100644 --- a/src/s4u/s4u_Actor.cpp +++ b/src/s4u/s4u_Actor.cpp @@ -8,11 +8,12 @@ #include "simgrid/s4u/Actor.hpp" #include "simgrid/s4u/Exec.hpp" #include "simgrid/s4u/Host.hpp" +#include "simgrid/s4u/VirtualMachine.hpp" #include "src/kernel/activity/ExecImpl.hpp" -#include "src/simix/smx_host_private.hpp" #include "src/simix/smx_private.hpp" #include "src/surf/HostImpl.hpp" +#include #include XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_actor, "S4U actors"); @@ -20,36 +21,52 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_actor, "S4U actors"); namespace simgrid { namespace s4u { -simgrid::xbt::signal s4u::Actor::on_creation; -simgrid::xbt::signal s4u::Actor::on_suspend; -simgrid::xbt::signal s4u::Actor::on_resume; -simgrid::xbt::signal s4u::Actor::on_sleep; -simgrid::xbt::signal s4u::Actor::on_wake_up; -simgrid::xbt::signal s4u::Actor::on_migration_start; -simgrid::xbt::signal s4u::Actor::on_migration_end; -simgrid::xbt::signal s4u::Actor::on_destruction; +xbt::signal s4u::Actor::on_creation; +xbt::signal s4u::Actor::on_suspend; +xbt::signal s4u::Actor::on_resume; +xbt::signal s4u::Actor::on_sleep; +xbt::signal s4u::Actor::on_wake_up; +xbt::signal s4u::Actor::on_migration_start; +xbt::signal s4u::Actor::on_migration_end; +xbt::signal s4u::Actor::on_termination; +xbt::signal s4u::Actor::on_destruction; // ***** Actor creation ***** -ActorPtr Actor::self() +Actor* Actor::self() { - smx_context_t self_context = simgrid::kernel::context::Context::self(); + kernel::context::Context* self_context = kernel::context::Context::self(); if (self_context == nullptr) - return simgrid::s4u::ActorPtr(); + return nullptr; + + return self_context->get_actor()->ciface(); +} +ActorPtr Actor::init(const std::string& name, s4u::Host* host) +{ + smx_actor_t self = SIMIX_process_self(); + kernel::actor::ActorImpl* actor = simix::simcall([self, &name, host] { return self->init(name, host).get(); }); + return actor->iface(); +} - return self_context->get_actor()->iface(); +ActorPtr Actor::start(const std::function& code) +{ + simgrid::simix::simcall([this, &code] { pimpl_->start(code); }); + return this; } -ActorPtr Actor::create(std::string name, s4u::Host* host, std::function code) +ActorPtr Actor::create(const std::string& name, s4u::Host* host, const std::function& code) { - simgrid::kernel::actor::ActorImpl* actor = - simcall_process_create(std::move(name), std::move(code), nullptr, host, nullptr); + smx_actor_t self = SIMIX_process_self(); + kernel::actor::ActorImpl* actor = + simix::simcall([self, &name, host, &code] { return self->init(name, host)->start(code); }); + return actor->iface(); } -ActorPtr Actor::create(std::string name, s4u::Host* host, const std::string& function, std::vector args) +ActorPtr Actor::create(const std::string& name, s4u::Host* host, const std::string& function, + std::vector args) { - simgrid::simix::ActorCodeFactory& factory = SIMIX_get_actor_code_factory(function); - return create(std::move(name), host, factory(std::move(args))); + simix::ActorCodeFactory& factory = SIMIX_get_actor_code_factory(function); + return create(name, host, factory(std::move(args))); } void intrusive_ptr_add_ref(Actor* actor) @@ -60,6 +77,10 @@ void intrusive_ptr_release(Actor* actor) { intrusive_ptr_release(actor->pimpl_); } +int Actor::get_refcount() +{ + return pimpl_->get_refcount(); +} // ***** Actor methods ***** @@ -75,56 +96,53 @@ void Actor::join(double timeout) void Actor::set_auto_restart(bool autorestart) { - simgrid::simix::simcall([this, autorestart]() { + simix::simcall([this, autorestart]() { xbt_assert(autorestart && not pimpl_->has_to_auto_restart()); // FIXME: handle all cases pimpl_->set_auto_restart(autorestart); - simgrid::kernel::actor::ProcessArg* arg = new simgrid::kernel::actor::ProcessArg(pimpl_->get_host(), pimpl_); + kernel::actor::ProcessArg* arg = new kernel::actor::ProcessArg(pimpl_->get_host(), pimpl_); XBT_DEBUG("Adding Process %s to the actors_at_boot_ list of Host %s", arg->name.c_str(), arg->host->get_cname()); pimpl_->get_host()->pimpl_->actors_at_boot_.emplace_back(arg); }); } -void Actor::on_exit(int_f_pvoid_pvoid_t fun, - void* data) /* deprecated: cleanup SIMIX_process_on_exit: change prototype of second parameter and - remove the last one */ +void Actor::on_exit(const std::function& fun, void* data) /* deprecated */ { - simgrid::simix::simcall([this, fun, data] { SIMIX_process_on_exit(pimpl_, fun, data); }); + on_exit([fun, data](bool failed) { fun(failed ? SMX_EXIT_FAILURE : SMX_EXIT_SUCCESS, data); }); } -void Actor::on_exit(std::function const fun) +void Actor::on_exit(const std::function& fun) const { - simgrid::simix::simcall( - [this, fun] { SIMIX_process_on_exit(pimpl_, [fun](int a, void* /*data*/) { fun(a != 0); }, nullptr); }); + simix::simcall([this, &fun] { SIMIX_process_on_exit(pimpl_, fun); }); } void Actor::migrate(Host* new_host) { - s4u::Actor::on_migration_start(this); + s4u::Actor::on_migration_start(*this); - simgrid::simix::simcall([this, new_host]() { + simix::simcall([this, new_host]() { if (pimpl_->waiting_synchro != nullptr) { // The actor is blocked on an activity. If it's an exec, migrate it too. // FIXME: implement the migration of other kind of activities - simgrid::kernel::activity::ExecImplPtr exec = - boost::dynamic_pointer_cast(pimpl_->waiting_synchro); + kernel::activity::ExecImplPtr exec = + boost::dynamic_pointer_cast(pimpl_->waiting_synchro); xbt_assert(exec.get() != nullptr, "We can only migrate blocked actors when they are blocked on executions."); exec->migrate(new_host); } this->pimpl_->set_host(new_host); }); - s4u::Actor::on_migration_end(this); + s4u::Actor::on_migration_end(*this); } -s4u::Host* Actor::get_host() +s4u::Host* Actor::get_host() const { return this->pimpl_->get_host(); } void Actor::daemonize() { - simgrid::simix::simcall([this]() { pimpl_->daemonize(); }); + simix::simcall([this]() { pimpl_->daemonize(); }); } bool Actor::is_daemon() const @@ -154,24 +172,24 @@ aid_t Actor::get_ppid() const void Actor::suspend() { - s4u::Actor::on_suspend(this); + s4u::Actor::on_suspend(*this); simcall_process_suspend(pimpl_); } void Actor::resume() { - simgrid::simix::simcall([this] { pimpl_->resume(); }); - s4u::Actor::on_resume(this); + simix::simcall([this] { pimpl_->resume(); }); + s4u::Actor::on_resume(*this); } bool Actor::is_suspended() { - return simgrid::simix::simcall([this] { return pimpl_->is_suspended(); }); + return simix::simcall([this] { return pimpl_->is_suspended(); }); } void Actor::set_kill_time(double kill_time) { - simgrid::simix::simcall([this, kill_time] { pimpl_->set_kill_time(kill_time); }); + simix::simcall([this, kill_time] { pimpl_->set_kill_time(kill_time); }); } /** @brief Get the kill time of an actor(or 0 if unset). */ @@ -182,10 +200,10 @@ double Actor::get_kill_time() void Actor::kill(aid_t pid) // deprecated { - smx_actor_t killer = SIMIX_process_self(); - smx_actor_t victim = SIMIX_process_from_PID(pid); + kernel::actor::ActorImpl* killer = SIMIX_process_self(); + kernel::actor::ActorImpl* victim = SIMIX_process_from_PID(pid); if (victim != nullptr) { - simgrid::simix::simcall([killer, victim] { killer->kill(victim); }); + simix::simcall([killer, victim] { killer->kill(victim); }); } else { std::ostringstream oss; oss << "kill: (" << pid << ") - No such actor" << std::endl; @@ -195,25 +213,18 @@ void Actor::kill(aid_t pid) // deprecated void Actor::kill() { - smx_actor_t process = SIMIX_process_self(); - simgrid::simix::simcall([this, process] { - if (pimpl_ == simix_global->maestro_process) - pimpl_->exit(); - else - process->kill(pimpl_); + kernel::actor::ActorImpl* process = SIMIX_process_self(); + simix::simcall([this, process] { + xbt_assert(pimpl_ != simix_global->maestro_process, "Killing maestro is a rather bad idea"); + process->kill(pimpl_); }); } -smx_actor_t Actor::get_impl() -{ - return pimpl_; -} - // ***** Static functions ***** ActorPtr Actor::by_pid(aid_t pid) { - smx_actor_t process = SIMIX_process_from_PID(pid); + kernel::actor::ActorImpl* process = SIMIX_process_from_PID(pid); if (process != nullptr) return process->iface(); else @@ -222,29 +233,29 @@ ActorPtr Actor::by_pid(aid_t pid) void Actor::kill_all() { - smx_actor_t self = SIMIX_process_self(); - simgrid::simix::simcall([self] { self->kill_all(); }); + kernel::actor::ActorImpl* self = SIMIX_process_self(); + simix::simcall([self] { self->kill_all(); }); } -std::unordered_map* Actor::get_properties() +const std::unordered_map* Actor::get_properties() const { - return simgrid::simix::simcall([this] { return this->pimpl_->get_properties(); }); + return pimpl_->get_properties(); } /** Retrieve the property value (or nullptr if not set) */ -const char* Actor::get_property(const std::string& key) +const char* Actor::get_property(const std::string& key) const { - return simgrid::simix::simcall([this, key] { return pimpl_->get_property(key); }); + return pimpl_->get_property(key); } -void Actor::set_property(const std::string& key, std::string value) +void Actor::set_property(const std::string& key, const std::string& value) { - simgrid::simix::simcall([this, key, value] { pimpl_->set_property(key, std::move(value)); }); + simix::simcall([this, &key, &value] { pimpl_->set_property(key, value); }); } Actor* Actor::restart() { - return simgrid::simix::simcall([this]() { return pimpl_->restart(); }); + return simix::simcall([this]() { return pimpl_->restart(); }); } // ***** this_actor ***** @@ -262,32 +273,32 @@ namespace this_actor { */ bool is_maestro() { - smx_actor_t process = SIMIX_process_self(); + kernel::actor::ActorImpl* process = SIMIX_process_self(); return process == nullptr || process == simix_global->maestro_process; } void sleep_for(double duration) { if (duration > 0) { - smx_actor_t actor = SIMIX_process_self(); - simgrid::s4u::Actor::on_sleep(actor->iface()); + kernel::actor::ActorImpl* actor = SIMIX_process_self(); + Actor::on_sleep(*actor->ciface()); simcall_process_sleep(duration); - simgrid::s4u::Actor::on_wake_up(actor->iface()); + Actor::on_wake_up(*actor->ciface()); } } void yield() { - simgrid::simix::simcall([] { /* do nothing*/ }); + simix::simcall([] { /* do nothing*/ }); } -XBT_PUBLIC void sleep_until(double timeout) +XBT_PUBLIC void sleep_until(double wakeup_time) { double now = SIMIX_get_clock(); - if (timeout > now) - sleep_for(timeout - now); + if (wakeup_time > now) + sleep_for(wakeup_time - now); } void execute(double flops) @@ -315,15 +326,21 @@ void parallel_execute(const std::vector& hosts, const std::vector(hosts.front())); + xbt_assert(std::all_of(hosts.begin(), hosts.end(), + [is_a_vm](s4u::Host* elm) { + bool tmp_is_a_vm = (nullptr != dynamic_cast(elm)); + return is_a_vm == tmp_is_a_vm; + }), + "parallel_execute: mixing VMs and PMs is not supported (yet)."); + /* checking for infinite values */ + xbt_assert(std::all_of(flops_amounts.begin(), flops_amounts.end(), [](double elm) { return std::isfinite(elm); }), + "flops_amounts comprises infinite values!"); + xbt_assert(std::all_of(bytes_amounts.begin(), bytes_amounts.end(), [](double elm) { return std::isfinite(elm); }), + "flops_amounts comprises infinite values!"); + + exec_init(hosts, flops_amounts, bytes_amounts)->set_timeout(timeout)->wait(); } // deprecated @@ -349,7 +366,13 @@ void parallel_execute(int host_nb, s4u::Host* const* host_list, const double* fl ExecPtr exec_init(double flops_amount) { - return ExecPtr(new Exec(get_host(), flops_amount)); + return ExecPtr(new ExecSeq(get_host(), flops_amount)); +} + +ExecPtr exec_init(const std::vector& hosts, const std::vector& flops_amounts, + const std::vector& bytes_amounts) +{ + return ExecPtr(new ExecPar(hosts, flops_amounts, bytes_amounts)); } ExecPtr exec_async(double flops) @@ -386,31 +409,31 @@ Host* get_host() void suspend() { - smx_actor_t actor = SIMIX_process_self(); - simgrid::s4u::Actor::on_suspend(actor->iface()); + kernel::actor::ActorImpl* actor = SIMIX_process_self(); + Actor::on_suspend(*actor->ciface()); simcall_process_suspend(actor); } void resume() { - smx_actor_t process = SIMIX_process_self(); - simgrid::simix::simcall([process] { process->resume(); }); - simgrid::s4u::Actor::on_resume(process->iface()); + kernel::actor::ActorImpl* self = SIMIX_process_self(); + simix::simcall([self] { self->resume(); }); + Actor::on_resume(*self->ciface()); } void exit() { - smx_actor_t actor = SIMIX_process_self(); - simgrid::simix::simcall([actor] { actor->exit(); }); + kernel::actor::ActorImpl* self = SIMIX_process_self(); + simgrid::simix::simcall([self] { self->exit(); }); } -void on_exit(std::function const fun) +void on_exit(const std::function& fun) { SIMIX_process_self()->iface()->on_exit(fun); } -void on_exit(std::function const fun, void* data) /* deprecated */ +void on_exit(const std::function& fun, void* data) /* deprecated */ { SIMIX_process_self()->iface()->on_exit([fun, data](bool exit) { fun(exit, data); }); } @@ -424,43 +447,6 @@ void migrate(Host* new_host) SIMIX_process_self()->iface()->migrate(new_host); } -std::string getName() /* deprecated */ -{ - return get_name(); -} -const char* getCname() /* deprecated */ -{ - return get_cname(); -} -bool isMaestro() /* deprecated */ -{ - return is_maestro(); -} -aid_t getPid() /* deprecated */ -{ - return get_pid(); -} -aid_t getPpid() /* deprecated */ -{ - return get_ppid(); -} -Host* getHost() /* deprecated */ -{ - return get_host(); -} -void on_exit(int_f_pvoid_pvoid_t fun, void* data) /* deprecated */ -{ - SIMIX_process_self()->iface()->on_exit([fun, data](int a) { fun((void*)(intptr_t)a, data); }); -} -void onExit(int_f_pvoid_pvoid_t fun, void* data) /* deprecated */ -{ - on_exit([fun, data](int a) { fun((void*)(intptr_t)a, data); }); -} -void kill() /* deprecated */ -{ - exit(); -} - } // namespace this_actor } // namespace s4u } // namespace simgrid @@ -539,7 +525,7 @@ xbt_dict_t sg_actor_get_properties(sg_actor_t actor) { xbt_assert(actor != nullptr, "Invalid parameter: First argument must not be nullptr"); xbt_dict_t as_dict = xbt_dict_new_homogeneous(xbt_free_f); - std::unordered_map* props = actor->get_properties(); + const std::unordered_map* props = actor->get_properties(); if (props == nullptr) return nullptr; for (auto const& kv : *props) { @@ -687,3 +673,39 @@ void sg_actor_detach() { simgrid::kernel::actor::ActorImpl::detach(); } + +aid_t sg_actor_self_get_pid() +{ + return simgrid::s4u::this_actor::get_pid(); +} + +aid_t sg_actor_self_get_ppid() +{ + return simgrid::s4u::this_actor::get_ppid(); +} + +const char* sg_actor_self_get_name() +{ + return simgrid::s4u::this_actor::get_cname(); +} + +sg_actor_t sg_actor_self() +{ + return simgrid::s4u::Actor::self(); +} + +void sg_actor_self_execute(double flops) +{ + simgrid::s4u::this_actor::execute(flops); +} + +/** @brief Take an extra reference on that actor to prevent it to be garbage-collected */ +void sg_actor_ref(sg_actor_t actor) +{ + intrusive_ptr_add_ref(actor); +} +/** @brief Release a reference on that actor so that it can get be garbage-collected */ +void sg_actor_unref(sg_actor_t actor) +{ + intrusive_ptr_release(actor); +}