X-Git-Url: http://plrg.eecs.uci.edu/git/?p=c11tester.git;a=blobdiff_plain;f=model.cc;h=569dd472bab4aeb908e0e1df60d50540cf607d87;hp=37417d644a14d40c3f5f6fa51dc1e883ca3d437c;hb=1ca9b05f504ed968eb922b12cddb0a8217d6fc50;hpb=2b493dff916099b11e559243b117ffd5eabe8f3b diff --git a/model.cc b/model.cc index 37417d64..569dd472 100644 --- a/model.cc +++ b/model.cc @@ -2,6 +2,7 @@ #include #include #include +#include #include "model.h" #include "action.h" @@ -419,9 +420,16 @@ bool ModelChecker::is_complete_execution() const * @param msg Descriptive message for the bug (do not include newline char) * @return True if bug is immediately-feasible */ -bool ModelChecker::assert_bug(const char *msg) +bool ModelChecker::assert_bug(const char *msg, ...) { - priv->bugs.push_back(new bug_message(msg)); + char str[800]; + + va_list ap; + va_start(ap, msg); + vsnprintf(str, sizeof(str), msg, ap); + va_end(ap); + + priv->bugs.push_back(new bug_message(str)); if (isfeasibleprefix()) { set_assert(); @@ -3068,23 +3076,14 @@ Thread * ModelChecker::take_step(ModelAction *curr) Thread *curr_thrd = get_thread(curr); ASSERT(curr_thrd->get_state() == THREAD_READY); - 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); - } + ASSERT(check_action_enabled(curr)); /* May have side effects? */ + curr = check_current_action(curr); + ASSERT(curr); if (curr_thrd->is_blocked() || curr_thrd->is_complete()) scheduler->remove_thread(curr_thrd); - if (curr) - return action_select_next_thread(curr); - return NULL; + return action_select_next_thread(curr); } /** Wrapper to run the user's main function, with appropriate arguments */ @@ -3129,7 +3128,16 @@ void ModelChecker::run() if (!thr->is_model_thread() && !thr->is_complete() && !thr->get_pending()) { switch_from_master(thr); if (thr->is_waiting_on(thr)) - assert_bug("Deadlock detected"); + assert_bug("Deadlock detected (thread %u)", i); + } + } + + /* Don't schedule threads which should be disabled */ + for (unsigned int i = 0; i < get_num_threads(); i++) { + Thread *th = get_thread(int_to_id(i)); + ModelAction *act = th->get_pending(); + if (act && is_enabled(th) && !check_action_enabled(act)) { + scheduler->sleep(th); } }