X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/173e6cb373d42d61f6eb620771dc5a2e5492173b..0fca06bbd37ed912e06515ffc0a27675734d1141:/src/kernel/actor/ActorImpl.cpp diff --git a/src/kernel/actor/ActorImpl.cpp b/src/kernel/actor/ActorImpl.cpp index 28fcc0f4ed..2b96c7d4fc 100644 --- a/src/kernel/actor/ActorImpl.cpp +++ b/src/kernel/actor/ActorImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2019. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2020. The SimGrid Team. All rights reserved. */ /* 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. */ @@ -52,7 +52,7 @@ ActorImpl* ActorImpl::self() return (self_context != nullptr) ? self_context->get_actor() : nullptr; } -ActorImpl::ActorImpl(simgrid::xbt::string name, s4u::Host* host) : host_(host), name_(std::move(name)), piface_(this) +ActorImpl::ActorImpl(xbt::string name, s4u::Host* host) : host_(host), name_(std::move(name)), piface_(this) { pid_ = maxpid++; simcall.issuer_ = this; @@ -60,13 +60,8 @@ ActorImpl::ActorImpl(simgrid::xbt::string name, s4u::Host* host) : host_(host), ActorImpl::~ActorImpl() { - if (simix_global != nullptr && this != simix_global->maestro_process) { - if (context_.get() != nullptr) /* the actor was not start()ed yet. This happens if its host was initially off */ - context_->iwannadie = false; // don't let the simcall's yield() do a Context::stop(), to avoid infinite loops - simgrid::kernel::actor::simcall([this] { simgrid::s4u::Actor::on_destruction(*ciface()); }); - if (context_.get() != nullptr) - context_->iwannadie = true; - } + if (simix_global != nullptr && this != simix_global->maestro_) + s4u::Actor::on_destruction(*ciface()); } /* Become an actor in the simulation @@ -82,11 +77,11 @@ ActorImplPtr ActorImpl::attach(const std::string& name, void* data, s4u::Host* h { // This is mostly a copy/paste from create(), it'd be nice to share some code between those two functions. - XBT_DEBUG("Attach process %s on host '%s'", name.c_str(), host->get_cname()); + XBT_DEBUG("Attach actor %s on host '%s'", name.c_str(), host->get_cname()); if (not host->is_on()) { - XBT_WARN("Cannot launch process '%s' on failed host '%s'", name.c_str(), host->get_cname()); - throw simgrid::HostFailureException(XBT_THROW_POINT, "Cannot attach actor on failed host."); + XBT_WARN("Cannot attach actor '%s' on failed host '%s'", name.c_str(), host->get_cname()); + throw HostFailureException(XBT_THROW_POINT, "Cannot attach actor on failed host."); } ActorImpl* actor = new ActorImpl(xbt::string(name), host); @@ -102,21 +97,21 @@ ActorImplPtr ActorImpl::attach(const std::string& name, void* data, s4u::Host* h if (properties != nullptr) actor->set_properties(*properties); - /* Add the process to it's host process list */ + /* Add the actor to it's host actor list */ host->pimpl_->add_actor(actor); - /* Now insert it in the global process list and in the process to run list */ + /* Now insert it in the global actor list and in the actors to run list */ simix_global->process_list[actor->get_pid()] = actor; XBT_DEBUG("Inserting [%p] %s(%s) in the to_run list", actor, actor->get_cname(), host->get_cname()); simix_global->actors_to_run.push_back(actor); intrusive_ptr_add_ref(actor); - auto* context = dynamic_cast(actor->context_.get()); + auto* context = dynamic_cast(actor->context_.get()); xbt_assert(nullptr != context, "Not a suitable context"); context->attach_start(); /* The on_creation() signal must be delayed until there, where the pid and everything is set */ - simgrid::s4u::Actor::on_creation(*actor->ciface()); + s4u::Actor::on_creation(*actor->ciface()); return ActorImplPtr(actor); } @@ -136,6 +131,20 @@ void ActorImpl::detach() context->attach_stop(); } +void ActorImpl::cleanup_from_simix() +{ + const std::lock_guard lock(simix_global->mutex); + simix_global->process_list.erase(pid_); + if (host_ && host_actor_list_hook.is_linked()) + host_->pimpl_->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); +#endif + simix_global->actors_to_destroy.push_back(*this); + } +} + void ActorImpl::cleanup() { finished_ = true; @@ -148,7 +157,7 @@ void ActorImpl::cleanup() if (on_exit) { // Execute the termination callbacks - bool failed = context_->iwannadie; + bool failed = context_->wannadie(); for (auto exit_fun = on_exit->crbegin(); exit_fun != on_exit->crend(); ++exit_fun) (*exit_fun)(failed); on_exit.reset(); @@ -162,7 +171,7 @@ void ActorImpl::cleanup() XBT_DEBUG("%s@%s(%ld) should not run anymore", get_cname(), get_host()->get_cname(), get_pid()); - if (this == simix_global->maestro_process) /* Do not cleanup maestro */ + if (this == simix_global->maestro_) /* Do not cleanup maestro */ return; XBT_DEBUG("Cleanup actor %s (%p), waiting synchro %p", get_cname(), this, waiting_synchro.get()); @@ -172,29 +181,16 @@ void ActorImpl::cleanup() kill_timer->remove(); kill_timer = nullptr; } + cleanup_from_simix(); - simix_global->mutex.lock(); - - simix_global->process_list.erase(pid_); - if (host_ && host_actor_list_hook.is_linked()) - host_->pimpl_->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); -#endif - simix_global->actors_to_destroy.push_back(*this); - } - - simix_global->mutex.unlock(); - - context_->iwannadie = false; // don't let the simcall's yield() do a Context::stop(), to avoid infinite loops - simgrid::kernel::actor::simcall([this] { simgrid::s4u::Actor::on_termination(*ciface()); }); - context_->iwannadie = true; + context_->set_wannadie(false); // don't let the simcall's yield() do a Context::stop(), to avoid infinite loops + actor::simcall([this] { s4u::Actor::on_termination(*ciface()); }); + context_->set_wannadie(); } void ActorImpl::exit() { - context_->iwannadie = true; + context_->set_wannadie(); suspended_ = false; exception_ = nullptr; @@ -227,7 +223,7 @@ void ActorImpl::exit() void ActorImpl::kill(ActorImpl* actor) { - xbt_assert(actor != simix_global->maestro_process, "Killing maestro is a rather bad idea"); + xbt_assert(actor != simix_global->maestro_, "Killing maestro is a rather bad idea"); if (actor->finished_) { XBT_DEBUG("Ignoring request to kill actor %s@%s that is already dead", actor->get_cname(), actor->host_->get_cname()); @@ -280,7 +276,7 @@ void ActorImpl::yield() /* Ok, maestro returned control to us */ XBT_DEBUG("Control returned to me: '%s'", get_cname()); - if (context_->iwannadie) { + if (context_->wannadie()) { XBT_DEBUG("Actor %s@%s is dead", get_cname(), host_->get_cname()); context_->stop(); THROW_IMPOSSIBLE; @@ -331,7 +327,7 @@ void ActorImpl::undaemonize() s4u::Actor* ActorImpl::restart() { - xbt_assert(this != simix_global->maestro_process, "Restarting maestro is not supported"); + xbt_assert(this != simix_global->maestro_, "Restarting maestro is not supported"); XBT_DEBUG("Restarting actor %s on %s", get_cname(), host_->get_cname()); @@ -375,7 +371,7 @@ void ActorImpl::resume() { XBT_IN("actor = %p", this); - if (context_->iwannadie) { + if (context_->wannadie()) { XBT_VERB("Ignoring request to suspend an actor that is currently dying."); return; } @@ -391,7 +387,7 @@ void ActorImpl::resume() XBT_OUT(); } -activity::ActivityImplPtr ActorImpl::join(ActorImpl* actor, double timeout) +activity::ActivityImplPtr ActorImpl::join(const ActorImpl* actor, double timeout) { activity::ActivityImplPtr sleep = this->sleep(timeout); actor->on_exit->emplace_back([sleep](bool) { @@ -404,7 +400,7 @@ activity::ActivityImplPtr ActorImpl::join(ActorImpl* actor, double timeout) activity::ActivityImplPtr ActorImpl::sleep(double duration) { if (not host_->is_on()) - throw_exception(std::make_exception_ptr(simgrid::HostFailureException( + throw_exception(std::make_exception_ptr(HostFailureException( XBT_THROW_POINT, std::string("Host ") + host_->get_cname() + " failed, you cannot sleep there."))); auto sleep = new activity::SleepImpl(); @@ -434,7 +430,7 @@ void ActorImpl::throw_exception(std::exception_ptr e) void ActorImpl::simcall_answer() { - if (this != simix_global->maestro_process){ + if (this != simix_global->maestro_) { XBT_DEBUG("Answer simcall %s (%d) issued by %s (%p)", SIMIX_simcall_name(simcall.call_), (int)simcall.call_, get_cname(), this); simcall.call_ = SIMCALL_NONE; @@ -465,19 +461,19 @@ ActorImplPtr ActorImpl::init(const std::string& name, s4u::Host* host) return ActorImplPtr(actor); } -ActorImpl* ActorImpl::start(const simix::ActorCode& code) +ActorImpl* ActorImpl::start(const ActorCode& code) { xbt_assert(code && host_ != nullptr, "Invalid parameters"); if (not host_->is_on()) { XBT_WARN("Cannot launch actor '%s' on failed host '%s'", name_.c_str(), host_->get_cname()); intrusive_ptr_release(this); - throw simgrid::HostFailureException(XBT_THROW_POINT, "Cannot start actor on failed host."); + throw HostFailureException(XBT_THROW_POINT, "Cannot start actor on failed host."); } this->code_ = code; XBT_VERB("Create context %s", get_cname()); - context_.reset(simix_global->context_factory->create_context(simix::ActorCode(code), this)); + context_.reset(simix_global->context_factory->create_context(ActorCode(code), this)); XBT_DEBUG("Start context '%s'", get_cname()); @@ -492,7 +488,7 @@ ActorImpl* ActorImpl::start(const simix::ActorCode& code) return this; } -ActorImplPtr ActorImpl::create(const std::string& name, const simix::ActorCode& code, void* data, s4u::Host* host, +ActorImplPtr ActorImpl::create(const std::string& name, const ActorCode& code, void* data, s4u::Host* host, const std::unordered_map* properties, ActorImpl* parent_actor) { XBT_DEBUG("Start actor %s@'%s'", name.c_str(), host->get_cname()); @@ -521,13 +517,13 @@ void create_maestro(const std::function& code) ActorImpl* maestro = new ActorImpl(xbt::string(""), /*host*/ nullptr); if (not code) { - maestro->context_.reset(simix_global->context_factory->create_context(simix::ActorCode(), maestro)); + maestro->context_.reset(simix_global->context_factory->create_context(ActorCode(), maestro)); } else { - maestro->context_.reset(simix_global->context_factory->create_maestro(simix::ActorCode(code), maestro)); + maestro->context_.reset(simix_global->context_factory->create_maestro(ActorCode(code), maestro)); } maestro->simcall.issuer_ = maestro; - simix_global->maestro_process = maestro; + simix_global->maestro_ = maestro; } } // namespace actor @@ -606,7 +602,7 @@ void SIMIX_process_on_exit(smx_actor_t actor, * @param host where the new agent is executed. * @param properties the properties of the process */ -smx_actor_t simcall_process_create(const std::string& name, const simgrid::simix::ActorCode& code, void* data, +smx_actor_t simcall_process_create(const std::string& name, const simgrid::kernel::actor::ActorCode& code, void* data, sg_host_t host, std::unordered_map* properties) { smx_actor_t self = simgrid::kernel::actor::ActorImpl::self(); @@ -615,7 +611,7 @@ smx_actor_t simcall_process_create(const std::string& name, const simgrid::simix }); } -void simcall_process_set_data(smx_actor_t process, void* data) +void simcall_process_set_data(smx_actor_t process, void* data) // XBT_ATTRIB_DEPRECATED_v329 { simgrid::kernel::actor::simcall([process, data] { process->set_user_data(data); }); }