From 0eef92d7d664eabdb1145f511916212504489d84 Mon Sep 17 00:00:00 2001 From: Frederic Suter Date: Sat, 16 Feb 2019 22:42:16 +0100 Subject: [PATCH] SIMIX_process_yield becomes ActorImpl::yield --- doc/doxygen/inside_extending.doc | 2 +- src/kernel/context/ContextSwapped.cpp | 4 +- src/simix/ActorImpl.cpp | 77 ++++++++++++++------------- src/simix/ActorImpl.hpp | 4 +- src/simix/popping_bodies.cpp | 2 +- src/simix/simcalls.py | 2 +- src/simix/smx_host.cpp | 6 +-- src/simix/smx_io.cpp | 3 +- src/simix/smx_network.cpp | 24 ++++----- src/simix/smx_private.hpp | 6 +-- 10 files changed, 66 insertions(+), 64 deletions(-) diff --git a/doc/doxygen/inside_extending.doc b/doc/doxygen/inside_extending.doc index 10d38b63b7..dc0c51e084 100644 --- a/doc/doxygen/inside_extending.doc +++ b/doc/doxygen/inside_extending.doc @@ -138,7 +138,7 @@ The workflow of a simcall is the following: - `simcall_BODY_()` - Initializes the simcall (store the arguments in position) - If maestro, executes the simcall directly (and return) - - If not, call `SIMIX_process_yield` to give back the control to maestro + - If not, call `ActorImpl::yield` to give back the control to maestro - ========== KERNEL MODE ========== - `SIMIX_simcall_handle` large switch (on simcall) doing for each: - `simcall_HANDLER_(simcall, )` (the manual code handling the simcall) diff --git a/src/kernel/context/ContextSwapped.cpp b/src/kernel/context/ContextSwapped.cpp index 364b82226e..2e964404dc 100644 --- a/src/kernel/context/ContextSwapped.cpp +++ b/src/kernel/context/ContextSwapped.cpp @@ -207,7 +207,7 @@ void SwappedContext::resume() Context::set_current(this); worker_context->swap_into(this); // No body runs that soul anymore at this point, but it is stored in a safe place. - // When the executed actor will do a blocking action, SIMIX_process_yield() will call suspend(), below. + // When the executed actor will do a blocking action, ActorImpl::yield() will call suspend(), below. } else { // sequential execution SwappedContext* old = static_cast(self()); Context::set_current(this); @@ -215,7 +215,7 @@ void SwappedContext::resume() } } -/** The actor wants to yield back to maestro, because it is blocked in a simcall (ie in SIMIX_process_yield()) +/** The actor wants to yield back to maestro, because it is blocked in a simcall (i.e., in ActorImpl::yield()) * * Actually, it does not really yield back to maestro, but directly into the next executable actor. * diff --git a/src/simix/ActorImpl.cpp b/src/simix/ActorImpl.cpp index 2fb512e81a..5c38159d3e 100644 --- a/src/simix/ActorImpl.cpp +++ b/src/simix/ActorImpl.cpp @@ -94,7 +94,7 @@ void ActorImpl::exit() context_->iwannadie = true; blocked_ = false; suspended_ = false; - exception = nullptr; + exception_ = nullptr; // Forcefully kill the actor if its host is turned off. Not a HostFailureException because you should not survive that if (not host_->is_on()) @@ -189,6 +189,43 @@ static void dying_daemon(int /*exit_status*/, void* data) vect->pop_back(); } +void ActorImpl::yield() +{ + XBT_DEBUG("Yield actor '%s'", get_cname()); + + /* Go into sleep and return control to maestro */ + context_->suspend(); + + /* Ok, maestro returned control to us */ + XBT_DEBUG("Control returned to me: '%s'", get_cname()); + + if (context_->iwannadie) { + + XBT_DEBUG("Actor %s@%s is dead", get_cname(), host_->get_cname()); + // throw simgrid::kernel::context::StopRequest(); Does not seem to properly kill the actor + context_->stop(); + THROW_IMPOSSIBLE; + } + + if (suspended_) { + XBT_DEBUG("Hey! I'm suspended."); + xbt_assert(exception_ != nullptr, "Gasp! This exception may be lost by subsequent calls."); + suspended_ = false; + suspend(this); + } + + if (exception_ != nullptr) { + XBT_DEBUG("Wait, maestro left me an exception"); + std::exception_ptr exception = std::move(exception_); + exception_ = nullptr; + std::rethrow_exception(std::move(exception)); + } + + if (SMPI_switch_data_segment && not finished_) { + SMPI_switch_data_segment(iface()); + } +} + /** This process will be terminated automatically when the last non-daemon process finishes */ void ActorImpl::daemonize() { @@ -285,7 +322,7 @@ smx_activity_t ActorImpl::sleep(double duration) void ActorImpl::throw_exception(std::exception_ptr e) { - exception = e; + exception_ = e; if (suspended_) resume(); @@ -612,42 +649,6 @@ void SIMIX_process_sleep_destroy(smx_activity_t synchro) * * @param self the current process */ -void SIMIX_process_yield(smx_actor_t self) -{ - XBT_DEBUG("Yield actor '%s'", self->get_cname()); - - /* Go into sleep and return control to maestro */ - self->context_->suspend(); - - /* Ok, maestro returned control to us */ - XBT_DEBUG("Control returned to me: '%s'", self->get_cname()); - - if (self->context_->iwannadie) { - - XBT_DEBUG("Process %s@%s is dead", self->get_cname(), self->host_->get_cname()); - // throw simgrid::kernel::context::StopRequest(); Does not seem to properly kill the actor - self->context_->stop(); - THROW_IMPOSSIBLE; - } - - if (self->suspended_) { - XBT_DEBUG("Hey! I'm suspended."); - xbt_assert(self->exception != nullptr, "Gasp! This exception may be lost by subsequent calls."); - self->suspended_ = false; - self->suspend(self); - } - - if (self->exception != nullptr) { - XBT_DEBUG("Wait, maestro left me an exception"); - std::exception_ptr exception = std::move(self->exception); - self->exception = nullptr; - std::rethrow_exception(std::move(exception)); - } - - if (SMPI_switch_data_segment && not self->finished_) { - SMPI_switch_data_segment(self->iface()); - } -} /** @brief Returns the list of processes to run. * @deprecated diff --git a/src/simix/ActorImpl.hpp b/src/simix/ActorImpl.hpp index 011afe7de2..404278f70e 100644 --- a/src/simix/ActorImpl.hpp +++ b/src/simix/ActorImpl.hpp @@ -42,7 +42,7 @@ public: s4u::Host* host_ = nullptr; /* the host on which the process is running */ smx_context_t context_ = nullptr; /* the context (uctx/raw/thread) that executes the user function */ - std::exception_ptr exception; + std::exception_ptr exception_; bool finished_ = false; bool blocked_ = false; bool suspended_ = false; @@ -98,6 +98,7 @@ public: void kill(smx_actor_t actor); void kill_all(); + void yield(); void daemonize(); bool is_daemon() { return daemon_; } /** Whether this actor has been daemonized */ bool is_suspended() { return suspended_; } @@ -163,7 +164,6 @@ XBT_PUBLIC void create_maestro(std::function code); typedef simgrid::kernel::actor::ActorImpl* smx_actor_t; XBT_PRIVATE void SIMIX_process_cleanup(smx_actor_t arg); -XBT_PRIVATE void SIMIX_process_yield(smx_actor_t self); extern void (*SMPI_switch_data_segment)(simgrid::s4u::ActorPtr actor); diff --git a/src/simix/popping_bodies.cpp b/src/simix/popping_bodies.cpp index ede5a41545..2525848ee2 100644 --- a/src/simix/popping_bodies.cpp +++ b/src/simix/popping_bodies.cpp @@ -30,7 +30,7 @@ inline static R simcall(e_smx_simcall_t call, T const&... t) if (self != simix_global->maestro_process) { XBT_DEBUG("Yield process '%s' on simcall %s (%d)", self->get_cname(), SIMIX_simcall_name(self->simcall.call), (int)self->simcall.call); - SIMIX_process_yield(self); + self->yield(); } else { SIMIX_simcall_handle(&self->simcall, 0); } diff --git a/src/simix/simcalls.py b/src/simix/simcalls.py index 922722e6fb..508015c67b 100755 --- a/src/simix/simcalls.py +++ b/src/simix/simcalls.py @@ -380,7 +380,7 @@ inline static R simcall(e_smx_simcall_t call, T const&... t) if (self != simix_global->maestro_process) { XBT_DEBUG("Yield process '%s' on simcall %s (%d)", self->get_cname(), SIMIX_simcall_name(self->simcall.call), (int)self->simcall.call); - SIMIX_process_yield(self); + self->yield(); } else { SIMIX_simcall_handle(&self->simcall, 0); } diff --git a/src/simix/smx_host.cpp b/src/simix/smx_host.cpp index 8f17148061..02430211c0 100644 --- a/src/simix/smx_host.cpp +++ b/src/simix/smx_host.cpp @@ -107,19 +107,19 @@ void SIMIX_execution_finish(smx_activity_t synchro) case SIMIX_FAILED: XBT_DEBUG("SIMIX_execution_finished: host '%s' failed", simcall->issuer->host_->get_cname()); simcall->issuer->context_->iwannadie = true; - simcall->issuer->exception = + simcall->issuer->exception_ = std::make_exception_ptr(simgrid::HostFailureException(XBT_THROW_POINT, "Host failed")); break; case SIMIX_CANCELED: XBT_DEBUG("SIMIX_execution_finished: execution canceled"); - simcall->issuer->exception = + simcall->issuer->exception_ = std::make_exception_ptr(simgrid::CancelException(XBT_THROW_POINT, "Execution Canceled")); break; case SIMIX_TIMEOUT: XBT_DEBUG("SIMIX_execution_finished: execution timeouted"); - simcall->issuer->exception = std::make_exception_ptr(simgrid::TimeoutError(XBT_THROW_POINT, "Timeouted")); + simcall->issuer->exception_ = std::make_exception_ptr(simgrid::TimeoutError(XBT_THROW_POINT, "Timeouted")); break; default: diff --git a/src/simix/smx_io.cpp b/src/simix/smx_io.cpp index b82e48d1ff..37ec6790ab 100644 --- a/src/simix/smx_io.cpp +++ b/src/simix/smx_io.cpp @@ -47,7 +47,8 @@ void SIMIX_io_finish(smx_activity_t synchro) SMX_EXCEPTION(simcall->issuer, io_error, 0, "IO failed"); break; case SIMIX_CANCELED: - simcall->issuer->exception = std::make_exception_ptr(simgrid::CancelException(XBT_THROW_POINT, "I/O Canceled")); + simcall->issuer->exception_ = + std::make_exception_ptr(simgrid::CancelException(XBT_THROW_POINT, "I/O Canceled")); break; default: xbt_die("Internal error in SIMIX_io_finish: unexpected synchro state %d", static_cast(synchro->state_)); diff --git a/src/simix/smx_network.cpp b/src/simix/smx_network.cpp index 7916873e42..5314480de5 100644 --- a/src/simix/smx_network.cpp +++ b/src/simix/smx_network.cpp @@ -391,7 +391,7 @@ void SIMIX_comm_finish(smx_activity_t synchro) if (not simcall->issuer->host_->is_on()) { simcall->issuer->context_->iwannadie = true; - simcall->issuer->exception = + simcall->issuer->exception_ = std::make_exception_ptr(simgrid::HostFailureException(XBT_THROW_POINT, "Host failed")); } else { switch (comm->state_) { @@ -402,12 +402,12 @@ void SIMIX_comm_finish(smx_activity_t synchro) break; case SIMIX_SRC_TIMEOUT: - simcall->issuer->exception = std::make_exception_ptr( + simcall->issuer->exception_ = std::make_exception_ptr( simgrid::TimeoutError(XBT_THROW_POINT, "Communication timeouted because of the sender")); break; case SIMIX_DST_TIMEOUT: - simcall->issuer->exception = std::make_exception_ptr( + simcall->issuer->exception_ = std::make_exception_ptr( simgrid::TimeoutError(XBT_THROW_POINT, "Communication timeouted because of the receiver")); break; @@ -415,7 +415,7 @@ void SIMIX_comm_finish(smx_activity_t synchro) if (simcall->issuer == comm->src_actor_) simcall->issuer->context_->iwannadie = true; else - simcall->issuer->exception = + simcall->issuer->exception_ = std::make_exception_ptr(simgrid::NetworkFailureException(XBT_THROW_POINT, "Remote peer failed")); break; @@ -423,7 +423,7 @@ void SIMIX_comm_finish(smx_activity_t synchro) if (simcall->issuer == comm->dst_actor_) simcall->issuer->context_->iwannadie = true; else - simcall->issuer->exception = + simcall->issuer->exception_ = std::make_exception_ptr(simgrid::NetworkFailureException(XBT_THROW_POINT, "Remote peer failed")); break; @@ -446,10 +446,10 @@ void SIMIX_comm_finish(smx_activity_t synchro) case SIMIX_CANCELED: if (simcall->issuer == comm->dst_actor_) - simcall->issuer->exception = std::make_exception_ptr( + simcall->issuer->exception_ = std::make_exception_ptr( simgrid::CancelException(XBT_THROW_POINT, "Communication canceled by the sender")); else - simcall->issuer->exception = std::make_exception_ptr( + simcall->issuer->exception_ = std::make_exception_ptr( simgrid::CancelException(XBT_THROW_POINT, "Communication canceled by the receiver")); break; @@ -459,7 +459,7 @@ void SIMIX_comm_finish(smx_activity_t synchro) } /* if there is an exception during a waitany or a testany, indicate the position of the failed communication */ - if (simcall->issuer->exception && + if (simcall->issuer->exception_ && (simcall->call == SIMCALL_COMM_WAITANY || simcall->call == SIMCALL_COMM_TESTANY)) { // First retrieve the rank of our failing synchro int rank = -1; @@ -478,16 +478,16 @@ void SIMIX_comm_finish(smx_activity_t synchro) // In order to modify the exception we have to rethrow it: try { - std::rethrow_exception(simcall->issuer->exception); + std::rethrow_exception(simcall->issuer->exception_); } catch (simgrid::TimeoutError& e) { e.value = rank; - simcall->issuer->exception = std::make_exception_ptr(e); + simcall->issuer->exception_ = std::make_exception_ptr(e); } catch (simgrid::NetworkFailureException& e) { e.value = rank; - simcall->issuer->exception = std::make_exception_ptr(e); + simcall->issuer->exception_ = std::make_exception_ptr(e); } catch (simgrid::CancelException& e) { e.value = rank; - simcall->issuer->exception = std::make_exception_ptr(e); + simcall->issuer->exception_ = std::make_exception_ptr(e); } } diff --git a/src/simix/smx_private.hpp b/src/simix/smx_private.hpp index 9bc917e7ee..ce23e8fde2 100644 --- a/src/simix/smx_private.hpp +++ b/src/simix/smx_private.hpp @@ -80,9 +80,9 @@ XBT_PUBLIC void SIMIX_clean(); if (1) { \ simgrid::kernel::actor::ActorImpl* _smx_throw_issuer = (issuer); /* evaluate only once */ \ xbt_ex e(XBT_THROW_POINT, msg); \ - e.category = cat; \ - e.value = val; \ - _smx_throw_issuer->exception = std::make_exception_ptr(e); \ + e.category = cat; \ + e.value = val; \ + _smx_throw_issuer->exception_ = std::make_exception_ptr(e); \ } else \ ((void)0) -- 2.20.1