X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=model.cc;h=bf956804479f3f1e82fe8f04fb273d50ce7c9cbb;hb=6357baf85edec072a52c7ea18e9fdb087765f9cb;hp=e496abd012a537b13019c292741a8dda6bc71935;hpb=d559cca6ce8264cee284dda4e0962b3bb564c955;p=model-checker.git diff --git a/model.cc b/model.cc index e496abd..bf95680 100644 --- a/model.cc +++ b/model.cc @@ -14,6 +14,8 @@ ModelChecker::ModelChecker() this->scheduler = new Scheduler(); this->current_action = NULL; + this->exploring = NULL; + this->nextThread = THREAD_ID_T_NONE; rootNode = new TreeNode(NULL); currentNode = rootNode; @@ -37,6 +39,60 @@ void ModelChecker::add_system_thread(Thread *t) this->system_thread = t; } +Thread *ModelChecker::schedule_next_thread() +{ + Thread *t; + if (nextThread == THREAD_ID_T_NONE) + return NULL; + t = thread_map[nextThread]; + if (t == NULL) + DEBUG("*** error: thread not in thread_map: id = %d\n", nextThread); + return t; +} + +/* + * get_next_replay_thread() - Choose the next thread in the replay sequence + * + * If we've reached the 'diverge' point, then we pick a thread from the + * backtracking set. + * Otherwise, we simply return the next thread in the sequence. + */ +thread_id_t ModelChecker::get_next_replay_thread() +{ + ModelAction *next; + thread_id_t tid; + + next = exploring->get_state(); + + if (next == exploring->get_diverge()) { + TreeNode *node = next->get_node(); + + /* Reached divergence point; discard our current 'exploring' */ + DEBUG("*** Discard 'Backtrack' object ***\n"); + tid = node->getNextBacktrack(); + delete exploring; + exploring = NULL; + } else { + tid = next->get_tid(); + } + DEBUG("*** ModelChecker chose next thread = %d ***\n", tid); + return tid; +} + +thread_id_t ModelChecker::advance_backtracking_state() +{ + /* Have we completed exploring the preselected path? */ + if (exploring == NULL) + return THREAD_ID_T_NONE; + + /* Else, we are trying to replay an execution */ + exploring->advance_state(); + if (exploring->get_state() == NULL) + DEBUG("*** error: reached end of backtrack trace\n"); + + return get_next_replay_thread(); +} + ModelAction *ModelChecker::get_last_conflict(ModelAction *act) { void *loc = act->get_location(); @@ -53,6 +109,7 @@ ModelAction *ModelChecker::get_last_conflict(ModelAction *act) default: break; } + /* linear search: from most recent to oldest */ action_list_t::reverse_iterator rit; for (rit = action_trace->rbegin(); rit != action_trace->rend(); rit++) { ModelAction *prev = *rit; @@ -91,9 +148,8 @@ void ModelChecker::set_backtracking(ModelAction *act) prev->print(); act->print(); - /* FIXME */ - //Backtrack *back = new Backtrack(prev, actionList); - //backtrackList->Append(back); + Backtrack *back = new Backtrack(prev, action_trace); + backtrack_list.push_back(back); } void ModelChecker::check_current_action(void) @@ -104,6 +160,7 @@ void ModelChecker::check_current_action(void) DEBUG("trying to push NULL action...\n"); return; } + nextThread = advance_backtracking_state(); next->set_node(currentNode); set_backtracking(next); currentNode = currentNode->exploreChild(next->get_tid());