From: Brian Norris Date: Wed, 3 Apr 2013 16:44:07 +0000 (-0700) Subject: model: pull thread control logic out of take_step(), check_current...() X-Git-Url: http://plrg.eecs.uci.edu/git/?p=c11tester.git;a=commitdiff_plain;h=2b493dff916099b11e559243b117ffd5eabe8f3b model: pull thread control logic out of take_step(), check_current...() Much of the scheduling and main control loop should be handled closer to the top-level run() method. This is a start toward putting these decisions at the appropriate level, making things more clear. Of course, it's not complete. --- diff --git a/model.cc b/model.cc index f385e560..37417d64 100644 --- a/model.cc +++ b/model.cc @@ -1489,15 +1489,6 @@ ModelAction * ModelChecker::check_current_action(ModelAction *curr) { ASSERT(curr); bool second_part_of_rmw = curr->is_rmwc() || curr->is_rmw(); - - if (!check_action_enabled(curr)) { - /* Make the execution look like we chose to run this action - * much later, when a lock/join can succeed */ - get_thread(curr)->set_pending(curr); - scheduler->sleep(get_thread(curr)); - return NULL; - } - bool newly_explored = initialize_curr_action(&curr); DBG(); @@ -3077,32 +3068,23 @@ Thread * ModelChecker::take_step(ModelAction *curr) Thread *curr_thrd = get_thread(curr); ASSERT(curr_thrd->get_state() == THREAD_READY); - curr = check_current_action(curr); - - /* Infeasible -> don't take any more steps */ - if (is_infeasible()) - return NULL; - else if (isfeasibleprefix() && have_bug_reports()) { - set_assert(); - return NULL; + if (!check_action_enabled(curr)) { + /* Make the execution look like we chose to run this action + * much later, when a lock/join can succeed */ + get_thread(curr)->set_pending(curr); + scheduler->sleep(curr_thrd); + curr = NULL; + } else { + curr = check_current_action(curr); + ASSERT(curr); } - if (params.bound != 0 && priv->used_sequence_numbers > params.bound) - return NULL; - if (curr_thrd->is_blocked() || curr_thrd->is_complete()) scheduler->remove_thread(curr_thrd); - Thread *next_thrd = NULL; if (curr) - next_thrd = action_select_next_thread(curr); - if (!next_thrd) - next_thrd = get_next_thread(); - - DEBUG("(%d, %d)\n", curr_thrd ? id_to_int(curr_thrd->get_id()) : -1, - next_thrd ? id_to_int(next_thrd->get_id()) : -1); - - return next_thrd; + return action_select_next_thread(curr); + return NULL; } /** Wrapper to run the user's main function, with appropriate arguments */ @@ -3111,6 +3093,21 @@ void user_main_wrapper(void *) user_main(model->params.argc, model->params.argv); } +bool ModelChecker::should_terminate_execution() +{ + /* Infeasible -> don't take any more steps */ + if (is_infeasible()) + return true; + else if (isfeasibleprefix() && have_bug_reports()) { + set_assert(); + return true; + } + + if (params.bound != 0 && priv->used_sequence_numbers > params.bound) + return true; + return false; +} + /** @brief Run ModelChecker for the user program */ void ModelChecker::run() { @@ -3141,11 +3138,16 @@ void ModelChecker::run() if (has_asserted()) break; + if (!t) + t = get_next_thread(); + if (!t || t->is_model_thread()) + break; + /* Consume the next action for a Thread */ ModelAction *curr = t->get_pending(); t->set_pending(NULL); t = take_step(curr); - } while (t && !t->is_model_thread()); + } while (!should_terminate_execution()); /* * Launch end-of-execution release sequence fixups only when diff --git a/model.h b/model.h index 12ec06c0..73272809 100644 --- a/model.h +++ b/model.h @@ -171,6 +171,7 @@ private: bool check_action_enabled(ModelAction *curr); Thread * take_step(ModelAction *curr); + bool should_terminate_execution(); template bool check_recency(ModelAction *curr, const T *rf) const;