std::string send_diff;
std::string recv_diff;
- void restore_communications_pattern(simgrid::mc::State* state);
+ void restore_communications_pattern(const simgrid::mc::State* state);
void deterministic_comm_pattern(aid_t process, const PatternCommunication* comm, bool backtracking);
void get_comm_pattern(smx_simcall_t request, CallType call_type, bool backtracking);
void complete_comm_pattern(RemotePtr<kernel::activity::CommImpl> const& comm_addr, aid_t issuer, bool backtracking);
- void handle_comm_pattern(simgrid::mc::CallType call_type, smx_simcall_t req, int value, bool backtracking);
+ void handle_comm_pattern(const Transition* transition, smx_simcall_t req, int value, bool backtracking);
};
simgrid::xbt::Extension<simgrid::mc::Checker, CommDetExtension> CommDetExtension::EXTENSION_ID;
/********** State Extension ***********/
return CommPatternDifference::NONE;
}
-static void patterns_copy(std::vector<simgrid::mc::PatternCommunication*>& dest,
- std::vector<simgrid::mc::PatternCommunication> const& source)
-{
- dest.clear();
- for (simgrid::mc::PatternCommunication const& comm : source) {
- auto* copy_comm = new simgrid::mc::PatternCommunication(comm.dup());
- dest.push_back(copy_comm);
- }
-}
-
-void CommDetExtension::restore_communications_pattern(simgrid::mc::State* state)
+void CommDetExtension::restore_communications_pattern(const simgrid::mc::State* state)
{
for (size_t i = 0; i < initial_communications_pattern.size(); i++)
initial_communications_pattern[i].index_comm =
state->extension<simgrid::mc::StateCommDet>()->communication_indices_[i];
const unsigned long maxpid = api::get().get_maxpid();
- for (unsigned long i = 0; i < maxpid; i++)
- patterns_copy(incomplete_communications_pattern[i],
- state->extension<simgrid::mc::StateCommDet>()->incomplete_comm_pattern_[i]);
+ for (unsigned long i = 0; i < maxpid; i++) {
+ incomplete_communications_pattern[i].clear();
+ for (simgrid::mc::PatternCommunication const& comm :
+ state->extension<simgrid::mc::StateCommDet>()->incomplete_comm_pattern_[i])
+ incomplete_communications_pattern[i].push_back(new simgrid::mc::PatternCommunication(comm.dup()));
+ }
}
static std::string print_determinism_result(simgrid::mc::CommPatternDifference diff, aid_t process,
return res;
}
-static void update_comm_pattern(simgrid::mc::PatternCommunication* comm_pattern,
- simgrid::mc::RemotePtr<simgrid::kernel::activity::CommImpl> const& comm_addr)
-{
- auto src_proc = api::get().get_src_actor(comm_addr);
- auto dst_proc = api::get().get_dst_actor(comm_addr);
- comm_pattern->src_proc = src_proc->get_pid();
- comm_pattern->dst_proc = dst_proc->get_pid();
-
- if (comm_pattern->data.empty()) {
- comm_pattern->data = api::get().get_pattern_comm_data(comm_addr);
- }
-}
-
void CommDetExtension::deterministic_comm_pattern(aid_t actor, const PatternCommunication* comm, bool backtracking)
{
if (not backtracking) {
std::find_if(begin(incomplete_pattern), end(incomplete_pattern),
[&comm_addr](const PatternCommunication* comm) { return (comm->comm_addr == comm_addr); });
xbt_assert(current_comm_pattern != std::end(incomplete_pattern), "Corresponding communication not found!");
-
- update_comm_pattern(*current_comm_pattern, comm_addr);
std::unique_ptr<PatternCommunication> comm_pattern(*current_comm_pattern);
+
+ comm_pattern->src_proc = api::get().get_src_actor(comm_addr)->get_pid();
+ comm_pattern->dst_proc = api::get().get_dst_actor(comm_addr)->get_pid();
+ if (comm_pattern->data.empty())
+ comm_pattern->data = api::get().get_pattern_comm_data(comm_addr);
+
XBT_DEBUG("Remove incomplete comm pattern for process %ld at cursor %zd", issuer,
std::distance(begin(incomplete_pattern), current_comm_pattern));
incomplete_pattern.erase(current_comm_pattern);
{
auto extension = this->extension<CommDetExtension>();
- /* Intermediate backtracking */
+ /* If asked to rollback on a state that has a snapshot, restore it */
State* last_state = stack_.back().get();
if (last_state->system_state_) {
api::get().restore_state(last_state->system_state_);
return;
}
+ /* if no snapshot, we need to restore the initial state and replay the transitions */
get_session().restore_initial_state();
const unsigned long maxpid = api::get().get_maxpid();
if (state == stack_.back())
break;
- int req_num = state->get_transition()->times_considered_;
- const s_smx_simcall* saved_req = &state->executed_req_;
- xbt_assert(saved_req);
-
- /* because we got a copy of the executed request, we have to fetch the
- real one, pointed by the request field of the issuer process */
+ auto* transition = state->get_transition();
+ /* because we got a copy of the executed request, we have to fetch the real one,
+ pointed by the request field of the issuer process */
+ auto* saved_req = &state->executed_req_;
const smx_actor_t issuer = api::get().simcall_get_issuer(saved_req);
smx_simcall_t req = &issuer->simcall_;
/* TODO : handle test and testany simcalls */
- CallType call = MC_get_call_type(req);
- state->get_transition()->replay();
- extension->handle_comm_pattern(call, req, req_num, true);
+ transition->replay();
+ extension->handle_comm_pattern(transition, req, transition->times_considered_, true);
/* Update statistics */
api::get().mc_inc_visited_states();
}
}
-void CommDetExtension::handle_comm_pattern(simgrid::mc::CallType call_type, smx_simcall_t req, int value,
+void CommDetExtension::handle_comm_pattern(const Transition* transition, smx_simcall_t req, int value,
bool backtracking)
{
+ if (not _sg_mc_comms_determinism && not _sg_mc_send_determinism)
+ return;
+
using simgrid::mc::CallType;
- switch(call_type) {
+ switch (MC_get_call_type(req)) {
case CallType::NONE:
break;
case CallType::SEND:
+ get_comm_pattern(req, CallType::SEND, backtracking);
+ break;
case CallType::RECV:
- get_comm_pattern(req, call_type, backtracking);
+ get_comm_pattern(req, CallType::RECV, backtracking);
break;
- case CallType::WAIT:
+ case CallType::WAIT: {
+ auto comm_addr = remote(simcall_comm_wait__getraw__comm(req));
+ auto simcall_issuer = api::get().simcall_get_issuer(req);
+ complete_comm_pattern(comm_addr, simcall_issuer->get_pid(), backtracking);
+ break;
+ }
case CallType::WAITANY: {
- RemotePtr<simgrid::kernel::activity::CommImpl> comm_addr;
- if (call_type == CallType::WAIT)
- comm_addr = remote(simcall_comm_wait__getraw__comm(req));
- else
- comm_addr = api::get().get_comm_waitany_raw_addr(req, value);
+ auto comm_addr = api::get().get_comm_waitany_raw_addr(req, value);
auto simcall_issuer = api::get().simcall_get_issuer(req);
complete_comm_pattern(comm_addr, simcall_issuer->get_pid(), backtracking);
} break;
default:
- xbt_die("Unexpected call type %i", (int)call_type);
+ xbt_die("Unexpected call type %i", (int)MC_get_call_type(req));
}
}
if (next_transition >= 0 && visited_state == nullptr) {
cur_state->execute_next(next_transition);
- int req_num = cur_state->get_transition()->times_considered_;
+ auto* transition = cur_state->get_transition();
smx_simcall_t req = &cur_state->executed_req_;
- XBT_DEBUG("Execute: %s", cur_state->get_transition()->to_string().c_str());
+ XBT_DEBUG("Execute: %s", transition->to_string().c_str());
std::string req_str;
if (dot_output != nullptr)
- req_str = api::get().request_get_dot_output(cur_state->get_transition());
-
- /* TODO : handle test and testany simcalls */
- CallType call = CallType::NONE;
- if (_sg_mc_comms_determinism || _sg_mc_send_determinism)
- call = MC_get_call_type(req);
+ req_str = api::get().request_get_dot_output(transition);
- extension->handle_comm_pattern(call, req, req_num, false);
+ extension->handle_comm_pattern(transition, req, transition->times_considered_, false);
/* Create the new expanded state */
auto next_state = std::make_unique<State>();