X-Git-Url: http://plrg.eecs.uci.edu/git/?p=model-checker.git;a=blobdiff_plain;f=model.cc;h=7c9b4c07296bf05e57280c4eb4f33198f62dbe38;hp=906416cd90a1aadf8c13eb6cb48c17882d5002d9;hb=8311cfbfaef6d71448cb04de647ef89cba3d3b98;hpb=e023a280ce4c4986413c516008ef8f39adf127dc diff --git a/model.cc b/model.cc index 906416c..7c9b4c0 100644 --- a/model.cc +++ b/model.cc @@ -211,11 +211,14 @@ Node * ModelChecker::get_curr_node() const * adjacency of read/write portions of a RMW action, force THREAD_CREATE to be * followed by a THREAD_START, or it can enforce execution replay/backtracking. * The model-checker may have no preference regarding the next thread (i.e., - * when exploring a new execution ordering), in which case this will return - * NULL. - * @param curr The current ModelAction. This action might guide the choice of - * next thread. - * @return The next thread to run. If the model-checker has no preference, NULL. + * when exploring a new execution ordering), in which case we defer to the + * scheduler. + * + * @param curr Optional: The current ModelAction. Only used if non-NULL and it + * might guide the choice of next thread (i.e., THREAD_CREATE should be + * followed by THREAD_START, or ATOMIC_RMWR followed by ATOMIC_{RMW,RMWC}) + * @return The next chosen thread to run, if any exist. Or else if no threads + * remain to be executed, return NULL. */ Thread * ModelChecker::get_next_thread(ModelAction *curr) { @@ -229,9 +232,12 @@ Thread * ModelChecker::get_next_thread(ModelAction *curr) return curr->get_thread_operand(); } - /* Have we completed exploring the preselected path? */ + /* + * Have we completed exploring the preselected path? Then let the + * scheduler decide + */ if (diverge == NULL) - return NULL; + return scheduler->select_next_thread(); /* Else, we are trying to replay an execution */ ModelAction *next = node_stack->get_next()->get_action(); @@ -539,7 +545,7 @@ bool ModelChecker::next_execution() return true; } -ModelAction * ModelChecker::get_last_conflict(ModelAction *act) +ModelAction * ModelChecker::get_last_conflict(ModelAction *act) const { switch (act->get_type()) { case ATOMIC_FENCE: @@ -2667,6 +2673,19 @@ bool ModelChecker::is_enabled(thread_id_t tid) const return scheduler->is_enabled(tid); } +/** + * Switch from a model-checker context to a user-thread context. This is the + * complement of ModelChecker::switch_to_master and must be called from the + * model-checker context + * + * @param thread The user-thread to switch to + */ +void ModelChecker::switch_from_master(Thread *thread) +{ + scheduler->set_current_thread(thread); + Thread::swap(&system_context, thread); +} + /** * Switch from a user-context to the "master thread" context (a.k.a. system * context). This switch is made with the intention of exploring a particular @@ -2719,10 +2738,6 @@ Thread * ModelChecker::take_step(ModelAction *curr) scheduler->remove_thread(curr_thrd); Thread *next_thrd = get_next_thread(curr); - /* Only ask for the next thread from Scheduler if we haven't chosen one - * already */ - if (!next_thrd) - next_thrd = scheduler->next_thread(next_thrd); DEBUG("(%d, %d)\n", curr_thrd ? id_to_int(curr_thrd->get_id()) : -1, next_thrd ? id_to_int(next_thrd->get_id()) : -1); @@ -2755,8 +2770,7 @@ void ModelChecker::run() thread_id_t tid = int_to_id(i); Thread *thr = get_thread(tid); if (!thr->is_model_thread() && !thr->is_complete() && !thr->get_pending()) { - scheduler->next_thread(thr); - Thread::swap(&system_context, thr); + switch_from_master(thr); } } @@ -2793,5 +2807,6 @@ void ModelChecker::run() }; } while (next_execution()); + model_print("******* Model-checking complete: *******\n"); print_stats(); }