- `simcall_BODY_<name>(<args>)`
- 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_<name>(simcall, <args>)` (the manual code handling the simcall)
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<SwappedContext*>(self());
Context::set_current(this);
}
}
-/** 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.
*
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())
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()
{
void ActorImpl::throw_exception(std::exception_ptr e)
{
- exception = e;
+ exception_ = e;
if (suspended_)
resume();
*
* @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
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;
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_; }
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);
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);
}
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);
}
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:
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<int>(synchro->state_));
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_) {
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;
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;
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;
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;
}
/* 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;
// 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);
}
}
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)