Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of github.com:simgrid/simgrid into dev_11
authorEhsan Azimi <eazimi@ehsan.irisa.fr>
Thu, 26 Nov 2020 08:46:43 +0000 (09:46 +0100)
committerEhsan Azimi <eazimi@ehsan.irisa.fr>
Thu, 26 Nov 2020 08:46:43 +0000 (09:46 +0100)
1  2 
src/mc/checker/CommunicationDeterminismChecker.cpp
src/mc/checker/LivenessChecker.cpp
src/mc/checker/SafetyChecker.cpp
src/mc/mc_base.cpp
src/mc/mc_state.cpp
src/mc/mc_state.hpp

@@@ -11,7 -11,6 +11,7 @@@
  #include "src/mc/mc_private.hpp"
  #include "src/mc/mc_request.hpp"
  #include "src/mc/mc_smx.hpp"
 +#include "src/mc/mc_api.hpp"
  
  #if HAVE_SMPI
  #include "smpi_request.hpp"
@@@ -20,7 -19,6 +20,7 @@@
  #include <cstdint>
  
  using simgrid::mc::remote;
 +using mcapi = simgrid::mc::mc_api;
  
  XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_comm_determinism, mc, "Logging specific to MC communication determinism detection");
  
@@@ -31,27 -29,28 +31,28 @@@ std::vector<std::vector<simgrid::mc::Pa
  
  /********** Static functions ***********/
  
- static e_mc_comm_pattern_difference_t compare_comm_pattern(const simgrid::mc::PatternCommunication* comm1,
-                                                            const simgrid::mc::PatternCommunication* comm2)
+ static simgrid::mc::CommPatternDifference compare_comm_pattern(const simgrid::mc::PatternCommunication* comm1,
+                                                                const simgrid::mc::PatternCommunication* comm2)
  {
+   using simgrid::mc::CommPatternDifference;
    if(comm1->type != comm2->type)
-     return TYPE_DIFF;
+     return CommPatternDifference::TYPE;
    if (comm1->rdv != comm2->rdv)
-     return RDV_DIFF;
+     return CommPatternDifference::RDV;
    if (comm1->src_proc != comm2->src_proc)
-     return SRC_PROC_DIFF;
+     return CommPatternDifference::SRC_PROC;
    if (comm1->dst_proc != comm2->dst_proc)
-     return DST_PROC_DIFF;
+     return CommPatternDifference::DST_PROC;
    if (comm1->tag != comm2->tag)
-     return TAG_DIFF;
+     return CommPatternDifference::TAG;
    if (comm1->data.size() != comm2->data.size())
-     return DATA_SIZE_DIFF;
+     return CommPatternDifference::DATA_SIZE;
    if (comm1->data != comm2->data)
-     return DATA_DIFF;
-   return NONE_DIFF;
+     return CommPatternDifference::DATA;
+   return CommPatternDifference::NONE;
  }
  
- static char* print_determinism_result(e_mc_comm_pattern_difference_t diff, int process,
+ static char* print_determinism_result(simgrid::mc::CommPatternDifference diff, int process,
                                        const simgrid::mc::PatternCommunication* comm, unsigned int cursor)
  {
    char* type;
    else
      type = bprintf("The recv communications pattern of the process %d is different!", process - 1);
  
+   using simgrid::mc::CommPatternDifference;
    switch(diff) {
-   case TYPE_DIFF:
-     res = bprintf("%s Different type for communication #%u", type, cursor);
-     break;
-   case RDV_DIFF:
-     res = bprintf("%s Different rdv for communication #%u", type, cursor);
-     break;
-   case TAG_DIFF:
-     res = bprintf("%s Different tag for communication #%u", type, cursor);
-     break;
-   case SRC_PROC_DIFF:
-     res = bprintf("%s Different source for communication #%u", type, cursor);
-     break;
-   case DST_PROC_DIFF:
-     res = bprintf("%s Different destination for communication #%u", type, cursor);
-     break;
-   case DATA_SIZE_DIFF:
-     res = bprintf("%s Different data size for communication #%u", type, cursor);
-     break;
-   case DATA_DIFF:
-     res = bprintf("%s Different data for communication #%u", type, cursor);
-     break;
-   default:
-     res = nullptr;
-     break;
+     case CommPatternDifference::TYPE:
+       res = bprintf("%s Different type for communication #%u", type, cursor);
+       break;
+     case CommPatternDifference::RDV:
+       res = bprintf("%s Different rdv for communication #%u", type, cursor);
+       break;
+     case CommPatternDifference::TAG:
+       res = bprintf("%s Different tag for communication #%u", type, cursor);
+       break;
+     case CommPatternDifference::SRC_PROC:
+       res = bprintf("%s Different source for communication #%u", type, cursor);
+       break;
+     case CommPatternDifference::DST_PROC:
+       res = bprintf("%s Different destination for communication #%u", type, cursor);
+       break;
+     case CommPatternDifference::DATA_SIZE:
+       res = bprintf("%s Different data size for communication #%u", type, cursor);
+       break;
+     case CommPatternDifference::DATA:
+       res = bprintf("%s Different data for communication #%u", type, cursor);
+       break;
+     default:
+       res = nullptr;
+       break;
    }
  
    return res;
@@@ -125,9 -125,9 +127,9 @@@ void CommunicationDeterminismChecker::d
  {
    if (not backtracking) {
      PatternCommunicationList& list      = initial_communications_pattern[process];
-     e_mc_comm_pattern_difference_t diff = compare_comm_pattern(list.list[list.index_comm].get(), comm);
+     CommPatternDifference diff          = compare_comm_pattern(list.list[list.index_comm].get(), comm);
  
-     if (diff != NONE_DIFF) {
+     if (diff != CommPatternDifference::NONE) {
        if (comm->type == PatternCommunicationType::send) {
          this->send_deterministic = false;
          if (this->send_diff != nullptr)
  
  /********** Non Static functions ***********/
  
- void CommunicationDeterminismChecker::get_comm_pattern(smx_simcall_t request, e_mc_call_type_t call_type,
-                                                        int backtracking)
+ void CommunicationDeterminismChecker::get_comm_pattern(smx_simcall_t request, CallType call_type, int backtracking)
  {
 -  const smx_actor_t issuer = MC_smx_simcall_get_issuer(request);
 +  const smx_actor_t issuer = mcapi::get().mc_smx_simcall_get_issuer(request);
    const mc::PatternCommunicationList& initial_pattern          = initial_communications_pattern[issuer->get_pid()];
    const std::vector<PatternCommunication*>& incomplete_pattern = incomplete_communications_pattern[issuer->get_pid()];
  
    auto pattern   = std::make_unique<PatternCommunication>();
    pattern->index = initial_pattern.index_comm + incomplete_pattern.size();
  
-   if (call_type == MC_CALL_TYPE_SEND) {
+   if (call_type == CallType::SEND) {
      /* Create comm pattern */
      pattern->type      = PatternCommunicationType::send;
 -    pattern->comm_addr = static_cast<kernel::activity::CommImpl*>(simcall_comm_isend__getraw__result(request));
 +    pattern->comm_addr = mcapi::get().get_pattern_comm_addr(request);
  
      Remote<kernel::activity::CommImpl> temp_synchro;
      mc_model_checker->get_remote_simulation().read(temp_synchro, remote(pattern->comm_addr));
  
      char* remote_name = mc_model_checker->get_remote_simulation().read<char*>(RemotePtr<char*>(
          (uint64_t)(synchro->get_mailbox() ? &synchro->get_mailbox()->name_ : &synchro->mbox_cpy->name_)));
 -    pattern->rdv      = mc_model_checker->get_remote_simulation().read_string(RemotePtr<char>(remote_name));
 -    pattern->src_proc =
 -        mc_model_checker->get_remote_simulation().resolve_actor(mc::remote(synchro->src_actor_.get()))->get_pid();
 -    pattern->src_host = MC_smx_actor_get_host_name(issuer);
 +    pattern->rdv      = mcapi::get().get_pattern_comm_rdv(pattern->comm_addr);
 +    pattern->src_proc = mcapi::get().get_pattern_comm_src_proc(pattern->comm_addr);
 +    pattern->src_host = mc_api::get().get_actor_host_name(issuer);
  
  #if HAVE_SMPI
      simgrid::smpi::Request mpi_request;
      pattern->tag = mpi_request.tag();
  #endif
  
 -    if (synchro->src_buff_ != nullptr) {
 -      pattern->data.resize(synchro->src_buff_size_);
 -      mc_model_checker->get_remote_simulation().read_bytes(pattern->data.data(), pattern->data.size(),
 -                                                           remote(synchro->src_buff_));
 +    // if (synchro->src_buff_ != nullptr) {
 +    //   pattern->data.resize(synchro->src_buff_size_);
 +    //   mc_model_checker->get_remote_simulation().read_bytes(pattern->data.data(), pattern->data.size(),
 +    //                                                        remote(synchro->src_buff_));
 +    // }
 +
 +    auto pattern_data = mcapi::get().get_pattern_comm_data(pattern->comm_addr);
 +    if(pattern_data.data() != nullptr) {
 +      auto data_size = pattern_data.size();
 +      pattern->data.resize(data_size);
 +      memcpy(pattern->data.data(), pattern_data.data(), data_size);
      }
  #if HAVE_SMPI
      if(mpi_request.detached()){
        return;
      }
  #endif
-   } else if (call_type == MC_CALL_TYPE_RECV) {
+   } else if (call_type == CallType::RECV) {
      pattern->type      = PatternCommunicationType::receive;
      pattern->comm_addr = static_cast<kernel::activity::CommImpl*>(simcall_comm_irecv__getraw__result(request));
  
@@@ -304,8 -297,7 +305,7 @@@ std::vector<std::string> CommunicationD
    std::vector<std::string> trace;
    for (auto const& state : stack_) {
      smx_simcall_t req = &state->executed_req_;
-     if (req)
-       trace.push_back(mcapi::get().request_to_string(req, state->transition_.argument_, RequestType::executed));
+     trace.push_back(request_to_string(req, state->transition_.argument_, RequestType::executed));
    }
    return trace;
  }
@@@ -327,8 -319,8 +327,8 @@@ void CommunicationDeterminismChecker::l
      }
    }
    XBT_INFO("Expanded states = %lu", expanded_states_count_);
 -  XBT_INFO("Visited states = %lu", mc_model_checker->visited_states);
 -  XBT_INFO("Executed transitions = %lu", mc_model_checker->executed_transitions);
 +  XBT_INFO("Visited states = %lu", mcapi::get().mc_get_visited_states());
 +  XBT_INFO("Executed transitions = %lu", mcapi::get().mc_get_executed_trans());
    XBT_INFO("Send-deterministic : %s", this->send_deterministic ? "Yes" : "No");
    if (_sg_mc_comms_determinism)
      XBT_INFO("Recv-deterministic : %s", this->recv_deterministic ? "Yes" : "No");
  
  void CommunicationDeterminismChecker::prepare()
  {
 -  const int maxpid = MC_smx_get_maxpid();
 +  const int maxpid = mcapi::get().get_maxpid();
  
    initial_communications_pattern.resize(maxpid);
    incomplete_communications_pattern.resize(maxpid);
    XBT_DEBUG("********* Start communication determinism verification *********");
  
    /* Get an enabled actor and insert it in the interleave set of the initial state */
 -  for (auto& actor : mc_model_checker->get_remote_simulation().actors())
 -    if (mc::actor_is_enabled(actor.copy.get_buffer()))
 +  auto actors = mcapi::get().get_actors();
 +  for (auto& actor : actors)
 +    if (mcapi::get().actor_is_enabled(actor.copy.get_buffer()->get_pid()))
        initial_state->add_interleaving_set(actor.copy.get_buffer());
  
    stack_.push_back(std::move(initial_state));
  
  static inline bool all_communications_are_finished()
  {
 -  for (size_t current_actor = 1; current_actor < MC_smx_get_maxpid(); current_actor++) {
 +  auto maxpid = mcapi::get().get_maxpid();
 +  for (size_t current_actor = 1; current_actor < maxpid; current_actor++) {
      if (not incomplete_communications_pattern[current_actor].empty()) {
        XBT_DEBUG("Some communications are not finished, cannot stop the exploration! State not visited.");
        return false;
@@@ -372,15 -362,15 +372,15 @@@ void CommunicationDeterminismChecker::r
    /* Intermediate backtracking */
    State* last_state = stack_.back().get();
    if (last_state->system_state_) {
 -    last_state->system_state_->restore(&mc_model_checker->get_remote_simulation());
 +    last_state->system_state_->restore(&mcapi::get().mc_get_remote_simulation());
      MC_restore_communications_pattern(last_state);
      return;
    }
  
    /* Restore the initial state */
 -  mc::session->restore_initial_state();
 +  mcapi::get().s_restore_initial_state();
  
 -  unsigned n = MC_smx_get_maxpid();
 +  unsigned n = mcapi::get().get_maxpid();
    assert(n == incomplete_communications_pattern.size());
    assert(n == initial_communications_pattern.size());
    for (unsigned j=0; j < n ; j++) {
      /* 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 */
  
 -    const smx_actor_t issuer = MC_smx_simcall_get_issuer(saved_req);
 +    const smx_actor_t issuer = mcapi::get().mc_smx_simcall_get_issuer(saved_req);
      smx_simcall_t req        = &issuer->simcall_;
  
      /* TODO : handle test and testany simcalls */
-     e_mc_call_type_t call = MC_get_call_type(req);
-     mcapi::get().handle_simcall(state->transition_);
+     CallType call = MC_get_call_type(req);
+     mc_model_checker->handle_simcall(state->transition_);
      MC_handle_comm_pattern(call, req, req_num, 1);
 -    mc_model_checker->wait_for_requests();
 +    mcapi::get().mc_wait_for_requests();
  
      /* Update statistics */
 -    mc_model_checker->visited_states++;
 -    mc_model_checker->executed_transitions++;
 +    mcapi::get().mc_inc_visited_states();
 +    mcapi::get().mc_inc_executed_trans();
    }
  }
  
@@@ -429,38 -419,37 +429,38 @@@ void CommunicationDeterminismChecker::r
                cur_state->interleave_size());
  
      /* Update statistics */
 -    mc_model_checker->visited_states++;
 +    mcapi::get().mc_inc_visited_states();
  
      if (stack_.size() <= (std::size_t)_sg_mc_max_depth)
 -      req = MC_state_choose_request(cur_state);
 +      req = mcapi::get().mc_state_choose_request(cur_state);
      else
        req = nullptr;
  
      if (req != nullptr && visited_state == nullptr) {
        int req_num = cur_state->transition_.argument_;
  
 -      XBT_DEBUG("Execute: %s", request_to_string(req, req_num, RequestType::simix).c_str());
 +      XBT_DEBUG("Execute: %s", mcapi::get().request_to_string(req, req_num, RequestType::simix).c_str());
  
        std::string req_str;
        if (dot_output != nullptr)
 -        req_str = request_get_dot_output(req, req_num);
 +        req_str = mcapi::get().request_get_dot_output(req, req_num);
  
 -      mc_model_checker->executed_transitions++;
 +      mcapi::get().mc_inc_executed_trans();
  
        /* TODO : handle test and testany simcalls */
-       e_mc_call_type_t call = MC_CALL_TYPE_NONE;
+       CallType call = CallType::NONE;
        if (_sg_mc_comms_determinism || _sg_mc_send_determinism)
          call = MC_get_call_type(req);
  
        /* Answer the request */
 -      mc_model_checker->handle_simcall(cur_state->transition_);
 +      mcapi::get().handle_simcall(cur_state->transition_);
        /* After this call req is no longer useful */
  
        MC_handle_comm_pattern(call, req, req_num, 0);
  
 +
        /* Wait for requests (schedules processes) */
 -      mc_model_checker->wait_for_requests();
 +      mcapi::get().mc_wait_for_requests();
  
        /* Create the new expanded state */
        ++expanded_states_count_;
  
        if (visited_state == nullptr) {
          /* Get enabled actors and insert them in the interleave set of the next state */
 -        for (auto& actor : mc_model_checker->get_remote_simulation().actors())
 -          if (simgrid::mc::actor_is_enabled(actor.copy.get_buffer()))
 +        auto actors = mcapi::get().mc_get_remote_simulation().actors();
 +        for (auto& actor : actors)
 +          if (mcapi::get().actor_is_enabled(actor.copy.get_buffer()->get_pid()))
              next_state->add_interleaving_set(actor.copy.get_buffer());
  
          if (dot_output != nullptr)
        visited_state = nullptr;
  
        /* Check for deadlocks */
 -      if (mc_model_checker->checkDeadlock()) {
 -        MC_show_deadlock();
 +      if (mcapi::get().mc_check_deadlock()) {
 +        mcapi::get().mc_show_deadlock();
          throw simgrid::mc::DeadlockError();
        }
  
      }
    }
  
 -  mc::session->log_state();
 +  mcapi::get().s_log_state();
  }
  
  void CommunicationDeterminismChecker::run()
  {
    XBT_INFO("Check communication determinism");
 -  mc::session->initialize();
 +  mcapi::get().s_initialize();
  
    this->prepare();
    this->real_run();
  #include "src/mc/mc_private.hpp"
  #include "src/mc/mc_request.hpp"
  #include "src/mc/mc_smx.hpp"
 +#include "src/mc/mc_api.hpp"
  
  #include <boost/range/algorithm.hpp>
  #include <cstring>
  
  XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_liveness, mc, "Logging specific to algorithms for liveness properties verification");
  
 +using mcapi = simgrid::mc::mc_api;
 +
  /********* Static functions *********/
  
  namespace simgrid {
@@@ -147,16 -144,14 +147,14 @@@ void LivenessChecker::replay(
  
        smx_simcall_t req = nullptr;
  
-       if (saved_req != nullptr) {
-         /* 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 */
-         const smx_actor_t issuer = MC_smx_simcall_get_issuer(saved_req);
-         req                      = &issuer->simcall_;
-         /* Debug information */
-         XBT_DEBUG("Replay (depth = %d) : %s (%p)", depth,
-                   request_to_string(req, req_num, simgrid::mc::RequestType::simix).c_str(), state.get());
-       }
+       /* 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 */
+       const smx_actor_t issuer = MC_smx_simcall_get_issuer(saved_req);
+       req                      = &issuer->simcall_;
+       /* Debug information */
+       XBT_DEBUG("Replay (depth = %d) : %s (%p)", depth,
+                 request_to_string(req, req_num, simgrid::mc::RequestType::simix).c_str(), state.get());
  
        this->get_session().execute(state->transition_);
      }
@@@ -256,7 -251,7 +254,7 @@@ std::vector<std::string> LivenessChecke
    for (std::shared_ptr<Pair> const& pair : exploration_stack_) {
      int req_num       = pair->graph_state->transition_.argument_;
      smx_simcall_t req = &pair->graph_state->executed_req_;
-     if (req && req->call_ != SIMCALL_NONE)
+     if (req->call_ != simix::Simcall::NONE)
        trace.push_back(request_to_string(req, req_num, RequestType::executed));
    }
    return trace;
@@@ -373,7 -368,7 +371,7 @@@ void LivenessChecker::run(
        }
      }
  
 -    smx_simcall_t req = MC_state_choose_request(current_pair->graph_state.get());
 +    smx_simcall_t req = mcapi::get().mc_state_choose_request(current_pair->graph_state.get());
      int req_num       = current_pair->graph_state->transition_.argument_;
  
      if (dot_output != nullptr) {
  #include "src/mc/mc_record.hpp"
  #include "src/mc/mc_request.hpp"
  #include "src/mc/mc_smx.hpp"
 +#include "src/mc/mc_api.hpp"
  
  #include "src/xbt/mmalloc/mmprivate.h"
  
 +using mcapi = simgrid::mc::mc_api;
 +
  XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_safety, mc, "Logging specific to MC safety verification ");
  
  namespace simgrid {
@@@ -37,17 -34,16 +37,17 @@@ namespace mc 
  void SafetyChecker::check_non_termination(const State* current_state)
  {
    for (auto state = stack_.rbegin(); state != stack_.rend(); ++state)
 -    if (snapshot_equal((*state)->system_state_.get(), current_state->system_state_.get())) {
 +    if (mcapi::get().snapshot_equal((*state)->system_state_.get(), current_state->system_state_.get())) {
        XBT_INFO("Non-progressive cycle: state %d -> state %d", (*state)->num_, current_state->num_);
        XBT_INFO("******************************************");
        XBT_INFO("*** NON-PROGRESSIVE CYCLE DETECTED ***");
        XBT_INFO("******************************************");
        XBT_INFO("Counter-example execution trace:");
 -      for (auto const& s : mc_model_checker->getChecker()->get_textual_trace())
 +      auto checker = mcapi::get().mc_get_checker();
 +      for (auto const& s : checker->get_textual_trace())
          XBT_INFO("  %s", s.c_str());
 -      dumpRecordPath();
 -      session->log_state();
 +      mcapi::get().mc_dump_record_path();
 +      mcapi::get().s_log_state();
  
        throw TerminationError();
      }
@@@ -67,8 -63,7 +67,7 @@@ std::vector<std::string> SafetyChecker:
    for (auto const& state : stack_) {
      int value         = state->transition_.argument_;
      smx_simcall_t req = &state->executed_req_;
-     if (req)
-       trace.push_back(mcapi::get().request_to_string(req, value, RequestType::executed));
+     trace.push_back(request_to_string(req, value, RequestType::executed));
    }
    return trace;
  }
@@@ -76,8 -71,8 +75,8 @@@
  void SafetyChecker::log_state() // override
  {
    XBT_INFO("Expanded states = %lu", expanded_states_count_);
 -  XBT_INFO("Visited states = %lu", mc_model_checker->visited_states);
 -  XBT_INFO("Executed transitions = %lu", mc_model_checker->executed_transitions);
 +  XBT_INFO("Visited states = %lu", mcapi::get().mc_get_visited_states());
 +  XBT_INFO("Executed transitions = %lu", mcapi::get().mc_get_executed_trans());
  }
  
  void SafetyChecker::run()
@@@ -94,7 -89,7 +93,7 @@@
      XBT_VERB("Exploration depth=%zu (state=%p, num %d)(%zu interleave)", stack_.size(), state, state->num_,
               state->interleave_size());
  
 -    mc_model_checker->visited_states++;
 +    mcapi::get().mc_inc_visited_states();
  
      // Backtrack if we reached the maximum depth
      if (stack_.size() > (std::size_t)_sg_mc_max_depth) {
  
      // Search an enabled transition in the current state; backtrack if the interleave set is empty
      // get_request also sets state.transition to be the one corresponding to the returned req
 -    smx_simcall_t req = MC_state_choose_request(state);
 +    smx_simcall_t req = mcapi::get().mc_state_choose_request(state);
      // req is now the transition of the process that was selected to be executed
  
      if (req == nullptr) {
  
      // If there are processes to interleave and the maximum depth has not been
      // reached then perform one step of the exploration algorithm.
 -    XBT_DEBUG("Execute: %s", request_to_string(req, state->transition_.argument_, RequestType::simix).c_str());
 +    XBT_DEBUG("Execute: %s", mcapi::get().request_to_string(req, state->transition_.argument_, RequestType::simix).c_str());
  
      std::string req_str;
      if (dot_output != nullptr)
 -      req_str = request_get_dot_output(req, state->transition_.argument_);
 +      req_str = mcapi::get().request_get_dot_output(req, state->transition_.argument_);
  
 -    mc_model_checker->executed_transitions++;
 +    mcapi::get().mc_inc_executed_trans();
  
      /* Actually answer the request: let execute the selected request (MCed does one step) */
 -    this->get_session().execute(state->transition_);
 +    mcapi::get().execute(state->transition_);
  
      /* Create the new expanded state (copy the state of MCed into our MCer data) */
      ++expanded_states_count_;
      /* If this is a new state (or if we don't care about state-equality reduction) */
      if (visited_state_ == nullptr) {
        /* Get an enabled process and insert it in the interleave set of the next state */
 -      for (auto& remoteActor : mc_model_checker->get_remote_simulation().actors()) {
 +      auto actors = mcapi::get().mc_get_remote_simulation().actors();
 +      for (auto& remoteActor : actors) {
          auto actor = remoteActor.copy.get_buffer();
 -        if (actor_is_enabled(actor)) {
 +        if (mcapi::get().actor_is_enabled(actor->get_pid())) {
            next_state->add_interleaving_set(actor);
            if (reductionMode_ == ReductionMode::dpor)
              break; // With DPOR, we take the first enabled transition
    }
  
    XBT_INFO("No property violation found.");
 -  session->log_state();
 +  mcapi::get().s_log_state();
  }
  
  void SafetyChecker::backtrack()
    stack_.pop_back();
  
    /* Check for deadlocks */
 -  if (mc_model_checker->checkDeadlock()) {
 -    MC_show_deadlock();
 +  if (mcapi::get().mc_check_deadlock()) {
 +    mcapi::get().mc_show_deadlock();
      throw DeadlockError();
    }
  
      stack_.pop_back();
      if (reductionMode_ == ReductionMode::dpor) {
        smx_simcall_t req = &state->internal_req_;
-       if (req->call_ == SIMCALL_MUTEX_LOCK || req->call_ == SIMCALL_MUTEX_TRYLOCK)
+       if (req->call_ == simix::Simcall::MUTEX_LOCK || req->call_ == simix::Simcall::MUTEX_TRYLOCK)
          xbt_die("Mutex is currently not supported with DPOR,  use --cfg=model-check/reduction:none");
  
 -      const kernel::actor::ActorImpl* issuer = MC_smx_simcall_get_issuer(req);
 +      const kernel::actor::ActorImpl* issuer = mcapi::get().mc_smx_simcall_get_issuer(req);
        for (auto i = stack_.rbegin(); i != stack_.rend(); ++i) {
          State* prev_state = i->get();
 -        if (request_depend(req, &prev_state->internal_req_)) {
 +        if (mcapi::get().request_depend(req, &prev_state->internal_req_)) {
            if (XBT_LOG_ISENABLED(mc_safety, xbt_log_priority_debug)) {
              XBT_DEBUG("Dependent Transitions:");
              int value              = prev_state->transition_.argument_;
              smx_simcall_t prev_req = &prev_state->executed_req_;
 -            XBT_DEBUG("%s (state=%d)", simgrid::mc::request_to_string(prev_req, value, RequestType::internal).c_str(),
 +            XBT_DEBUG("%s (state=%d)", mcapi::get().request_to_string(prev_req, value, RequestType::internal).c_str(),
                        prev_state->num_);
              value    = state->transition_.argument_;
              prev_req = &state->executed_req_;
 -            XBT_DEBUG("%s (state=%d)", simgrid::mc::request_to_string(prev_req, value, RequestType::executed).c_str(),
 +            XBT_DEBUG("%s (state=%d)", mcapi::get().request_to_string(prev_req, value, RequestType::executed).c_str(),
                        state->num_);
            }
  
              XBT_DEBUG("Process %p is in done set", req->issuer_);
            break;
          } else if (req->issuer_ == prev_state->internal_req_.issuer_) {
 -          XBT_DEBUG("Simcall %s and %s with same issuer", SIMIX_simcall_name(req->call_),
 -                    SIMIX_simcall_name(prev_state->internal_req_.call_));
 +          XBT_DEBUG("Simcall %s and %s with same issuer", mcapi::get().simix_simcall_name(req->call_),
 +                    mcapi::get().simix_simcall_name(prev_state->internal_req_.call_));
            break;
          } else {
 -          const kernel::actor::ActorImpl* previous_issuer = MC_smx_simcall_get_issuer(&prev_state->internal_req_);
 +          const kernel::actor::ActorImpl* previous_issuer = mcapi::get().mc_smx_simcall_get_issuer(&prev_state->internal_req_);
            XBT_DEBUG("Simcall %s, process %ld (state %d) and simcall %s, process %ld (state %d) are independent",
 -                    SIMIX_simcall_name(req->call_), issuer->get_pid(), state->num_,
 -                    SIMIX_simcall_name(prev_state->internal_req_.call_), previous_issuer->get_pid(), prev_state->num_);
 +                    mcapi::get().simix_simcall_name(req->call_), issuer->get_pid(), state->num_,
 +                    mcapi::get().simix_simcall_name(prev_state->internal_req_.call_), previous_issuer->get_pid(), prev_state->num_);
          }
        }
      }
@@@ -252,21 -246,21 +251,21 @@@ void SafetyChecker::restore_state(
    /* Intermediate backtracking */
    const State* last_state = stack_.back().get();
    if (last_state->system_state_) {
 -    last_state->system_state_->restore(&mc_model_checker->get_remote_simulation());
 +    last_state->system_state_->restore(&mcapi::get().mc_get_remote_simulation());
      return;
    }
  
    /* Restore the initial state */
 -  session->restore_initial_state();
 +  mcapi::get().s_restore_initial_state();
  
    /* Traverse the stack from the state at position start and re-execute the transitions */
    for (std::unique_ptr<State> const& state : stack_) {
      if (state == stack_.back())
        break;
 -    session->execute(state->transition_);
 +    mcapi::get().execute(state->transition_);
      /* Update statistics */
 -    mc_model_checker->visited_states++;
 -    mc_model_checker->executed_transitions++;
 +    mcapi::get().mc_inc_visited_states();
 +    mcapi::get().mc_inc_executed_trans();
    }
  }
  
@@@ -284,8 -278,7 +283,8 @@@ SafetyChecker::SafetyChecker(Session& s
      XBT_INFO("Check a safety property. Reduction is: %s.",
               (reductionMode_ == ReductionMode::none ? "none"
                                                      : (reductionMode_ == ReductionMode::dpor ? "dpor" : "unknown")));
 -  session->initialize();
 +  
 +  mcapi::get().s_initialize();  
  
    XBT_DEBUG("Starting the safety algorithm");
  
    XBT_DEBUG("Initial state");
  
    /* Get an enabled actor and insert it in the interleave set of the initial state */
 -  for (auto& actor : mc_model_checker->get_remote_simulation().actors())
 -    if (actor_is_enabled(actor.copy.get_buffer())) {
 +  auto actors = mcapi::get().get_actors();
 +  for (auto& actor : actors)
 +    if (mcapi::get().actor_is_enabled(actor.copy.get_buffer()->get_pid())) {
        initial_state->add_interleaving_set(actor.copy.get_buffer());
        if (reductionMode_ != ReductionMode::none)
          break;
diff --combined src/mc/mc_base.cpp
@@@ -44,7 -44,7 +44,7 @@@ void wait_for_requests(
      simix_global->run_all_actors();
      for (smx_actor_t const& process : simix_global->actors_that_ran) {
        const s_smx_simcall* req = &process->simcall_;
-       if (req->call_ != SIMCALL_NONE && not simgrid::mc::request_is_visible(req))
+       if (req->call_ != simix::Simcall::NONE && not simgrid::mc::request_is_visible(req))
          process->simcall_handle(0);
      }
    }
  // Called from both MCer and MCed:
  bool actor_is_enabled(smx_actor_t actor)
  {
 +// #del
  #if SIMGRID_HAVE_MC
    // If in the MCer, ask the client app since it has all the data
    if (mc_model_checker != nullptr) {
      return simgrid::mc::session->actor_is_enabled(actor->get_pid());
    }
  #endif
 +// #
  
    // Now, we are in the client app, no need for remote memory reading.
    smx_simcall_t req = &actor->simcall_;
    if (req->inspector_ != nullptr)
      return req->inspector_->is_enabled();
  
+   using simix::Simcall;
    switch (req->call_) {
-     case SIMCALL_NONE:
+     case Simcall::NONE:
        return false;
  
-     case SIMCALL_COMM_WAIT: {
+     case Simcall::COMM_WAIT: {
        /* FIXME: check also that src and dst processes are not suspended */
        const kernel::activity::CommImpl* act = simcall_comm_wait__getraw__comm(req);
  
        return (act->src_actor_ && act->dst_actor_);
      }
  
-     case SIMCALL_COMM_WAITANY: {
+     case Simcall::COMM_WAITANY: {
        simgrid::kernel::activity::CommImpl** comms = simcall_comm_waitany__get__comms(req);
        size_t count                                = simcall_comm_waitany__get__count(req);
        for (unsigned int index = 0; index < count; ++index) {
        return false;
      }
  
-     case SIMCALL_MUTEX_LOCK: {
+     case Simcall::MUTEX_LOCK: {
        const kernel::activity::MutexImpl* mutex = simcall_mutex_lock__get__mutex(req);
  
        if (mutex->get_owner() == nullptr)
        return mutex->get_owner()->get_pid() == req->issuer_->get_pid();
      }
  
-     case SIMCALL_SEM_ACQUIRE: {
+     case Simcall::SEM_ACQUIRE: {
        static int warned = 0;
        if (not warned)
          XBT_INFO("Using semaphore in model-checked code is still experimental. Use at your own risk");
        return true;
      }
  
-     case SIMCALL_COND_WAIT: {
+     case Simcall::COND_WAIT: {
        static int warned = 0;
        if (not warned)
          XBT_INFO("Using condition variables in model-checked code is still experimental. Use at your own risk");
@@@ -156,10 -155,12 +157,12 @@@ bool request_is_visible(const s_smx_sim
    xbt_assert(mc_model_checker == nullptr, "This should be called from the client side");
  #endif
  
-   return (req->inspector_ != nullptr && req->inspector_->is_visible()) || req->call_ == SIMCALL_COMM_ISEND ||
-          req->call_ == SIMCALL_COMM_IRECV || req->call_ == SIMCALL_COMM_WAIT || req->call_ == SIMCALL_COMM_WAITANY ||
-          req->call_ == SIMCALL_COMM_TEST || req->call_ == SIMCALL_COMM_TESTANY || req->call_ == SIMCALL_MC_RANDOM ||
-          req->call_ == SIMCALL_MUTEX_LOCK || req->call_ == SIMCALL_MUTEX_TRYLOCK || req->call_ == SIMCALL_MUTEX_UNLOCK;
+   using simix::Simcall;
+   return (req->inspector_ != nullptr && req->inspector_->is_visible()) || req->call_ == Simcall::COMM_ISEND ||
+          req->call_ == Simcall::COMM_IRECV || req->call_ == Simcall::COMM_WAIT || req->call_ == Simcall::COMM_WAITANY ||
+          req->call_ == Simcall::COMM_TEST || req->call_ == Simcall::COMM_TESTANY || req->call_ == Simcall::MC_RANDOM ||
+          req->call_ == Simcall::MUTEX_LOCK || req->call_ == Simcall::MUTEX_TRYLOCK ||
+          req->call_ == Simcall::MUTEX_UNLOCK;
  }
  
  }
diff --combined src/mc/mc_state.cpp
@@@ -4,13 -4,14 +4,13 @@@
   * under the terms of the license (GNU LGPL) which comes with this package. */
  
  #include "src/mc/mc_state.hpp"
 -#include "src/mc/mc_comm_pattern.hpp"
  #include "src/mc/mc_config.hpp"
 -#include "src/mc/mc_request.hpp"
 -#include "src/mc/mc_smx.hpp"
 +#include "src/mc/mc_api.hpp"
  
  #include <boost/range/algorithm.hpp>
  
  using simgrid::mc::remote;
 +using mcapi = simgrid::mc::mc_api;
  
  namespace simgrid {
  namespace mc {
  State::State(unsigned long state_number) : num_(state_number)
  {
    this->internal_comm_.clear();
 -
 -  actor_states_.resize(MC_smx_get_maxpid());
 +  auto maxpid = mcapi::get().get_maxpid();
 +  actor_states_.resize(maxpid);
    /* Stateful model checking */
    if ((_sg_mc_checkpoint > 0 && (state_number % _sg_mc_checkpoint == 0)) || _sg_mc_termination) {
 -    system_state_ = std::make_shared<simgrid::mc::Snapshot>(num_);
 +    auto snapshot_ptr = mcapi::get().take_snapshot(num_);
 +    system_state_ = std::shared_ptr<simgrid::mc::Snapshot>(snapshot_ptr);
      if (_sg_mc_comms_determinism || _sg_mc_send_determinism) {
 -      MC_state_copy_incomplete_communications_pattern(this);
 -      MC_state_copy_index_communications_pattern(this);
 +      mcapi::get().copy_incomplete_comm_pattern(this);
 +      mcapi::get().copy_index_comm_pattern(this);
      }
    }
  }
@@@ -43,3 -43,173 +43,173 @@@ Transition State::get_transition() cons
  
  }
  }
+ /* Search an enabled transition for the given process.
+  *
+  * This can be seen as an iterator returning the next transition of the process.
+  *
+  * We only consider the processes that are both
+  *  - marked "to be interleaved" in their ActorState (controlled by the checker algorithm).
+  *  - which simcall can currently be executed (like a comm where the other partner is already known)
+  * Once we returned the last enabled transition of a process, it is marked done.
+  *
+  * Things can get muddled with the WAITANY and TESTANY simcalls, that are rewritten on the fly to a bunch of WAIT
+  * (resp TEST) transitions using the transition.argument field to remember what was the last returned sub-transition.
+  */
+ static inline smx_simcall_t MC_state_choose_request_for_process(simgrid::mc::State* state, smx_actor_t actor)
+ {
+   using simgrid::simix::Simcall;
+   /* reset the outgoing transition */
+   simgrid::mc::ActorState* procstate   = &state->actor_states_[actor->get_pid()];
+   state->transition_.pid_              = -1;
+   state->transition_.argument_         = -1;
+   state->executed_req_.call_           = Simcall::NONE;
+   if (not simgrid::mc::actor_is_enabled(actor))
+     return nullptr; // Not executable in the application
+   smx_simcall_t req = nullptr;
+   switch (actor->simcall_.call_) {
+     case Simcall::COMM_WAITANY:
+       state->transition_.argument_ = -1;
+       while (procstate->times_considered < simcall_comm_waitany__get__count(&actor->simcall_)) {
+         if (simgrid::mc::request_is_enabled_by_idx(&actor->simcall_, procstate->times_considered)) {
+           state->transition_.argument_ = procstate->times_considered;
+           ++procstate->times_considered;
+           break;
+         }
+         ++procstate->times_considered;
+       }
+       if (procstate->times_considered >= simcall_comm_waitany__get__count(&actor->simcall_))
+         procstate->set_done();
+       if (state->transition_.argument_ != -1)
+         req = &actor->simcall_;
+       break;
+     case Simcall::COMM_TESTANY: {
+       unsigned start_count       = procstate->times_considered;
+       state->transition_.argument_ = -1;
+       while (procstate->times_considered < simcall_comm_testany__get__count(&actor->simcall_)) {
+         if (simgrid::mc::request_is_enabled_by_idx(&actor->simcall_, procstate->times_considered)) {
+           state->transition_.argument_ = procstate->times_considered;
+           ++procstate->times_considered;
+           break;
+         }
+         ++procstate->times_considered;
+       }
+       if (procstate->times_considered >= simcall_comm_testany__get__count(&actor->simcall_))
+         procstate->set_done();
+       if (state->transition_.argument_ != -1 || start_count == 0)
+         req = &actor->simcall_;
+       break;
+     }
+     case Simcall::COMM_WAIT: {
+       simgrid::mc::RemotePtr<simgrid::kernel::activity::CommImpl> remote_act =
+           remote(simcall_comm_wait__getraw__comm(&actor->simcall_));
+       simgrid::mc::Remote<simgrid::kernel::activity::CommImpl> temp_act;
+       mc_model_checker->get_remote_simulation().read(temp_act, remote_act);
+       const simgrid::kernel::activity::CommImpl* act = temp_act.get_buffer();
+       if (act->src_actor_.get() && act->dst_actor_.get())
+         state->transition_.argument_ = 0; // OK
+       else if (act->src_actor_.get() == nullptr && act->type_ == simgrid::kernel::activity::CommImpl::Type::READY &&
+                act->detached())
+         state->transition_.argument_ = 0; // OK
+       else
+         state->transition_.argument_ = -1; // timeout
+       procstate->set_done();
+       req = &actor->simcall_;
+       break;
+     }
+     case Simcall::MC_RANDOM: {
+       int min_value                = simcall_mc_random__get__min(&actor->simcall_);
+       state->transition_.argument_ = procstate->times_considered + min_value;
+       procstate->times_considered++;
+       if (state->transition_.argument_ == simcall_mc_random__get__max(&actor->simcall_))
+         procstate->set_done();
+       req = &actor->simcall_;
+       break;
+     }
+     default:
+       procstate->set_done();
+       state->transition_.argument_ = 0;
+       req                          = &actor->simcall_;
+       break;
+   }
+   if (not req)
+     return nullptr;
+   state->transition_.pid_ = actor->get_pid();
+   state->executed_req_    = *req;
+   // Fetch the data of the request and translate it:
+   state->internal_req_ = *req;
+   /* The waitany and testany request are transformed into a wait or test request over the corresponding communication
+    * action so it can be treated later by the dependence function. */
+   switch (req->call_) {
+     case Simcall::COMM_WAITANY: {
+       state->internal_req_.call_ = Simcall::COMM_WAIT;
+       simgrid::kernel::activity::CommImpl* remote_comm;
+       remote_comm = mc_model_checker->get_remote_simulation().read(
+           remote(simcall_comm_waitany__get__comms(req) + state->transition_.argument_));
+       mc_model_checker->get_remote_simulation().read(state->internal_comm_, remote(remote_comm));
+       simcall_comm_wait__set__comm(&state->internal_req_, state->internal_comm_.get_buffer());
+       simcall_comm_wait__set__timeout(&state->internal_req_, 0);
+       break;
+     }
+     case Simcall::COMM_TESTANY:
+       state->internal_req_.call_ = Simcall::COMM_TEST;
+       if (state->transition_.argument_ > 0) {
+         simgrid::kernel::activity::CommImpl* remote_comm = mc_model_checker->get_remote_simulation().read(
+             remote(simcall_comm_testany__get__comms(req) + state->transition_.argument_));
+         mc_model_checker->get_remote_simulation().read(state->internal_comm_, remote(remote_comm));
+       }
+       simcall_comm_test__set__comm(&state->internal_req_, state->internal_comm_.get_buffer());
+       simcall_comm_test__set__result(&state->internal_req_, state->transition_.argument_);
+       break;
+     case Simcall::COMM_WAIT:
+       mc_model_checker->get_remote_simulation().read_bytes(&state->internal_comm_, sizeof(state->internal_comm_),
+                                                            remote(simcall_comm_wait__getraw__comm(req)));
+       simcall_comm_wait__set__comm(&state->executed_req_, state->internal_comm_.get_buffer());
+       simcall_comm_wait__set__comm(&state->internal_req_, state->internal_comm_.get_buffer());
+       break;
+     case Simcall::COMM_TEST:
+       mc_model_checker->get_remote_simulation().read_bytes(&state->internal_comm_, sizeof(state->internal_comm_),
+                                                            remote(simcall_comm_test__getraw__comm(req)));
+       simcall_comm_test__set__comm(&state->executed_req_, state->internal_comm_.get_buffer());
+       simcall_comm_test__set__comm(&state->internal_req_, state->internal_comm_.get_buffer());
+       break;
+     default:
+       /* No translation needed */
+       break;
+   }
+   return req;
+ }
+ smx_simcall_t MC_state_choose_request(simgrid::mc::State* state)
+ {
+   for (auto& actor : mc_model_checker->get_remote_simulation().actors()) {
+     /* Only consider the actors that were marked as interleaving by the checker algorithm */
+     if (not state->actor_states_[actor.copy.get_buffer()->get_pid()].is_todo())
+       continue;
+     smx_simcall_t res = MC_state_choose_request_for_process(state, actor.copy.get_buffer());
+     if (res)
+       return res;
+   }
+   return nullptr;
+ }
diff --combined src/mc/mc_state.hpp
@@@ -6,13 -6,90 +6,13 @@@
  #ifndef SIMGRID_MC_STATE_HPP
  #define SIMGRID_MC_STATE_HPP
  
 -#include "src/kernel/activity/CommImpl.hpp"
  #include "src/mc/Transition.hpp"
  #include "src/mc/sosp/Snapshot.hpp"
 +#include "src/mc/mc_pattern.hpp"
  
  namespace simgrid {
  namespace mc {
  
 -enum class PatternCommunicationType {
 -  none    = 0,
 -  send    = 1,
 -  receive = 2,
 -};
 -
 -class PatternCommunication {
 -public:
 -  int num = 0;
 -  simgrid::kernel::activity::CommImpl* comm_addr;
 -  PatternCommunicationType type = PatternCommunicationType::send;
 -  unsigned long src_proc        = 0;
 -  unsigned long dst_proc        = 0;
 -  const char* src_host          = nullptr;
 -  const char* dst_host          = nullptr;
 -  std::string rdv;
 -  std::vector<char> data;
 -  int tag   = 0;
 -  int index = 0;
 -
 -  PatternCommunication() { std::memset(&comm_addr, 0, sizeof(comm_addr)); }
 -
 -  PatternCommunication dup() const
 -  {
 -    simgrid::mc::PatternCommunication res;
 -    // num?
 -    res.comm_addr = this->comm_addr;
 -    res.type      = this->type;
 -    // src_proc?
 -    // dst_proc?
 -    res.dst_proc = this->dst_proc;
 -    res.dst_host = this->dst_host;
 -    res.rdv      = this->rdv;
 -    res.data     = this->data;
 -    // tag?
 -    res.index = this->index;
 -    return res;
 -  }
 -};
 -
 -/* On every state, each actor has an entry of the following type.
 - * This represents both the actor and its transition because
 - *   an actor cannot have more than one enabled transition at a given time.
 - */
 -class ActorState {
 -  /* Possible exploration status of an actor transition in a state.
 -   * Either the checker did not consider the transition, or it was considered and still to do, or considered and done.
 -   */
 -  enum class InterleavingType {
 -    /** This actor transition is not considered by the checker (yet?) */
 -    disabled = 0,
 -    /** The checker algorithm decided that this actor transitions should be done at some point */
 -    todo,
 -    /** The checker algorithm decided that this should be done, but it was done in the meanwhile */
 -    done,
 -  };
 -
 -  /** Exploration control information */
 -  InterleavingType state = InterleavingType::disabled;
 -
 -public:
 -  /** Number of times that the process was considered to be executed */
 -  // TODO, make this private
 -  unsigned int times_considered = 0;
 -
 -  bool is_disabled() const { return this->state == InterleavingType::disabled; }
 -  bool is_done() const { return this->state == InterleavingType::done; }
 -  bool is_todo() const { return this->state == InterleavingType::todo; }
 -  /** Mark that we should try executing this process at some point in the future of the checker algorithm */
 -  void consider()
 -  {
 -    this->state            = InterleavingType::todo;
 -    this->times_considered = 0;
 -  }
 -  void set_done() { this->state = InterleavingType::done; }
 -};
 -
  /* A node in the exploration graph (kind-of) */
  class XBT_PRIVATE State {
  public:
  
    /* Internal translation of the executed_req simcall
     *
-    * SIMCALL_COMM_TESTANY is translated to a SIMCALL_COMM_TEST
-    * and SIMCALL_COMM_WAITANY to a SIMCALL_COMM_WAIT.
+    * Simcall::COMM_TESTANY is translated to a Simcall::COMM_TEST
+    * and Simcall::COMM_WAITANY to a Simcall::COMM_WAIT.
     */
    s_smx_simcall internal_req_;