X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=model.cc;h=23efa8f77566d10752f5d4f7e8c6c70f73aff55d;hb=d21164220a0d87ae931bf50d0e97ebf838742659;hp=feda416222de94f460291ee7f6a6ea15a21ddf22;hpb=1ad7373e04c1b94a927f4b8735bffe2c62af55f3;p=model-checker.git diff --git a/model.cc b/model.cc index feda416..23efa8f 100644 --- a/model.cc +++ b/model.cc @@ -2,6 +2,7 @@ #include #include #include +#include #include "model.h" #include "action.h" @@ -15,6 +16,7 @@ #include "datarace.h" #include "threads-model.h" #include "output.h" +#include "traceanalysis.h" #define INITIAL_THREAD_ID 0 @@ -91,6 +93,7 @@ ModelChecker::ModelChecker(struct model_params params) : thrd_last_action(new SnapVector(1)), thrd_last_fence_release(new SnapVector()), node_stack(new NodeStack()), + trace_analyses(new ModelVector()), priv(new struct model_snapshot_members()), mo_graph(new CycleGraph()) { @@ -120,6 +123,9 @@ ModelChecker::~ModelChecker() delete thrd_last_action; delete thrd_last_fence_release; delete node_stack; + for (unsigned int i = 0; i size();i++) + delete (*trace_analyses)[i]; + delete trace_analyses; delete scheduler; delete mo_graph; delete priv; @@ -145,6 +151,18 @@ static SnapVector * get_safe_ptr_vect_action(HashTable *wrv=obj_thrd_map->get(obj); + if (wrv==NULL) + return NULL; + unsigned int thread=id_to_int(tid); + if (thread < wrv->size()) + return &(*wrv)[thread]; + else + return NULL; +} + + /** * Restores user program to initial state and resets all model-checker data * structures. @@ -419,9 +437,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(); @@ -545,6 +570,7 @@ bool ModelChecker::next_execution() assert_bug("Deadlock detected"); checkDataRaces(); + run_trace_analyses(); } record_stats(); @@ -570,6 +596,15 @@ bool ModelChecker::next_execution() return true; } +/** + * @brief Run trace analyses on complete trace. */ + +void ModelChecker::run_trace_analyses() { + for(unsigned int i=0; i < trace_analyses->size(); i++) { + (*trace_analyses)[i]->analyze(action_trace); + } +} + /** * @brief Find the last fence-related backtracking conflict for a ModelAction * @@ -1492,8 +1527,6 @@ ModelAction * ModelChecker::check_current_action(ModelAction *curr) bool newly_explored = initialize_curr_action(&curr); DBG(); - if (DBG_ENABLED()) - curr->print(); wake_up_sleeping_actions(curr); @@ -1790,16 +1823,15 @@ bool ModelChecker::check_recency(ModelAction *curr, const T *rf) const } /** - * Updates the mo_graph with the constraints imposed from the current + * @brief Updates the mo_graph with the constraints imposed from the current * read. * * Basic idea is the following: Go through each other thread and find * the last action that happened before our read. Two cases: * - * (1) The action is a write => that write must either occur before + * -# The action is a write: that write must either occur before * the write we read from or be the write we read from. - * - * (2) The action is a read => the write that that action read from + * -# The action is a read: the write that that action read from * must occur before the write we read from or be the same write. * * @param curr The current action. Must be a read. @@ -3120,7 +3152,7 @@ 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); } }