smx_activity_t comm = simcall_HANDLER_comm_isend(simcall, src, mbox, task_size, rate, src_buff, src_buff_size,
match_fun, nullptr, copy_data_fun, data, 0);
SIMCALL_SET_MC_VALUE(simcall, 0);
- simcall_HANDLER_comm_wait(simcall, comm, timeout);
+ simcall_HANDLER_comm_wait(simcall, static_cast<simgrid::kernel::activity::CommImpl*>(comm.get()), timeout);
}
XBT_PRIVATE smx_activity_t simcall_HANDLER_comm_isend(
smx_activity_t comm = simcall_HANDLER_comm_irecv(simcall, receiver, mbox, dst_buff, dst_buff_size, match_fun,
copy_data_fun, data, rate);
SIMCALL_SET_MC_VALUE(simcall, 0);
- simcall_HANDLER_comm_wait(simcall, comm, timeout);
+ simcall_HANDLER_comm_wait(simcall, static_cast<simgrid::kernel::activity::CommImpl*>(comm.get()), timeout);
}
XBT_PRIVATE smx_activity_t simcall_HANDLER_comm_irecv(
return other_comm;
}
-void simcall_HANDLER_comm_wait(smx_simcall_t simcall, smx_activity_t synchro, double timeout)
+void simcall_HANDLER_comm_wait(smx_simcall_t simcall, simgrid::kernel::activity::CommImpl* comm, double timeout)
{
/* Associate this simcall to the wait synchro */
- XBT_DEBUG("simcall_HANDLER_comm_wait, %p", synchro.get());
+ XBT_DEBUG("simcall_HANDLER_comm_wait, %p", comm);
- synchro->simcalls_.push_back(simcall);
- simcall->issuer->waiting_synchro = synchro;
+ comm->simcalls_.push_back(simcall);
+ simcall->issuer->waiting_synchro = comm;
if (MC_is_active() || MC_record_replay_is_active()) {
int idx = SIMCALL_GET_MC_VALUE(simcall);
if (idx == 0) {
- synchro->state_ = SIMIX_DONE;
+ comm->state_ = SIMIX_DONE;
} else {
/* If we reached this point, the wait simcall must have a timeout */
/* Otherwise it shouldn't be enabled and executed by the MC */
if (timeout < 0.0)
THROW_IMPOSSIBLE;
- simgrid::kernel::activity::CommImplPtr comm =
- boost::static_pointer_cast<simgrid::kernel::activity::CommImpl>(synchro);
if (comm->src_actor_ == simcall->issuer)
comm->state_ = SIMIX_SRC_TIMEOUT;
else
comm->state_ = SIMIX_DST_TIMEOUT;
}
- boost::static_pointer_cast<simgrid::kernel::activity::CommImpl>(synchro)->finish();
+ comm->finish();
return;
}
/* If the synchro has already finish perform the error handling, */
/* otherwise set up a waiting timeout on the right side */
- if (synchro->state_ != SIMIX_WAITING && synchro->state_ != SIMIX_RUNNING) {
- boost::static_pointer_cast<simgrid::kernel::activity::CommImpl>(synchro)->finish();
+ if (comm->state_ != SIMIX_WAITING && comm->state_ != SIMIX_RUNNING) {
+ comm->finish();
} else { /* we need a sleep action (even when there is no timeout) to be notified of host failures */
simgrid::kernel::resource::Action* sleep = simcall->issuer->get_host()->pimpl_cpu->sleep(timeout);
- sleep->set_data(synchro.get());
+ sleep->set_data(comm);
- simgrid::kernel::activity::CommImplPtr comm =
- boost::static_pointer_cast<simgrid::kernel::activity::CommImpl>(synchro);
if (simcall->issuer == comm->src_actor_)
comm->src_timeout_ = sleep;
else
}
}
-void simcall_HANDLER_comm_test(smx_simcall_t simcall, smx_activity_t synchro)
+void simcall_HANDLER_comm_test(smx_simcall_t simcall, simgrid::kernel::activity::CommImpl* comm)
{
- simgrid::kernel::activity::CommImplPtr comm =
- boost::static_pointer_cast<simgrid::kernel::activity::CommImpl>(synchro);
-
int res;
if (MC_is_active() || MC_record_replay_is_active()) {
res = comm->src_actor_ && comm->dst_actor_;
if (res)
- synchro->state_ = SIMIX_DONE;
+ comm->state_ = SIMIX_DONE;
} else {
- res = synchro->state_ != SIMIX_WAITING && synchro->state_ != SIMIX_RUNNING;
+ res = comm->state_ != SIMIX_WAITING && comm->state_ != SIMIX_RUNNING;
}
simcall_comm_test__set__result(simcall, res);
if (simcall_comm_test__get__result(simcall)) {
- synchro->simcalls_.push_back(simcall);
- boost::static_pointer_cast<simgrid::kernel::activity::CommImpl>(synchro)->finish();
+ comm->simcalls_.push_back(simcall);
+ comm->finish();
} else {
SIMIX_simcall_answer(simcall);
}
}
-void simcall_HANDLER_comm_testany(smx_simcall_t simcall, simgrid::kernel::activity::ActivityImplPtr comms[],
- size_t count)
+void simcall_HANDLER_comm_testany(smx_simcall_t simcall, simgrid::kernel::activity::CommImpl* comms[], size_t count)
{
// The default result is -1 -- this means, "nothing is ready".
// It can be changed below, but only if something matches.
if (idx == -1) {
SIMIX_simcall_answer(simcall);
} else {
- simgrid::kernel::activity::ActivityImplPtr synchro = comms[idx];
+ simgrid::kernel::activity::CommImpl* comm = comms[idx];
simcall_comm_testany__set__result(simcall, idx);
- synchro->simcalls_.push_back(simcall);
- synchro->state_ = SIMIX_DONE;
- boost::static_pointer_cast<simgrid::kernel::activity::CommImpl>(synchro)->finish();
+ comm->simcalls_.push_back(simcall);
+ comm->state_ = SIMIX_DONE;
+ comm->finish();
}
return;
}
for (std::size_t i = 0; i != count; ++i) {
- simgrid::kernel::activity::ActivityImplPtr synchro = comms[i];
- if (synchro->state_ != SIMIX_WAITING && synchro->state_ != SIMIX_RUNNING) {
+ simgrid::kernel::activity::CommImpl* comm = comms[i];
+ if (comm->state_ != SIMIX_WAITING && comm->state_ != SIMIX_RUNNING) {
simcall_comm_testany__set__result(simcall, i);
- synchro->simcalls_.push_back(simcall);
- boost::static_pointer_cast<simgrid::kernel::activity::CommImpl>(synchro)->finish();
+ comm->simcalls_.push_back(simcall);
+ comm->finish();
return;
}
}
static void SIMIX_waitany_remove_simcall_from_actions(smx_simcall_t simcall)
{
- unsigned int cursor = 0;
- xbt_dynar_t synchros = simcall_comm_waitany__get__comms(simcall);
-
- simgrid::kernel::activity::ActivityImpl* ptr;
- xbt_dynar_foreach (synchros, cursor, ptr) {
- smx_activity_t synchro = simgrid::kernel::activity::ActivityImplPtr(ptr);
+ simgrid::kernel::activity::CommImpl** comms = simcall_comm_waitany__get__comms(simcall);
+ size_t count = simcall_comm_waitany__get__count(simcall);
+ for (size_t i = 0; i < count; i++) {
// Remove the first occurence of simcall:
- auto i = boost::range::find(synchro->simcalls_, simcall);
- if (i != synchro->simcalls_.end())
- synchro->simcalls_.erase(i);
+ auto* comm = comms[i];
+ auto j = boost::range::find(comm->simcalls_, simcall);
+ if (j != comm->simcalls_.end())
+ comm->simcalls_.erase(j);
}
}
-void simcall_HANDLER_comm_waitany(smx_simcall_t simcall, xbt_dynar_t synchros, double timeout)
+void simcall_HANDLER_comm_waitany(smx_simcall_t simcall, simgrid::kernel::activity::CommImpl* comms[], size_t count,
+ double timeout)
{
if (MC_is_active() || MC_record_replay_is_active()) {
if (timeout > 0.0)
xbt_die("Timeout not implemented for waitany in the model-checker");
- int idx = SIMCALL_GET_MC_VALUE(simcall);
- smx_activity_t synchro = xbt_dynar_get_as(synchros, idx, smx_activity_t);
- synchro->simcalls_.push_back(simcall);
+ int idx = SIMCALL_GET_MC_VALUE(simcall);
+ auto* comm = comms[idx];
+ comm->simcalls_.push_back(simcall);
simcall_comm_waitany__set__result(simcall, idx);
- synchro->state_ = SIMIX_DONE;
- boost::static_pointer_cast<simgrid::kernel::activity::CommImpl>(synchro)->finish();
+ comm->state_ = SIMIX_DONE;
+ comm->finish();
return;
}
});
}
- unsigned int cursor;
- simgrid::kernel::activity::ActivityImpl* ptr;
- xbt_dynar_foreach (synchros, cursor, ptr) {
- smx_activity_t synchro = simgrid::kernel::activity::ActivityImplPtr(ptr);
+ for (size_t i = 0; i < count; i++) {
/* associate this simcall to the the synchro */
- synchro->simcalls_.push_back(simcall);
+ auto* comm = comms[i];
+ comm->simcalls_.push_back(simcall);
/* see if the synchro is already finished */
- if (synchro->state_ != SIMIX_WAITING && synchro->state_ != SIMIX_RUNNING) {
- boost::static_pointer_cast<simgrid::kernel::activity::CommImpl>(synchro)->finish();
+ if (comm->state_ != SIMIX_WAITING && comm->state_ != SIMIX_RUNNING) {
+ comm->finish();
break;
}
}
CommImpl::~CommImpl()
{
- XBT_DEBUG("Really free communication %p", this);
+ XBT_DEBUG("Really free communication %p in state %d (detached = %d)", this, static_cast<int>(state_),
+ static_cast<int>(detached));
cleanupSurf();
if (clean_fun)
clean_fun(src_buff_);
src_buff_ = nullptr;
- }
-
- if (mbox)
+ } else if (mbox) {
mbox->remove(this);
+ }
}
/** @brief Starts the simulation of a communication synchro. */
{
/* if the synchro is a waiting state means that it is still in a mbox so remove from it and delete it */
if (state_ == SIMIX_WAITING) {
- mbox->remove(this);
- state_ = SIMIX_CANCELED;
+ if (not detached) {
+ mbox->remove(this);
+ state_ = SIMIX_CANCELED;
+ }
} else if (not MC_is_active() /* when running the MC there are no surf actions */
&& not MC_record_replay_is_active() && (state_ == SIMIX_READY || state_ == SIMIX_RUNNING)) {
surf_action_->cancel();
void CommImpl::finish()
{
- smx_activity_t synchro = this;
while (not simcalls_.empty()) {
smx_simcall_t simcall = simcalls_.front();
simcalls_.pop_front();
/* If a waitany simcall is waiting for this synchro to finish, then remove it from the other synchros in the waitany
- * list. Afterwards, get the position of the actual synchro in the waitany dynar and return it as the result of the
+ * list. Afterwards, get the position of the actual synchro in the waitany list and return it as the result of the
* simcall */
if (simcall->call == SIMCALL_NONE) // FIXME: maybe a better way to handle this case
simcall->timer->remove();
simcall->timer = nullptr;
}
- if (not MC_is_active() && not MC_record_replay_is_active())
- simcall_comm_waitany__set__result(simcall,
- xbt_dynar_search(simcall_comm_waitany__get__comms(simcall), &synchro));
+ if (not MC_is_active() && not MC_record_replay_is_active()) {
+ CommImpl** comms = simcall_comm_waitany__get__comms(simcall);
+ size_t count = simcall_comm_waitany__get__count(simcall);
+ CommImpl** element = std::find(comms, comms + count, this);
+ int rank = (element != comms + count) ? element - comms : -1;
+ simcall_comm_waitany__set__result(simcall, rank);
+ }
}
/* If the synchro is still in a rendez-vous point then remove from it */
xbt_die("Unexpected synchro state in CommImpl::finish: %d", static_cast<int>(state_));
}
}
-
/* if there is an exception during a waitany or a testany, indicate the position of the failed communication */
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;
+ CommImpl** comms;
+ size_t count;
if (simcall->call == SIMCALL_COMM_WAITANY) {
- rank = xbt_dynar_search(simcall_comm_waitany__get__comms(simcall), &synchro);
- } else if (simcall->call == SIMCALL_COMM_TESTANY) {
- rank = -1;
- auto* comms = simcall_comm_testany__get__comms(simcall);
- auto count = simcall_comm_testany__get__count(simcall);
- auto element = std::find(comms, comms + count, this);
- if (element == comms + count)
- rank = -1;
- else
- rank = element - comms;
+ comms = simcall_comm_waitany__get__comms(simcall);
+ count = simcall_comm_waitany__get__count(simcall);
+ } else {
+ /* simcall->call == SIMCALL_COMM_TESTANY */
+ comms = simcall_comm_testany__get__comms(simcall);
+ count = simcall_comm_testany__get__count(simcall);
}
+ CommImpl** element = std::find(comms, comms + count, this);
+ int rank = (element != comms + count) ? element - comms : -1;
// In order to modify the exception we have to rethrow it:
try {