fix merge issue
[c11tester.git] / model.cc
index 1be15edbf2a1a63c4912684c367a338cb1f1da39..cfbc3b8606243e1cf558a1e7a2a48d0bd3c70967 100644 (file)
--- a/model.cc
+++ b/model.cc
@@ -7,7 +7,6 @@
 
 #include "model.h"
 #include "action.h"
-#include "nodestack.h"
 #include "schedule.h"
 #include "snapshot-interface.h"
 #include "common.h"
@@ -34,8 +33,7 @@ ModelChecker::ModelChecker() :
        params(),
        restart_flag(false),
        scheduler(new Scheduler()),
-       node_stack(new NodeStack()),
-       execution(new ModelExecution(this, scheduler, node_stack)),
+       execution(new ModelExecution(this, scheduler)),
        history(new ModelHistory()),
        execution_number(1),
        trace_analyses(),
@@ -47,12 +45,12 @@ ModelChecker::ModelChecker() :
        scheduler->set_current_thread(init_thread);
        execution->setParams(&params);
        param_defaults(&params);
+       initRaceDetector();
 }
 
 /** @brief Destructor */
 ModelChecker::~ModelChecker()
 {
-       delete node_stack;
        delete scheduler;
 }
 
@@ -114,7 +112,7 @@ Thread * ModelChecker::get_next_thread()
         * Have we completed exploring the preselected path? Then let the
         * scheduler decide
         */
-       return scheduler->select_next_thread(node_stack->get_head());
+       return scheduler->select_next_thread();
 }
 
 /**
@@ -141,6 +139,28 @@ bool ModelChecker::assert_bug(const char *msg, ...)
        return execution->assert_bug(str);
 }
 
+/**
+ * @brief Assert a data race in the executing program.
+ *
+ * Different from assert_bug, the program will not be aborted immediately
+ * upon calling this function, unless the number of data races exceeds
+ * a threshold.
+ *
+ * @param msg Descriptive message for the bug (do not include newline char)
+ * @return True if bug is immediately-feasible
+ */
+bool ModelChecker::assert_race(const char *msg, ...)
+{
+       char str[800];
+
+       va_list ap;
+       va_start(ap, msg);
+       vsnprintf(str, sizeof(str), msg, ap);
+       va_end(ap);
+
+       return execution->assert_race(str);
+}
+
 /**
  * @brief Assert a bug in the executing program, asserted by a user thread
  * @see ModelChecker::assert_bug
@@ -162,7 +182,7 @@ void ModelChecker::print_bugs() const
                                                        bugs->size(),
                                                        bugs->size() > 1 ? "s" : "");
        for (unsigned int i = 0;i < bugs->size();i++)
-               (*bugs)[i]->print();
+               (*bugs)[i] -> print();
 }
 
 /**
@@ -173,15 +193,15 @@ void ModelChecker::print_bugs() const
  */
 void ModelChecker::record_stats()
 {
-       stats.num_total++;
+       stats.num_total ++;
        if (!execution->isfeasibleprefix())
-               stats.num_infeasible++;
+               stats.num_infeasible ++;
        else if (execution->have_bug_reports())
-               stats.num_buggy_executions++;
+               stats.num_buggy_executions ++;
        else if (execution->is_complete_execution())
-               stats.num_complete++;
+               stats.num_complete ++;
        else {
-               stats.num_redundant++;
+               stats.num_redundant ++;
 
                /**
                 * @todo We can violate this ASSERT() when fairness/sleep sets
@@ -246,7 +266,6 @@ bool ModelChecker::next_execution()
                if (execution->is_deadlocked())
                        assert_bug("Deadlock detected");
 
-               checkDataRaces();
                run_trace_analyses();
        }
 
@@ -262,15 +281,15 @@ bool ModelChecker::next_execution()
                return true;
        }
 // test code
-       execution_number++;
+       execution_number ++;
        reset_to_initial_state();
        return false;
 }
 
 /** @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(execution->get_action_trace());
+       for (unsigned int i = 0;i < trace_analyses.size();i ++)
+               trace_analyses[i] -> analyze(execution->get_action_trace());
 }
 
 /**
@@ -319,6 +338,16 @@ void ModelChecker::switch_from_master(Thread *thread)
  */
 uint64_t ModelChecker::switch_to_master(ModelAction *act)
 {
+       if (forklock) {
+               static bool fork_message_printed = false;
+
+               if (!fork_message_printed) {
+                       model_print("Fork handler trying to call into model checker...\n");
+                       fork_message_printed = true;
+               }
+               delete act;
+               return 0;
+       }
        DBG();
        Thread *old = thread_current();
        scheduler->set_current_thread(NULL);
@@ -350,7 +379,7 @@ bool ModelChecker::should_terminate_execution()
        /* Infeasible -> don't take any more steps */
        if (execution->is_infeasible())
                return true;
-       else if (execution->isfeasibleprefix() && execution->have_bug_reports()) {
+       else if (execution->isfeasibleprefix() && execution->have_fatal_bug_reports()) {
                execution->set_assert();
                return true;
        }