tests: add some normal loads/stores to test data races
[model-checker.git] / model.cc
index c1818ad5bfb8fb48c8b8e9221212119b2ca125ff..08ea3294b3b963b63ec8d63f3d1a88a39dc7b728 100644 (file)
--- a/model.cc
+++ b/model.cc
@@ -602,6 +602,10 @@ void ModelChecker::process_relseq_fixup(ModelAction *curr, work_queue_t *work_qu
                mo_graph->addEdge(release, write);
                mo_graph->addEdge(write, rf);
        }
+
+       /* See if we have realized a data race */
+       if (checkDataRaces())
+               set_assert();
 }
 
 /**
@@ -1334,6 +1338,8 @@ bool ModelChecker::release_seq_heads(const ModelAction *rf,
                                th->is_complete())
                        future_ordered = true;
 
+               ASSERT(!th->is_model_thread() || future_ordered);
+
                for (rit = list->rbegin(); rit != list->rend(); rit++) {
                        const ModelAction *act = *rit;
                        /* Reach synchronization -> this thread is complete */
@@ -1971,6 +1977,25 @@ bool ModelChecker::take_step() {
        DEBUG("(%d, %d)\n", curr ? id_to_int(curr->get_id()) : -1,
                        next ? id_to_int(next->get_id()) : -1);
 
+       /*
+        * Launch end-of-execution release sequence fixups only when there are:
+        *
+        * (1) no more user threads to run (or when execution replay chooses
+        *     the 'model_thread')
+        * (2) pending release sequences
+        * (3) pending assertions (i.e., data races)
+        */
+       if (!pending_rel_seqs->empty() && (!next || next->is_model_thread()) &&
+                       !unrealizedraces.empty()) {
+               printf("*** WARNING: release sequence fixup action (%zu pending release seuqences) ***\n",
+                               pending_rel_seqs->size());
+               ModelAction *fixup = new ModelAction(MODEL_FIXUP_RELSEQ,
+                               std::memory_order_seq_cst, NULL, VALUE_NONE,
+                               model_thread);
+               set_current_action(fixup);
+               return true;
+       }
+
        /* next == NULL -> don't take any more steps */
        if (!next)
                return false;