* And if we kept it and the actor is enabled in this state, mark the actor as already done, so that
* it is not explored*/
for (auto& [aid, transition] : parent_state_->get_sleep_set()) {
-
if (not parent_state_->get_transition()->depends(&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<<",
aid_t State::next_transition() const
{
- XBT_DEBUG("Search for an actor to run. %zu actors to consider", guide->actors_to_run_.size());
- for (auto const& [aid, actor] : guide->actors_to_run_) {
+ XBT_DEBUG("Search for an actor to run. %zu actors to consider", guide_->actors_to_run_.size());
+ for (auto const& [aid, actor] : guide_->actors_to_run_) {
/* Only consider actors (1) marked as interleaving by the checker and (2) currently enabled in the application */
if (not actor.is_todo() || not actor.is_enabled() || actor.is_done()) {
-
if (not actor.is_todo())
XBT_DEBUG("Can't run actor %ld because it is not todo", aid);
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 (min_aid == -1) {
+ stack_ = std::list<std::shared_ptr<State>>();
+ return;
+ }
- 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 (backtrack.back()->count_todo() <= 1)
+ opened_states.pop_back();
- } 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 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());
+ on_restore_system_state_signal(last_state, get_remote_app());
+ stack_ = backtrack;
+ 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());
-
- /* 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
+ /* 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::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_DEBUG(">> Backtracked to %s", get_record_trace().to_string().c_str());
}
- // 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, bool need_memory_info)
+ : Exploration(args, need_memory_info || _sg_mc_termination)
{
if (with_dpor)
reduction_mode_ = ReductionMode::dpor;