run tabbing pass
[c11tester.git] / execution.cc
index e253ab0f2611e65898173fc504177a040ea394dd..99f86195713523cb02791fb8ae75fcc309a1b0ec 100644 (file)
@@ -28,7 +28,6 @@ struct model_snapshot_members {
                used_sequence_numbers(0),
                bugs(),
                bad_synchronization(false),
-               bad_sc_read(false),
                asserted(false)
        { }
 
@@ -43,16 +42,13 @@ struct model_snapshot_members {
        SnapVector<bug_message *> bugs;
        /** @brief Incorrectly-ordered synchronization was made */
        bool bad_synchronization;
-       bool bad_sc_read;
        bool asserted;
 
        SNAPSHOTALLOC
 };
 
 /** @brief Constructor */
-ModelExecution::ModelExecution(ModelChecker *m,
-                                                                                                                        Scheduler *scheduler,
-                                                                                                                        NodeStack *node_stack) :
+ModelExecution::ModelExecution(ModelChecker *m, Scheduler *scheduler, NodeStack *node_stack) :
        model(m),
        params(NULL),
        scheduler(scheduler),
@@ -68,7 +64,7 @@ ModelExecution::ModelExecution(ModelChecker *m,
        thrd_last_fence_release(),
        node_stack(node_stack),
        priv(new struct model_snapshot_members ()),
-                        mo_graph(new CycleGraph()),
+       mo_graph(new CycleGraph()),
        fuzzer(new Fuzzer())
 {
        /* Initialize a model-checker thread, for special ModelActions */
@@ -190,13 +186,6 @@ void ModelExecution::set_bad_synchronization()
        priv->bad_synchronization = true;
 }
 
-/** @brief Alert the model-checker that an incorrectly-ordered
- * synchronization was made */
-void ModelExecution::set_bad_sc_read()
-{
-       priv->bad_sc_read = true;
-}
-
 bool ModelExecution::assert_bug(const char *msg)
 {
        priv->bugs.push_back(new bug_message(msg));
@@ -283,8 +272,9 @@ bool ModelExecution::is_complete_execution() const
  * @param rf_set is the set of model actions we can possibly read from
  * @return True if processing this read updates the mo_graph.
  */
-bool ModelExecution::process_read(ModelAction *curr, ModelVector<ModelAction *> * rf_set)
+void ModelExecution::process_read(ModelAction *curr, SnapVector<ModelAction *> * rf_set)
 {
+       SnapVector<const ModelAction *> * priorset = new SnapVector<const ModelAction *>();
        while(true) {
 
                int index = fuzzer->selectWrite(curr, rf_set);
@@ -293,15 +283,16 @@ bool ModelExecution::process_read(ModelAction *curr, ModelVector<ModelAction *>
 
                ASSERT(rf);
 
-               mo_graph->startChanges();
-               bool updated = r_modification_order(curr, rf);
-               if (!is_infeasible()) {
+               if (r_modification_order(curr, rf, priorset)) {
+                       for(unsigned int i=0;i<priorset->size();i++) {
+                               mo_graph->addEdge((*priorset)[i], rf);
+                       }
                        read_from(curr, rf);
-                       mo_graph->commitChanges();
                        get_thread(curr)->set_return_value(curr->get_return_value());
-                       return updated;
+                       delete priorset;
+                       return;
                }
-               mo_graph->rollbackChanges();
+               priorset->clear();
                (*rf_set)[index] = rf_set->back();
                rf_set->pop_back();
        }
@@ -399,15 +390,13 @@ bool ModelExecution::process_mutex(ModelAction *curr)
  * @param curr The ModelAction to process
  * @return True if the mo_graph was updated or promises were resolved
  */
-bool ModelExecution::process_write(ModelAction *curr)
+void ModelExecution::process_write(ModelAction *curr)
 {
 
-       bool updated_mod_order = w_modification_order(curr);
+       w_modification_order(curr);
 
-       mo_graph->commitChanges();
 
        get_thread(curr)->set_return_value(VALUE_NONE);
-       return updated_mod_order;
 }
 
 /**
@@ -693,10 +682,10 @@ ModelAction * ModelExecution::check_current_action(ModelAction *curr)
        wake_up_sleeping_actions(curr);
 
        /* Add the action to lists before any other model-checking tasks */
-       if (!second_part_of_rmw)
+       if (!second_part_of_rmw && curr->get_type() != NOOP)
                add_action_to_lists(curr);
 
-       ModelVector<ModelAction *> * rf_set = NULL;
+       SnapVector<ModelAction *> * rf_set = NULL;
        /* Build may_read_from set for newly-created actions */
        if (newly_explored && curr->is_read())
                rf_set = build_may_read_from(curr);
@@ -741,12 +730,8 @@ void ModelExecution::print_infeasibility(const char *prefix) const
 {
        char buf[100];
        char *ptr = buf;
-       if (mo_graph->checkForCycles())
-               ptr += sprintf(ptr, "[mo cycle]");
        if (priv->bad_synchronization)
                ptr += sprintf(ptr, "[bad sw ordering]");
-       if (priv->bad_sc_read)
-               ptr += sprintf(ptr, "[bad sc read]");
        if (ptr != buf)
                model_print("%s: %s", prefix ? prefix : "Infeasible", buf);
 }
@@ -759,9 +744,7 @@ void ModelExecution::print_infeasibility(const char *prefix) const
  */
 bool ModelExecution::is_infeasible() const
 {
-       return mo_graph->checkForCycles() ||
-                                priv->bad_synchronization ||
-                                priv->bad_sc_read;
+       return priv->bad_synchronization;
 }
 
 /** Close out a RMWR by converting previous RMWR into a RMW or READ. */
@@ -770,7 +753,6 @@ ModelAction * ModelExecution::process_rmw(ModelAction *act) {
        lastread->process_rmw(act);
        if (act->is_rmw()) {
                mo_graph->addRMWEdge(lastread->get_reads_from(), lastread);
-               mo_graph->commitChanges();
        }
        return lastread;
 }
@@ -791,12 +773,11 @@ ModelAction * ModelExecution::process_rmw(ModelAction *act) {
  * @param rf The ModelAction or Promise that curr reads from. Must be a write.
  * @return True if modification order edges were added; false otherwise
  */
-template <typename rf_type>
-bool ModelExecution::r_modification_order(ModelAction *curr, const rf_type *rf)
+
+bool ModelExecution::r_modification_order(ModelAction *curr, const ModelAction *rf, SnapVector<const ModelAction *> * priorset)
 {
        SnapVector<action_list_t> *thrd_lists = obj_thrd_map.get(curr->get_location());
        unsigned int i;
-       bool added = false;
        ASSERT(curr->is_read());
 
        /* Last SC fence in the current thread */
@@ -838,19 +819,25 @@ bool ModelExecution::r_modification_order(ModelAction *curr, const rf_type *rf)
                                /* C++, Section 29.3 statement 5 */
                                if (curr->is_seqcst() && last_sc_fence_thread_local &&
                                                *act < *last_sc_fence_thread_local) {
-                                       added = mo_graph->addEdge(act, rf) || added;
+                                       if (mo_graph->checkReachable(rf, act))
+                                               return false;
+                                       priorset->push_back(act);
                                        break;
                                }
                                /* C++, Section 29.3 statement 4 */
                                else if (act->is_seqcst() && last_sc_fence_local &&
                                                                 *act < *last_sc_fence_local) {
-                                       added = mo_graph->addEdge(act, rf) || added;
+                                       if (mo_graph->checkReachable(rf, act))
+                                               return false;
+                                       priorset->push_back(act);
                                        break;
                                }
                                /* C++, Section 29.3 statement 6 */
                                else if (last_sc_fence_thread_before &&
                                                                 *act < *last_sc_fence_thread_before) {
-                                       added = mo_graph->addEdge(act, rf) || added;
+                                       if (mo_graph->checkReachable(rf, act))
+                                               return false;
+                                       priorset->push_back(act);
                                        break;
                                }
                        }
@@ -861,18 +848,22 @@ bool ModelExecution::r_modification_order(ModelAction *curr, const rf_type *rf)
                         */
                        if (act->happens_before(curr)) {
                                if (act->is_write()) {
-                                       added = mo_graph->addEdge(act, rf) || added;
+                                       if (mo_graph->checkReachable(rf, act))
+                                               return false;
+                                       priorset->push_back(act);
                                } else {
                                        const ModelAction *prevrf = act->get_reads_from();
-                                       if (!prevrf->equals(rf))
-                                               added = mo_graph->addEdge(prevrf, rf) || added;
+                                       if (!prevrf->equals(rf)) {
+                                               if (mo_graph->checkReachable(rf, prevrf))
+                                                       return false;
+                                               priorset->push_back(prevrf);
+                                       }
                                }
                                break;
                        }
                }
        }
-
-       return added;
+       return true;
 }
 
 /**
@@ -899,11 +890,10 @@ bool ModelExecution::r_modification_order(ModelAction *curr, const rf_type *rf)
  * value. If NULL, then don't record any future values.
  * @return True if modification order edges were added; false otherwise
  */
-bool ModelExecution::w_modification_order(ModelAction *curr)
+void ModelExecution::w_modification_order(ModelAction *curr)
 {
        SnapVector<action_list_t> *thrd_lists = obj_thrd_map.get(curr->get_location());
        unsigned int i;
-       bool added = false;
        ASSERT(curr->is_write());
 
        if (curr->is_seqcst()) {
@@ -911,7 +901,7 @@ bool ModelExecution::w_modification_order(ModelAction *curr)
                         so we are initialized. */
                ModelAction *last_seq_cst = get_last_seq_cst_write(curr);
                if (last_seq_cst != NULL) {
-                       added = mo_graph->addEdge(last_seq_cst, curr) || added;
+                       mo_graph->addEdge(last_seq_cst, curr);
                }
        }
 
@@ -928,6 +918,7 @@ bool ModelExecution::w_modification_order(ModelAction *curr)
                /* Iterate over actions in thread, starting from most recent */
                action_list_t *list = &(*thrd_lists)[i];
                action_list_t::reverse_iterator rit;
+               bool force_edge = false;
                for (rit = list->rbegin();rit != list->rend();rit++) {
                        ModelAction *act = *rit;
                        if (act == curr) {
@@ -942,6 +933,7 @@ bool ModelExecution::w_modification_order(ModelAction *curr)
                                 * 3) If normal write, we need to look at earlier actions, so
                                 * continue processing list.
                                 */
+                               force_edge = true;
                                if (curr->is_rmw()) {
                                        if (curr->get_reads_from() != NULL)
                                                break;
@@ -954,7 +946,7 @@ bool ModelExecution::w_modification_order(ModelAction *curr)
                        /* C++, Section 29.3 statement 7 */
                        if (last_sc_fence_thread_before && act->is_write() &&
                                        *act < *last_sc_fence_thread_before) {
-                               added = mo_graph->addEdge(act, curr) || added;
+                               mo_graph->addEdge(act, curr, force_edge);
                                break;
                        }
 
@@ -970,10 +962,10 @@ bool ModelExecution::w_modification_order(ModelAction *curr)
                                 *   readfrom(act) --mo--> act
                                 */
                                if (act->is_write())
-                                       added = mo_graph->addEdge(act, curr) || added;
+                                       mo_graph->addEdge(act, curr, force_edge);
                                else if (act->is_read()) {
                                        //if previous read accessed a null, just keep going
-                                       added = mo_graph->addEdge(act->get_reads_from(), curr) || added;
+                                       mo_graph->addEdge(act->get_reads_from(), curr, force_edge);
                                }
                                break;
                        } else if (act->is_read() && !act->could_synchronize_with(curr) &&
@@ -994,8 +986,6 @@ bool ModelExecution::w_modification_order(ModelAction *curr)
                        }
                }
        }
-
-       return added;
 }
 
 /**
@@ -1055,12 +1045,8 @@ bool ModelExecution::mo_may_allow(const ModelAction *writer, const ModelAction *
  * @return true, if the ModelExecution is certain that release_heads is complete;
  * false otherwise
  */
-bool ModelExecution::release_seq_heads(const ModelAction *rf,
-                                                                                                                                                        rel_heads_list_t *release_heads) const
+bool ModelExecution::release_seq_heads(const ModelAction *rf, rel_heads_list_t *release_heads) const
 {
-       /* Only check for release sequences if there are no cycles */
-       if (mo_graph->checkForCycles())
-               return false;
 
        for ( ;rf != NULL;rf = rf->get_reads_from()) {
                ASSERT(rf->is_write());
@@ -1327,7 +1313,7 @@ bool valequals(uint64_t val1, uint64_t val2, int size) {
  * @param curr is the current ModelAction that we are exploring; it must be a
  * 'read' operation.
  */
-ModelVector<ModelAction *> *  ModelExecution::build_may_read_from(ModelAction *curr)
+SnapVector<ModelAction *> *  ModelExecution::build_may_read_from(ModelAction *curr)
 {
        SnapVector<action_list_t> *thrd_lists = obj_thrd_map.get(curr->get_location());
        unsigned int i;
@@ -1338,7 +1324,7 @@ ModelVector<ModelAction *> *  ModelExecution::build_may_read_from(ModelAction *c
        if (curr->is_seqcst())
                last_sc_write = get_last_seq_cst_write(curr);
 
-       ModelVector<ModelAction *> * rf_set = new ModelVector<ModelAction *>();
+       SnapVector<ModelAction *> * rf_set = new SnapVector<ModelAction *>();
 
        /* Iterate over all threads */
        for (i = 0;i < thrd_lists->size();i++) {
@@ -1374,11 +1360,7 @@ ModelVector<ModelAction *> *  ModelExecution::build_may_read_from(ModelAction *c
 
                        if (allow_read) {
                                /* Only add feasible reads */
-                               mo_graph->startChanges();
-                               r_modification_order(curr, act);
-                               if (!is_infeasible())
-                                       rf_set->push_back(act);
-                               mo_graph->rollbackChanges();
+                               rf_set->push_back(act);
                        }
 
                        /* Include at most one act per-thread that "happens before" curr */