partial edits
authorbdemsky <bdemsky@uci.edu>
Wed, 12 Jun 2019 22:30:30 +0000 (15:30 -0700)
committerbdemsky <bdemsky@uci.edu>
Wed, 12 Jun 2019 22:30:30 +0000 (15:30 -0700)
clockvector.cc
clockvector.h
cyclegraph.cc
cyclegraph.h
execution.cc
execution.h
fuzzer.cc
fuzzer.h

index 54e8c4a1a9b5188eb0b56875015f13950712eabd..c86995bc9bbb555cf9e2381d1b7df91036330a46 100644 (file)
@@ -16,7 +16,7 @@
  * same thread or the parent that created this thread)
  * @param act is an action with which to update the ClockVector
  */
  * same thread or the parent that created this thread)
  * @param act is an action with which to update the ClockVector
  */
-ClockVector::ClockVector(ClockVector *parent, ModelAction *act)
+ClockVector::ClockVector(ClockVector *parent, const ModelAction *act)
 {
        ASSERT(act);
        num_threads = int_to_id(act->get_tid()) + 1;
 {
        ASSERT(act);
        num_threads = int_to_id(act->get_tid()) + 1;
index 430dc1771bc9c03f09bfbb01f2e16e46c4744e57..962e9ec4844995c811638030d5a7c11a983ea36e 100644 (file)
@@ -11,7 +11,7 @@
 
 class ClockVector {
 public:
 
 class ClockVector {
 public:
-       ClockVector(ClockVector *parent = NULL, ModelAction *act = NULL);
+       ClockVector(ClockVector *parent = NULL, const ModelAction *act = NULL);
        ~ClockVector();
        bool merge(const ClockVector *cv);
        bool synchronized_since(const ModelAction *act) const;
        ~ClockVector();
        bool merge(const ClockVector *cv);
        bool synchronized_since(const ModelAction *act) const;
index 36f64a43a16885217d1b4d75cfa5e281e43d3d19..a3e86cf00b5f78ce098b5161d10c0dc90bc88390 100644 (file)
@@ -2,13 +2,11 @@
 #include "action.h"
 #include "common.h"
 #include "threads-model.h"
 #include "action.h"
 #include "common.h"
 #include "threads-model.h"
+#include "clockvector.h"
 
 /** Initializes a CycleGraph object. */
 CycleGraph::CycleGraph() :
 
 /** Initializes a CycleGraph object. */
 CycleGraph::CycleGraph() :
-       discovered(new HashTable<const CycleNode *, const CycleNode *, uintptr_t, 4, model_malloc, model_calloc, model_free>(16)),
-       queue(new ModelVector<const CycleNode *>()),
-       hasCycles(false),
-       oldCycles(false)
+       queue(new SnapVector<const CycleNode *>())
 {
 }
 
 {
 }
 
@@ -16,7 +14,6 @@ CycleGraph::CycleGraph() :
 CycleGraph::~CycleGraph()
 {
        delete queue;
 CycleGraph::~CycleGraph()
 {
        delete queue;
-       delete discovered;
 }
 
 /**
 }
 
 /**
@@ -62,51 +59,55 @@ CycleNode * CycleGraph::getNode(const ModelAction *action)
  * @param tonode The edge points to this CycleNode
  * @return True, if new edge(s) are added; otherwise false
  */
  * @param tonode The edge points to this CycleNode
  * @return True, if new edge(s) are added; otherwise false
  */
-bool CycleGraph::addNodeEdge(CycleNode *fromnode, CycleNode *tonode)
+void CycleGraph::addNodeEdge(CycleNode *fromnode, CycleNode *tonode)
 {
 {
-       if (fromnode->addEdge(tonode)) {
-               rollbackvector.push_back(fromnode);
-               if (!hasCycles)
-                       hasCycles = checkReachable(tonode, fromnode);
-       } else
-               return false;/* No new edge */
+       //quick check whether edge is redundant
+       if (checkReachable(fromnode, tonode))
+               return;
+
+       CycleNode *edgeSrcNode = fromnode;
 
        /*
 
        /*
-        * If the fromnode has a rmwnode that is not the tonode, we should
-        * follow its RMW chain to add an edge at the end, unless we encounter
-        * tonode along the way
+        * If the fromnode has a rmwnode, we should
+        * follow its RMW chain to add an edge at the end.
         */
        CycleNode *rmwnode = fromnode->getRMW();
        if (rmwnode) {
         */
        CycleNode *rmwnode = fromnode->getRMW();
        if (rmwnode) {
-               while (rmwnode != tonode && rmwnode->getRMW())
+               while (rmwnode->getRMW())
                        rmwnode = rmwnode->getRMW();
                        rmwnode = rmwnode->getRMW();
+               edgeSrcNode = rmwnode;
+       }
 
 
-               if (rmwnode != tonode) {
-                       if (rmwnode->addEdge(tonode)) {
-                               if (!hasCycles)
-                                       hasCycles = checkReachable(tonode, rmwnode);
-
-                               rollbackvector.push_back(rmwnode);
+       edgeSrcNode->addEdge(tonode);   //Add edge to edgeSrcNode
+
+       /* Propagate clock vector changes */
+       if (tonode->cv->merge(edgeSrcNode->cv)) {
+               queue->push_back(edgeSrcNode);
+               while(!queue->empty()) {
+                       const CycleNode *node = queue->back();
+                       unsigned int numedges = node->getNumEdges();
+                       for(unsigned int i = 0;i < numedges;i++) {
+                               CycleNode * enode = node->getEdge(i);
+                               if (enode->cv->merge(node->cv))
+                                       queue->push_back(enode);
                        }
                }
        }
                        }
                }
        }
-       return true;
 }
 
 /**
  * @brief Add an edge between a write and the RMW which reads from it
  *
  * Handles special case of a RMW action, where the ModelAction rmw reads from
 }
 
 /**
  * @brief Add an edge between a write and the RMW which reads from it
  *
  * Handles special case of a RMW action, where the ModelAction rmw reads from
- * the ModelAction/Promise from. The key differences are:
+ * the ModelAction from. The key differences are:
  *  -# No write can occur in between the @a rmw and @a from actions.
  *  -# Only one RMW action can read from a given write.
  *
  *  -# No write can occur in between the @a rmw and @a from actions.
  *  -# Only one RMW action can read from a given write.
  *
- * @param from The edge comes from this ModelAction/Promise
+ * @param from The edge comes from this ModelAction
  * @param rmw The edge points to this ModelAction; this action must read from
  * @param rmw The edge points to this ModelAction; this action must read from
- * the ModelAction/Promise from
+ * the ModelAction from
  */
  */
-template <typename T>
-void CycleGraph::addRMWEdge(const T *from, const ModelAction *rmw)
+void CycleGraph::addRMWEdge(const ModelAction *from, const ModelAction *rmw)
 {
        ASSERT(from);
        ASSERT(rmw);
 {
        ASSERT(from);
        ASSERT(rmw);
@@ -117,11 +118,7 @@ void CycleGraph::addRMWEdge(const T *from, const ModelAction *rmw)
        /* We assume that this RMW has no RMW reading from it yet */
        ASSERT(!rmwnode->getRMW());
 
        /* We assume that this RMW has no RMW reading from it yet */
        ASSERT(!rmwnode->getRMW());
 
-       /* Two RMW actions cannot read from the same write. */
-       if (fromnode->setRMW(rmwnode))
-               hasCycles = true;
-       else
-               rmwrollbackvector.push_back(fromnode);
+       fromnode->setRMW(rmwnode);
 
        /* Transfer all outgoing edges from the from node to the rmw node */
        /* This process should not add a cycle because either:
 
        /* Transfer all outgoing edges from the from node to the rmw node */
        /* This process should not add a cycle because either:
@@ -133,15 +130,12 @@ void CycleGraph::addRMWEdge(const T *from, const ModelAction *rmw)
        for (unsigned int i = 0;i < fromnode->getNumEdges();i++) {
                CycleNode *tonode = fromnode->getEdge(i);
                if (tonode != rmwnode) {
        for (unsigned int i = 0;i < fromnode->getNumEdges();i++) {
                CycleNode *tonode = fromnode->getEdge(i);
                if (tonode != rmwnode) {
-                       if (rmwnode->addEdge(tonode))
-                               rollbackvector.push_back(rmwnode);
+                       rmwnode->addEdge(tonode);
                }
        }
 
        addNodeEdge(fromnode, rmwnode);
 }
                }
        }
 
        addNodeEdge(fromnode, rmwnode);
 }
-/* Instantiate two forms of CycleGraph::addRMWEdge */
-template void CycleGraph::addRMWEdge(const ModelAction *from, const ModelAction *rmw);
 
 /**
  * @brief Adds an edge between objects
 
 /**
  * @brief Adds an edge between objects
@@ -156,8 +150,8 @@ template void CycleGraph::addRMWEdge(const ModelAction *from, const ModelAction
  * @param from The edge comes from this object, of type U
  * @return True, if new edge(s) are added; otherwise false
  */
  * @param from The edge comes from this object, of type U
  * @return True, if new edge(s) are added; otherwise false
  */
-template <typename T, typename U>
-bool CycleGraph::addEdge(const T *from, const U *to)
+
+void CycleGraph::addEdge(const ModelAction *from, const ModelAction *to)
 {
        ASSERT(from);
        ASSERT(to);
 {
        ASSERT(from);
        ASSERT(to);
@@ -165,10 +159,8 @@ bool CycleGraph::addEdge(const T *from, const U *to)
        CycleNode *fromnode = getNode(from);
        CycleNode *tonode = getNode(to);
 
        CycleNode *fromnode = getNode(from);
        CycleNode *tonode = getNode(to);
 
-       return addNodeEdge(fromnode, tonode);
+       addNodeEdge(fromnode, tonode);
 }
 }
-/* Instantiate four forms of CycleGraph::addEdge */
-template bool CycleGraph::addEdge(const ModelAction *from, const ModelAction *to);
 
 #if SUPPORT_MOD_ORDER_DUMP
 
 
 #if SUPPORT_MOD_ORDER_DUMP
 
@@ -196,16 +188,13 @@ void CycleGraph::dot_print_node(FILE *file, const ModelAction *act)
        print_node(file, getNode(act), 1);
 }
 
        print_node(file, getNode(act), 1);
 }
 
-template <typename T, typename U>
-void CycleGraph::dot_print_edge(FILE *file, const T *from, const U *to, const char *prop)
+void CycleGraph::dot_print_edge(FILE *file, const ModelAction *from, const ModelAction *to, const char *prop)
 {
        CycleNode *fromnode = getNode(from);
        CycleNode *tonode = getNode(to);
 
        print_edge(file, fromnode, tonode, prop);
 }
 {
        CycleNode *fromnode = getNode(from);
        CycleNode *tonode = getNode(to);
 
        print_edge(file, fromnode, tonode, prop);
 }
-/* Instantiate two forms of CycleGraph::dot_print_edge */
-template void CycleGraph::dot_print_edge(FILE *file, const ModelAction *from, const ModelAction *to, const char *prop);
 
 void CycleGraph::dumpNodes(FILE *file) const
 {
 
 void CycleGraph::dumpNodes(FILE *file) const
 {
@@ -240,34 +229,16 @@ void CycleGraph::dumpGraphToFile(const char *filename) const
  */
 bool CycleGraph::checkReachable(const CycleNode *from, const CycleNode *to) const
 {
  */
 bool CycleGraph::checkReachable(const CycleNode *from, const CycleNode *to) const
 {
-       discovered->reset();
-       queue->clear();
-       queue->push_back(from);
-       discovered->put(from, from);
-       while (!queue->empty()) {
-               const CycleNode *node = queue->back();
-               queue->pop_back();
-               if (node == to)
-                       return true;
-               for (unsigned int i = 0;i < node->getNumEdges();i++) {
-                       CycleNode *next = node->getEdge(i);
-                       if (!discovered->contains(next)) {
-                               discovered->put(next, next);
-                               queue->push_back(next);
-                       }
-               }
-       }
-       return false;
+       return to->cv->synchronized_since(from->action);
 }
 
 /**
 }
 
 /**
- * Checks whether one ModelAction/Promise can reach another ModelAction/Promise
- * @param from The ModelAction or Promise from which to begin exploration
- * @param to The ModelAction or Promise to reach
+ * Checks whether one ModelAction can reach another ModelAction
+ * @param from The ModelAction from which to begin exploration
+ * @param to The ModelAction to reach
  * @return True, @a from can reach @a to; otherwise, false
  */
  * @return True, @a from can reach @a to; otherwise, false
  */
-template <typename T, typename U>
-bool CycleGraph::checkReachable(const T *from, const U *to) const
+bool CycleGraph::checkReachable(const ModelAction *from, const ModelAction *to) const
 {
        CycleNode *fromnode = getNode_noCreate(from);
        CycleNode *tonode = getNode_noCreate(to);
 {
        CycleNode *fromnode = getNode_noCreate(from);
        CycleNode *tonode = getNode_noCreate(to);
@@ -277,45 +248,6 @@ bool CycleGraph::checkReachable(const T *from, const U *to) const
 
        return checkReachable(fromnode, tonode);
 }
 
        return checkReachable(fromnode, tonode);
 }
-/* Instantiate four forms of CycleGraph::checkReachable */
-template bool CycleGraph::checkReachable(const ModelAction *from,
-                                                                                                                                                                const ModelAction *to) const;
-
-/** @brief Begin a new sequence of graph additions which can be rolled back */
-void CycleGraph::startChanges()
-{
-       ASSERT(rollbackvector.empty());
-       ASSERT(rmwrollbackvector.empty());
-       ASSERT(oldCycles == hasCycles);
-}
-
-/** Commit changes to the cyclegraph. */
-void CycleGraph::commitChanges()
-{
-       rollbackvector.clear();
-       rmwrollbackvector.clear();
-       oldCycles = hasCycles;
-}
-
-/** Rollback changes to the previous commit. */
-void CycleGraph::rollbackChanges()
-{
-       for (unsigned int i = 0;i < rollbackvector.size();i++)
-               rollbackvector[i]->removeEdge();
-
-       for (unsigned int i = 0;i < rmwrollbackvector.size();i++)
-               rmwrollbackvector[i]->clearRMW();
-
-       hasCycles = oldCycles;
-       rollbackvector.clear();
-       rmwrollbackvector.clear();
-}
-
-/** @returns whether a CycleGraph contains cycles. */
-bool CycleGraph::checkForCycles() const
-{
-       return hasCycles;
-}
 
 /**
  * @brief Constructor for a CycleNode
 
 /**
  * @brief Constructor for a CycleNode
@@ -323,7 +255,8 @@ bool CycleGraph::checkForCycles() const
  */
 CycleNode::CycleNode(const ModelAction *act) :
        action(act),
  */
 CycleNode::CycleNode(const ModelAction *act) :
        action(act),
-       hasRMW(NULL)
+       hasRMW(NULL),
+       cv(new ClockVector(NULL, act))
 {
 }
 
 {
 }
 
@@ -342,24 +275,6 @@ unsigned int CycleNode::getNumEdges() const
        return edges.size();
 }
 
        return edges.size();
 }
 
-/**
- * @brief Remove an element from a vector
- * @param v The vector
- * @param n The element to remove
- * @return True if the element was found; false otherwise
- */
-template <typename T>
-static bool vector_remove_node(SnapVector<T>& v, const T n)
-{
-       for (unsigned int i = 0;i < v.size();i++) {
-               if (v[i] == n) {
-                       v.erase(v.begin() + i);
-                       return true;
-               }
-       }
-       return false;
-}
-
 /**
  * @brief Remove a (forward) edge from this CycleNode
  * @return The CycleNode which was popped, if one exists; otherwise NULL
 /**
  * @brief Remove a (forward) edge from this CycleNode
  * @return The CycleNode which was popped, if one exists; otherwise NULL
@@ -379,13 +294,12 @@ CycleNode * CycleNode::removeEdge()
  * @param node The node to which we add a directed edge
  * @return True if this edge is a new edge; false otherwise
  */
  * @param node The node to which we add a directed edge
  * @return True if this edge is a new edge; false otherwise
  */
-bool CycleNode::addEdge(CycleNode *node)
+void CycleNode::addEdge(CycleNode *node)
 {
        for (unsigned int i = 0;i < edges.size();i++)
                if (edges[i] == node)
 {
        for (unsigned int i = 0;i < edges.size();i++)
                if (edges[i] == node)
-                       return false;
+                       return;
        edges.push_back(node);
        edges.push_back(node);
-       return true;
 }
 
 /** @returns the RMW CycleNode that reads from the current CycleNode */
 }
 
 /** @returns the RMW CycleNode that reads from the current CycleNode */
index fefe34401c15038484bd44389b4da44a80cc56ec..624ce885f2aadf4543dd9505b40a4192ceb802aa 100644 (file)
@@ -23,58 +23,33 @@ class CycleGraph {
 public:
        CycleGraph();
        ~CycleGraph();
 public:
        CycleGraph();
        ~CycleGraph();
+       void addEdge(const ModelAction *from, const ModelAction *to);
+       void addRMWEdge(const ModelAction *from, const ModelAction *rmw);
+       bool checkReachable(const ModelAction *from, const ModelAction *to) const;
 
 
-       template <typename T, typename U>
-       bool addEdge(const T *from, const U *to);
-
-       template <typename T>
-       void addRMWEdge(const T *from, const ModelAction *rmw);
-
-       bool checkForCycles() const;
-
-       template <typename T, typename U>
-       bool checkReachable(const T *from, const U *to) const;
-
-       void startChanges();
-       void commitChanges();
-       void rollbackChanges();
 #if SUPPORT_MOD_ORDER_DUMP
        void dumpNodes(FILE *file) const;
        void dumpGraphToFile(const char *filename) const;
 #if SUPPORT_MOD_ORDER_DUMP
        void dumpNodes(FILE *file) const;
        void dumpGraphToFile(const char *filename) const;
-
        void dot_print_node(FILE *file, const ModelAction *act);
        void dot_print_node(FILE *file, const ModelAction *act);
-       template <typename T, typename U>
-       void dot_print_edge(FILE *file, const T *from, const U *to, const char *prop);
+       void dot_print_edge(FILE *file, const ModelAction *from, const ModelAction *to, const char *prop);
 #endif
 #endif
-       CycleNode * getNode_noCreate(const ModelAction *act) const;
 
 
+       CycleNode * getNode_noCreate(const ModelAction *act) const;
        SNAPSHOTALLOC
 private:
        SNAPSHOTALLOC
 private:
-       bool addNodeEdge(CycleNode *fromnode, CycleNode *tonode);
+       void addNodeEdge(CycleNode *fromnode, CycleNode *tonode);
        void putNode(const ModelAction *act, CycleNode *node);
        CycleNode * getNode(const ModelAction *act);
        void putNode(const ModelAction *act, CycleNode *node);
        CycleNode * getNode(const ModelAction *act);
-       bool mergeNodes(CycleNode *node1, CycleNode *node2);
-
-       HashTable<const CycleNode *, const CycleNode *, uintptr_t, 4, model_malloc, model_calloc, model_free> *discovered;
-       ModelVector<const CycleNode *> * queue;
-
 
        /** @brief A table for mapping ModelActions to CycleNodes */
        HashTable<const ModelAction *, CycleNode *, uintptr_t, 4> actionToNode;
 
        /** @brief A table for mapping ModelActions to CycleNodes */
        HashTable<const ModelAction *, CycleNode *, uintptr_t, 4> actionToNode;
+       SnapVector<const CycleNode *> * queue;
 
 #if SUPPORT_MOD_ORDER_DUMP
        SnapVector<CycleNode *> nodeList;
 #endif
 
        bool checkReachable(const CycleNode *from, const CycleNode *to) const;
 
 #if SUPPORT_MOD_ORDER_DUMP
        SnapVector<CycleNode *> nodeList;
 #endif
 
        bool checkReachable(const CycleNode *from, const CycleNode *to) const;
-
-       /** @brief A flag: true if this graph contains cycles */
-       bool hasCycles;
-       /** @brief The previous value of CycleGraph::hasCycles, for rollback */
-       bool oldCycles;
-
-       SnapVector<CycleNode *> rollbackvector;
-       SnapVector<CycleNode *> rmwrollbackvector;
 };
 
 /**
 };
 
 /**
@@ -83,11 +58,10 @@ private:
 class CycleNode {
 public:
        CycleNode(const ModelAction *act);
 class CycleNode {
 public:
        CycleNode(const ModelAction *act);
-       bool addEdge(CycleNode *node);
+       void addEdge(CycleNode *node);
        CycleNode * getEdge(unsigned int i) const;
        unsigned int getNumEdges() const;
        CycleNode * removeEdge();
        CycleNode * getEdge(unsigned int i) const;
        unsigned int getNumEdges() const;
        CycleNode * removeEdge();
-
        bool setRMW(CycleNode *);
        CycleNode * getRMW() const;
        void clearRMW() { hasRMW = NULL; }
        bool setRMW(CycleNode *);
        CycleNode * getRMW() const;
        void clearRMW() { hasRMW = NULL; }
@@ -104,6 +78,10 @@ private:
        /** Pointer to a RMW node that reads from this node, or NULL, if none
         * exists */
        CycleNode *hasRMW;
        /** Pointer to a RMW node that reads from this node, or NULL, if none
         * exists */
        CycleNode *hasRMW;
+
+       /** ClockVector for this Node. */
+       ClockVector *cv;
+       friend class CycleGraph;
 };
 
 #endif /* __CYCLEGRAPH_H__ */
 };
 
 #endif /* __CYCLEGRAPH_H__ */
index e253ab0f2611e65898173fc504177a040ea394dd..b62f69443dff0f10df28ca58e97cfa02926dbe00 100644 (file)
@@ -28,7 +28,6 @@ struct model_snapshot_members {
                used_sequence_numbers(0),
                bugs(),
                bad_synchronization(false),
                used_sequence_numbers(0),
                bugs(),
                bad_synchronization(false),
-               bad_sc_read(false),
                asserted(false)
        { }
 
                asserted(false)
        { }
 
@@ -43,16 +42,13 @@ struct model_snapshot_members {
        SnapVector<bug_message *> bugs;
        /** @brief Incorrectly-ordered synchronization was made */
        bool bad_synchronization;
        SnapVector<bug_message *> bugs;
        /** @brief Incorrectly-ordered synchronization was made */
        bool bad_synchronization;
-       bool bad_sc_read;
        bool asserted;
 
        SNAPSHOTALLOC
 };
 
 /** @brief Constructor */
        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),
        model(m),
        params(NULL),
        scheduler(scheduler),
@@ -190,13 +186,6 @@ void ModelExecution::set_bad_synchronization()
        priv->bad_synchronization = true;
 }
 
        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));
 bool ModelExecution::assert_bug(const char *msg)
 {
        priv->bugs.push_back(new bug_message(msg));
@@ -283,7 +272,7 @@ 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.
  */
  * @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)
+bool ModelExecution::process_read(ModelAction *curr, SnapVector<ModelAction *> * rf_set)
 {
        while(true) {
 
 {
        while(true) {
 
@@ -294,7 +283,7 @@ bool ModelExecution::process_read(ModelAction *curr, ModelVector<ModelAction *>
                ASSERT(rf);
 
                mo_graph->startChanges();
                ASSERT(rf);
 
                mo_graph->startChanges();
-               bool updated = r_modification_order(curr, rf);
+               r_modification_order(curr, rf);
                if (!is_infeasible()) {
                        read_from(curr, rf);
                        mo_graph->commitChanges();
                if (!is_infeasible()) {
                        read_from(curr, rf);
                        mo_graph->commitChanges();
@@ -696,7 +685,7 @@ ModelAction * ModelExecution::check_current_action(ModelAction *curr)
        if (!second_part_of_rmw)
                add_action_to_lists(curr);
 
        if (!second_part_of_rmw)
                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);
        /* Build may_read_from set for newly-created actions */
        if (newly_explored && curr->is_read())
                rf_set = build_may_read_from(curr);
@@ -745,8 +734,6 @@ void ModelExecution::print_infeasibility(const char *prefix) const
                ptr += sprintf(ptr, "[mo cycle]");
        if (priv->bad_synchronization)
                ptr += sprintf(ptr, "[bad sw ordering]");
                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);
 }
        if (ptr != buf)
                model_print("%s: %s", prefix ? prefix : "Infeasible", buf);
 }
@@ -760,8 +747,7 @@ void ModelExecution::print_infeasibility(const char *prefix) const
 bool ModelExecution::is_infeasible() const
 {
        return mo_graph->checkForCycles() ||
 bool ModelExecution::is_infeasible() const
 {
        return mo_graph->checkForCycles() ||
-                                priv->bad_synchronization ||
-                                priv->bad_sc_read;
+                                priv->bad_synchronization;
 }
 
 /** Close out a RMWR by converting previous RMWR into a RMW or READ. */
 }
 
 /** Close out a RMWR by converting previous RMWR into a RMW or READ. */
@@ -791,12 +777,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
  */
  * @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<ModelAction *> * priorset)
 {
        SnapVector<action_list_t> *thrd_lists = obj_thrd_map.get(curr->get_location());
        unsigned int i;
 {
        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 */
        ASSERT(curr->is_read());
 
        /* Last SC fence in the current thread */
@@ -838,20 +823,26 @@ 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) {
                                /* 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->add(act);
                                        break;
                                }
                                /* C++, Section 29.3 statement 4 */
                                else if (act->is_seqcst() && last_sc_fence_local &&
                                                                 *act < *last_sc_fence_local) {
                                        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;
-                                       break;
+                                 if (mo_graph->checkReachable(rf, act))
+                                   return false;
+                                 priorset->add(act);
+                                 break;
                                }
                                /* C++, Section 29.3 statement 6 */
                                else if (last_sc_fence_thread_before &&
                                                                 *act < *last_sc_fence_thread_before) {
                                }
                                /* 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;
-                                       break;
+                                 if (mo_graph->checkReachable(rf, act))
+                                   return false;
+                                 priorset->add(act);
+                                 break;
                                }
                        }
 
                                }
                        }
 
@@ -861,18 +852,22 @@ bool ModelExecution::r_modification_order(ModelAction *curr, const rf_type *rf)
                         */
                        if (act->happens_before(curr)) {
                                if (act->is_write()) {
                         */
                        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->add(act);
                                } else {
                                        const ModelAction *prevrf = act->get_reads_from();
                                } 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->add(prevrf);
+                                       }
                                }
                                break;
                        }
                }
        }
                                }
                                break;
                        }
                }
        }
-
-       return added;
+       return true;
 }
 
 /**
 }
 
 /**
@@ -899,11 +894,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
  */
  * 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;
 {
        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()) {
        ASSERT(curr->is_write());
 
        if (curr->is_seqcst()) {
@@ -911,7 +905,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) {
                         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);
                }
        }
 
                }
        }
 
@@ -954,7 +948,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) {
                        /* 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);
                                break;
                        }
 
                                break;
                        }
 
@@ -970,10 +964,10 @@ bool ModelExecution::w_modification_order(ModelAction *curr)
                                 *   readfrom(act) --mo--> act
                                 */
                                if (act->is_write())
                                 *   readfrom(act) --mo--> act
                                 */
                                if (act->is_write())
-                                       added = mo_graph->addEdge(act, curr) || added;
+                                       mo_graph->addEdge(act, curr);
                                else if (act->is_read()) {
                                        //if previous read accessed a null, just keep going
                                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);
                                }
                                break;
                        } else if (act->is_read() && !act->could_synchronize_with(curr) &&
                                }
                                break;
                        } else if (act->is_read() && !act->could_synchronize_with(curr) &&
@@ -994,8 +988,6 @@ bool ModelExecution::w_modification_order(ModelAction *curr)
                        }
                }
        }
                        }
                }
        }
-
-       return added;
 }
 
 /**
 }
 
 /**
@@ -1327,7 +1319,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.
  */
  * @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;
 {
        SnapVector<action_list_t> *thrd_lists = obj_thrd_map.get(curr->get_location());
        unsigned int i;
@@ -1338,7 +1330,8 @@ ModelVector<ModelAction *> *  ModelExecution::build_may_read_from(ModelAction *c
        if (curr->is_seqcst())
                last_sc_write = get_last_seq_cst_write(curr);
 
        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 *>();
+       SnapVector<ModelAction *> * priorset = new SnapVector<ModelAction *>();
 
        /* Iterate over all threads */
        for (i = 0;i < thrd_lists->size();i++) {
 
        /* Iterate over all threads */
        for (i = 0;i < thrd_lists->size();i++) {
index 950d6335c6dbb83f8aed88c6d5aa37face17d8d6..40cd3ac03ba1360013c64bc52bef7b24c03293f7 100644 (file)
@@ -120,7 +120,6 @@ private:
 
        bool mo_may_allow(const ModelAction *writer, const ModelAction *reader);
        void set_bad_synchronization();
 
        bool mo_may_allow(const ModelAction *writer, const ModelAction *reader);
        void set_bad_synchronization();
-       void set_bad_sc_read();
        bool should_wake_up(const ModelAction *curr, const Thread *thread) const;
        void wake_up_sleeping_actions(ModelAction *curr);
        modelclock_t get_next_seq_num();
        bool should_wake_up(const ModelAction *curr, const Thread *thread) const;
        void wake_up_sleeping_actions(ModelAction *curr);
        modelclock_t get_next_seq_num();
@@ -128,7 +127,7 @@ private:
        bool next_execution();
        ModelAction * check_current_action(ModelAction *curr);
        bool initialize_curr_action(ModelAction **curr);
        bool next_execution();
        ModelAction * check_current_action(ModelAction *curr);
        bool initialize_curr_action(ModelAction **curr);
-       bool process_read(ModelAction *curr, ModelVector<ModelAction *> * rf_set);
+       bool process_read(ModelAction *curr, SnapVector<ModelAction *> * rf_set);
        bool process_write(ModelAction *curr);
        bool process_fence(ModelAction *curr);
        bool process_mutex(ModelAction *curr);
        bool process_write(ModelAction *curr);
        bool process_fence(ModelAction *curr);
        bool process_mutex(ModelAction *curr);
@@ -142,13 +141,11 @@ private:
        ModelAction * get_last_seq_cst_write(ModelAction *curr) const;
        ModelAction * get_last_seq_cst_fence(thread_id_t tid, const ModelAction *before_fence) const;
        ModelAction * get_last_unlock(ModelAction *curr) const;
        ModelAction * get_last_seq_cst_write(ModelAction *curr) const;
        ModelAction * get_last_seq_cst_fence(thread_id_t tid, const ModelAction *before_fence) const;
        ModelAction * get_last_unlock(ModelAction *curr) const;
-       ModelVector<ModelAction *> * build_may_read_from(ModelAction *curr);
+       SnapVector<ModelAction *> * build_may_read_from(ModelAction *curr);
        ModelAction * process_rmw(ModelAction *curr);
 
        ModelAction * process_rmw(ModelAction *curr);
 
-       template <typename rf_type>
-       bool r_modification_order(ModelAction *curr, const rf_type *rf);
-
-       bool w_modification_order(ModelAction *curr);
+  bool r_modification_order(ModelAction *curr, const ModelAction *rf, SnapVector<ModelAction *> *priorset);
+       void w_modification_order(ModelAction *curr);
        void get_release_seq_heads(ModelAction *acquire, ModelAction *read, rel_heads_list_t *release_heads);
        bool release_seq_heads(const ModelAction *rf, rel_heads_list_t *release_heads) const;
        ModelAction * get_uninitialized_action(const ModelAction *curr) const;
        void get_release_seq_heads(ModelAction *acquire, ModelAction *read, rel_heads_list_t *release_heads);
        bool release_seq_heads(const ModelAction *rf, rel_heads_list_t *release_heads) const;
        ModelAction * get_uninitialized_action(const ModelAction *curr) const;
index d3d9d2c52059ae87b2097f227a175856aac9a9e4..9ad61c3c5cddbc96073e85c15e8dd05f46bffadb 100644 (file)
--- a/fuzzer.cc
+++ b/fuzzer.cc
@@ -3,7 +3,7 @@
 #include "threads-model.h"
 #include "model.h"
 
 #include "threads-model.h"
 #include "model.h"
 
-int Fuzzer::selectWrite(ModelAction *read, ModelVector<ModelAction *> * rf_set) {
+int Fuzzer::selectWrite(ModelAction *read, SnapVector<ModelAction *> * rf_set) {
        int random_index = random() % rf_set->size();
        return random_index;
 }
        int random_index = random() % rf_set->size();
        return random_index;
 }
index 3a84351067690a66463a8651d260d8950cc269c8..6cf1efbad26352782e4a45b985654e8f52069a1b 100644 (file)
--- a/fuzzer.h
+++ b/fuzzer.h
@@ -7,7 +7,7 @@
 class Fuzzer {
 public:
        Fuzzer() {}
 class Fuzzer {
 public:
        Fuzzer() {}
-       int selectWrite(ModelAction *read, ModelVector<ModelAction *>* rf_set);
+       int selectWrite(ModelAction *read, SnapVector<ModelAction *>* rf_set);
        Thread * selectThread(Node *n, int * threadlist, int numthreads);
        Thread * selectNotify(action_list_t * waiters);
        MEMALLOC
        Thread * selectThread(Node *n, int * threadlist, int numthreads);
        Thread * selectNotify(action_list_t * waiters);
        MEMALLOC