traceanalysis: rename to remove '_'
[model-checker.git] / model.cc
index 29b88c1171aa1873d34b98a19dad43c0b6c6a035..a7558c8c3a67dba4636264dd038d0204d37009c7 100644 (file)
--- a/model.cc
+++ b/model.cc
 #include "datarace.h"
 #include "threads-model.h"
 #include "output.h"
+#include "traceanalysis.h"
+#include "bugmessage.h"
 
 #define INITIAL_THREAD_ID      0
 
 ModelChecker *model;
 
-struct bug_message {
-       bug_message(const char *str) {
-               const char *fmt = "  [BUG] %s\n";
-               msg = (char *)snapshot_malloc(strlen(fmt) + strlen(str));
-               sprintf(msg, fmt, str);
-       }
-       ~bug_message() { if (msg) snapshot_free(msg); }
-
-       char *msg;
-       void print() { model_print("%s", msg); }
-
-       SNAPSHOTALLOC
-};
-
 /**
  * Structure for holding small ModelChecker members that should be snapshotted
  */
@@ -92,6 +80,7 @@ ModelChecker::ModelChecker(struct model_params params) :
        thrd_last_action(new SnapVector<ModelAction *>(1)),
        thrd_last_fence_release(new SnapVector<ModelAction *>()),
        node_stack(new NodeStack()),
+       trace_analyses(new ModelVector<TraceAnalysis *>()),
        priv(new struct model_snapshot_members()),
        mo_graph(new CycleGraph())
 {
@@ -121,6 +110,9 @@ ModelChecker::~ModelChecker()
        delete thrd_last_action;
        delete thrd_last_fence_release;
        delete node_stack;
+       for (unsigned int i = 0; i < trace_analyses->size(); i++)
+               delete (*trace_analyses)[i];
+       delete trace_analyses;
        delete scheduler;
        delete mo_graph;
        delete priv;
@@ -146,6 +138,18 @@ static SnapVector<action_list_t> * get_safe_ptr_vect_action(HashTable<void *, Sn
        return tmp;
 }
 
+action_list_t * ModelChecker::get_actions_on_obj(void * obj, thread_id_t tid) {
+       SnapVector<action_list_t> *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.
@@ -553,6 +557,7 @@ bool ModelChecker::next_execution()
                        assert_bug("Deadlock detected");
 
                checkDataRaces();
+               run_trace_analyses();
        }
 
        record_stats();
@@ -578,6 +583,12 @@ 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
  *
@@ -1796,16 +1807,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.
@@ -3090,6 +3100,12 @@ void user_main_wrapper(void *)
        user_main(model->params.argc, model->params.argv);
 }
 
+/** @return True if the execution has taken too many steps */
+bool ModelChecker::too_many_steps() const
+{
+       return params.bound != 0 && priv->used_sequence_numbers > params.bound;
+}
+
 bool ModelChecker::should_terminate_execution()
 {
        /* Infeasible -> don't take any more steps */
@@ -3100,7 +3116,7 @@ bool ModelChecker::should_terminate_execution()
                return true;
        }
 
-       if (params.bound != 0 && priv->used_sequence_numbers > params.bound)
+       if (too_many_steps())
                return true;
        return false;
 }