X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/fc843eea56266a45c81d671ba8fcbda11d6099d1..919a006452206f935fe271499ab68eb8cf875854:/src/kernel/actor/ActorImpl.cpp diff --git a/src/kernel/actor/ActorImpl.cpp b/src/kernel/actor/ActorImpl.cpp index f62d97c7a6..ef37508256 100644 --- a/src/kernel/actor/ActorImpl.cpp +++ b/src/kernel/actor/ActorImpl.cpp @@ -29,7 +29,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_actor, kernel, "Logging specific to Actor's * * @return The SIMIX process */ -smx_actor_t SIMIX_process_self() // XBT_ATTRIB_DEPRECATED_v333 +simgrid::kernel::actor::ActorImpl* SIMIX_process_self() // XBT_ATTRIB_DEPRECATED_v333 { return simgrid::kernel::actor::ActorImpl::self(); } @@ -38,6 +38,7 @@ namespace simgrid { namespace kernel { namespace actor { +/*------------------------- [ ActorIDTrait ] -------------------------*/ static unsigned long maxpid = 0; unsigned long get_maxpid() { @@ -47,10 +48,7 @@ unsigned long* get_maxpid_addr() { return &maxpid; } -ActorImpl* ActorImpl::by_pid(aid_t pid) -{ - return EngineImpl::get_instance()->get_actor_by_pid(pid); -} +ActorIDTrait::ActorIDTrait(const std::string& name, aid_t ppid) : name_(name), pid_(maxpid++), ppid_(ppid) {} ActorImpl* ActorImpl::self() { @@ -59,9 +57,9 @@ ActorImpl* ActorImpl::self() return (self_context != nullptr) ? self_context->get_actor() : nullptr; } -ActorImpl::ActorImpl(xbt::string name, s4u::Host* host) : host_(host), name_(std::move(name)), piface_(this) +ActorImpl::ActorImpl(xbt::string name, s4u::Host* host, aid_t ppid) + : ActorIDTrait(std::move(name), ppid), host_(host), piface_(this) { - pid_ = maxpid++; simcall_.issuer_ = this; stacksize_ = context::stack_size; } @@ -91,7 +89,7 @@ ActorImplPtr ActorImpl::attach(const std::string& name, void* data, s4u::Host* h throw HostFailureException(XBT_THROW_POINT, "Cannot attach actor on failed host."); } - auto* actor = new ActorImpl(xbt::string(name), host); + auto* actor = new ActorImpl(xbt::string(name), host, /*ppid*/ -1); /* Actor data */ actor->piface_.set_data(data); actor->code_ = nullptr; @@ -139,11 +137,13 @@ bool ActorImpl::is_maestro() const void ActorImpl::cleanup_from_kernel() { - xbt_assert(s4u::Actor::is_maestro(), "Cleanup_from_kernel called from '%s' on '%s'", ActorImpl::self()->get_cname(), - get_cname()); + xbt_assert(s4u::Actor::is_maestro(), "Cleanup_from_kernel must be called in maestro context"); auto* engine = EngineImpl::get_instance(); - engine->remove_actor(pid_); + if (engine->get_actor_by_pid(get_pid()) == nullptr) + return; // Already cleaned + + engine->remove_actor(get_pid()); if (host_ && host_actor_list_hook.is_linked()) host_->get_impl()->remove_actor(this); if (not kernel_destroy_list_hook.is_linked()) @@ -156,6 +156,7 @@ void ActorImpl::cleanup_from_kernel() } undaemonize(); + s4u::Actor::on_termination(*get_ciface()); while (not mailboxes_.empty()) mailboxes_.back()->set_receiver(nullptr); @@ -166,11 +167,11 @@ void ActorImpl::cleanup_from_kernel() void ActorImpl::cleanup_from_self() { xbt_assert(not ActorImpl::is_maestro(), "Cleanup_from_self called from maestro on '%s'", get_cname()); - context_->set_to_be_freed(); + set_to_be_freed(); if (on_exit) { // Execute the termination callbacks - bool failed = context_->wannadie(); + bool failed = wannadie(); for (auto exit_fun = on_exit->crbegin(); exit_fun != on_exit->crend(); ++exit_fun) (*exit_fun)(failed); on_exit.reset(); @@ -193,14 +194,15 @@ void ActorImpl::cleanup_from_self() simcall_.timeout_cb_ = nullptr; } - context_->set_wannadie(false); // don't let the simcall's yield() do a Context::stop(), to avoid infinite loops - actor::simcall_answered([this] { s4u::Actor::on_termination(*get_ciface()); }); - context_->set_wannadie(); + /* maybe the actor was killed during a simcall, reset its observer */ + simcall_.observer_ = nullptr; + + set_wannadie(); } void ActorImpl::exit() { - context_->set_wannadie(); + set_wannadie(); suspended_ = false; exception_ = nullptr; @@ -225,7 +227,7 @@ void ActorImpl::exit() void ActorImpl::kill(ActorImpl* actor) const { xbt_assert(not actor->is_maestro(), "Killing maestro is a rather bad idea."); - if (actor->context_->wannadie()) { + if (actor->wannadie()) { XBT_DEBUG("Ignoring request to kill actor %s@%s that is already dead", actor->get_cname(), actor->host_->get_cname()); return; @@ -275,7 +277,7 @@ void ActorImpl::yield() /* Ok, maestro returned control to us */ XBT_DEBUG("Control returned to me: '%s'", get_cname()); - if (context_->wannadie()) { + if (wannadie()) { XBT_DEBUG("Actor %s@%s is dead", get_cname(), host_->get_cname()); context_->stop(); THROW_IMPOSSIBLE; @@ -298,7 +300,7 @@ void ActorImpl::yield() } } #if HAVE_SMPI - if (not context_->wannadie()) + if (not wannadie()) smpi_switch_data_segment(get_iface()); #endif } @@ -354,7 +356,7 @@ void ActorImpl::resume() { XBT_IN("actor = %p", this); - if (context_->wannadie()) { + if (wannadie()) { XBT_VERB("Ignoring request to resume an actor that is currently dying."); return; } @@ -375,7 +377,7 @@ void ActorImpl::resume() activity::ActivityImplPtr ActorImpl::join(const ActorImpl* actor, double timeout) { activity::ActivityImplPtr sleep = this->sleep(timeout); - if (actor->context_->wannadie() || actor->context_->to_be_freed()) { + if (actor->wannadie() || actor->to_be_freed()) { if (sleep->surf_action_) sleep->surf_action_->finish(resource::Action::State::FINISHED); } else { @@ -437,8 +439,7 @@ void ActorImpl::set_host(s4u::Host* dest) ActorImplPtr ActorImpl::init(const std::string& name, s4u::Host* host) const { - auto* actor = new ActorImpl(xbt::string(name), host); - actor->set_ppid(this->pid_); + auto* actor = new ActorImpl(xbt::string(name), host, get_pid()); intrusive_ptr_add_ref(actor); /* The on_creation() signal must be delayed until there, where the pid and everything is set */ @@ -453,7 +454,7 @@ ActorImpl* ActorImpl::start(const ActorCode& code) auto* engine = EngineImpl::get_instance(); if (not host_->is_on()) { - XBT_WARN("Cannot launch actor '%s' on failed host '%s'", name_.c_str(), host_->get_cname()); + XBT_WARN("Cannot launch actor '%s' on failed host '%s'", get_cname(), host_->get_cname()); intrusive_ptr_release(this); throw HostFailureException(XBT_THROW_POINT, "Cannot start actor on failed host."); } @@ -466,7 +467,7 @@ ActorImpl* ActorImpl::start(const ActorCode& code) /* Add the actor to its host's actor list */ host_->get_impl()->add_actor(this); - engine->add_actor(pid_, this); + engine->add_actor(get_pid(), this); /* Now insert it in the global actor list and in the actor to run list */ engine->add_actor_to_run_list_no_check(this); @@ -506,12 +507,17 @@ ActorImplPtr ActorImpl::create(ProcessArg* args) actor->daemonize(); return actor; } +void ActorImpl::set_wannadie(bool value) +{ + XBT_DEBUG("Actor %s gonna die.", get_cname()); + iwannadie_ = value; +} void create_maestro(const std::function& code) { auto* engine = EngineImpl::get_instance(); /* Create maestro actor and initialize it */ - auto* maestro = new ActorImpl(xbt::string(""), /*host*/ nullptr); + auto* maestro = new ActorImpl(xbt::string(""), /*host*/ nullptr, /*ppid*/ -1); if (not code) { maestro->context_.reset(engine->get_context_factory()->create_context(ActorCode(), maestro));