/* Stateful model checking */
if ((_sg_mc_checkpoint > 0 && (num_ % _sg_mc_checkpoint == 0)) || _sg_mc_termination)
system_state_ = std::make_shared<simgrid::mc::Snapshot>(num_, remote_app.get_page_store(),
- remote_app.get_remote_process_memory());
+ *remote_app.get_remote_process_memory());
}
-State::State(RemoteApp& remote_app, const State* parent_state)
- : num_(++expended_states_), parent_state_(parent_state), guide(std::make_unique<BasicGuide>())
+State::State(RemoteApp& remote_app, const State* parent_state) : num_(++expended_states_), parent_state_(parent_state)
{
- remote_app.get_actors_status(guide->actors_to_run_);
+ if (_sg_mc_guided == "none")
+ guide_ = std::make_unique<BasicGuide>();
+ if (_sg_mc_guided == "nb_wait")
+ guide_ = std::make_unique<WaitGuide>();
+ *guide_ = *(parent_state->guide_);
+
+ remote_app.get_actors_status(guide_->actors_to_run_);
/* Stateful model checking */
if ((_sg_mc_checkpoint > 0 && (num_ % _sg_mc_checkpoint == 0)) || _sg_mc_termination)
if (not parent_state_->get_transition()->depends(&transition)) {
- sleep_set_.emplace(aid, transition);
+ sleep_set_.try_emplace(aid, transition);
- if (guide->actors_to_run_.count(aid) != 0) {
+ if (guide_->actors_to_run_.count(aid) != 0) {
XBT_DEBUG("Actor %ld will not be explored, for it is in the sleep set", aid);
- guide->actors_to_run_.at(aid).mark_done();
+ guide_->actors_to_run_.at(aid).mark_done();
}
} else
XBT_DEBUG("Transition >>%s<< removed from the sleep set because it was dependent with >>%s<<",
if (stack_.back()->get_transition()->aid_ == 0)
stack_.pop_back();
- /* Traverse the stack backwards until a state with a non empty interleave set is found, deleting all the states that
- * have it empty in the way. */
- bool found_backtracking_point = false;
- while (not stack_.empty() && not found_backtracking_point) {
- std::unique_ptr<State> state = std::move(stack_.back());
-
- stack_.pop_back();
-
+ stack_t backtrack;
+ double min_dist = std::numeric_limits<double>::infinity();
+ aid_t min_aid = -1;
+ for (auto& stack : opened_states) {
+ auto [aid, dist] = stack.back()->next_transition_guided();
+ if (aid == -1)
+ continue;
+ if (dist < min_dist) {
+ min_dist = dist;
+ min_aid = aid;
+ backtrack = stack;
+ }
+ }
- if (state->count_todo() == 0) { // Empty interleaving set: exploration at this level is over
- XBT_DEBUG("Delete state %ld at depth %zu", state->get_num(), stack_.size() + 1);
+ if (min_aid == -1) {
+ stack_ = std::list<std::shared_ptr<State>>();
+ return;
+ }
- } else {
- XBT_DEBUG("Back-tracking to state %ld at depth %zu: %lu transitions left to be explored", state->get_num(),
- stack_.size() + 1, state->count_todo());
- stack_.push_back(
- std::move(state)); // Put it back on the stack so we can explore the next transition of the interleave
- found_backtracking_point = true;
- }
+ if (backtrack.back()->count_todo() <= 1)
+ opened_states.pop_back();
+ XBT_VERB("%lu todo actors in last states of the next backtracking point %s (remaining %lu opened stacks)",
+ backtrack.back()->count_todo(), backtrack.back()->get_transition()->to_string().c_str(),
+ opened_states.size());
+
+ /* If asked to rollback on a state that has a snapshot, restore it */
+ State* last_state = backtrack.back().get();
+ if (const auto* system_state = last_state->get_system_state()) {
- system_state->restore(get_remote_app().get_remote_process_memory());
++ system_state->restore(*get_remote_app().get_remote_process_memory());
+ on_restore_system_state_signal(last_state, get_remote_app());
+ return;
}
- if (found_backtracking_point) {
- /* If asked to rollback on a state that has a snapshot, restore it */
- State* last_state = stack_.back().get();
- if (const auto* system_state = last_state->get_system_state()) {
- system_state->restore(*get_remote_app().get_remote_process_memory());
- on_restore_system_state_signal(last_state, get_remote_app());
- return;
- }
+ /* if no snapshot, we need to restore the initial state and replay the transitions */
+ get_remote_app().restore_initial_state();
+ on_restore_initial_state_signal(get_remote_app());
- /* if no snapshot, we need to restore the initial state and replay the transitions */
- get_remote_app().restore_initial_state();
- on_restore_initial_state_signal(get_remote_app());
-
- /* 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()) /* If we are arrived on the target state, don't replay the outgoing transition */
- break;
- state->get_transition()->replay(get_remote_app());
- on_transition_replay_signal(state->get_transition(), get_remote_app());
- visited_states_count_++;
- }
- } // If no backtracing point, then the stack is empty and the exploration is over
+ /* Traverse the stack from the state at position start and re-execute the transitions */
+ for (std::shared_ptr<State> const& state : backtrack) {
+ if (state == backtrack.back()) /* If we are arrived on the target state, don't replay the outgoing transition */
+ break;
+ state->get_transition()->replay(get_remote_app());
+ on_transition_replay_signal(state->get_transition(), get_remote_app());
+ visited_states_count_++;
+ }
+ stack_ = backtrack;
+ XBT_VERB(">> Backtracked to %s", get_record_trace().to_string().c_str());
}
- DFSExplorer::DFSExplorer(const std::vector<char*>& args, bool with_dpor) : Exploration(args)
-//DFSExplorer::DFSExplorer(const std::vector<char*>& args, bool with_dpor) : Exploration(args, _sg_mc_termination) // UNCOMMENT TO ACTIVATE REFORKS
-DFSExplorer::DFSExplorer(const std::vector<char*>& args, bool with_dpor) : Exploration(args, true) // This version does not use reforks as it breaks
++// DFSExplorer::DFSExplorer(const std::vector<char*>& args, bool with_dpor) : Exploration(args, _sg_mc_termination) //
++// UNCOMMENT TO ACTIVATE REFORKS
++DFSExplorer::DFSExplorer(const std::vector<char*>& args, bool with_dpor)
++ : Exploration(args, true) // This version does not use reforks as it breaks
{
if (with_dpor)
reduction_mode_ = ReductionMode::dpor;