Change initialize a bit
[c11tester.git] / cyclegraph.cc
index a3e86cf00b5f78ce098b5161d10c0dc90bc88390..1d9533f4ba9b6f2fa61ae0018bb36dc22de5abcc 100644 (file)
@@ -43,7 +43,7 @@ CycleNode * CycleGraph::getNode_noCreate(const ModelAction *act) const
  * @param action The ModelAction to find a node for
  * @return The CycleNode paired with this action
  */
-CycleNode * CycleGraph::getNode(const ModelAction *action)
+CycleNode * CycleGraph::getNode(ModelAction *action)
 {
        CycleNode *node = getNode_noCreate(action);
        if (node == NULL) {
@@ -59,32 +59,31 @@ CycleNode * CycleGraph::getNode(const ModelAction *action)
  * @param tonode The edge points to this CycleNode
  * @return True, if new edge(s) are added; otherwise false
  */
-void CycleGraph::addNodeEdge(CycleNode *fromnode, CycleNode *tonode)
+void CycleGraph::addNodeEdge(CycleNode *fromnode, CycleNode *tonode, bool forceedge)
 {
        //quick check whether edge is redundant
-       if (checkReachable(fromnode, tonode))
+       if (checkReachable(fromnode, tonode) && !forceedge) {
                return;
-
-       CycleNode *edgeSrcNode = fromnode;
+       }
 
        /*
         * 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) {
-               while (rmwnode->getRMW())
-                       rmwnode = rmwnode->getRMW();
-               edgeSrcNode = rmwnode;
+       while (CycleNode * nextnode = fromnode->getRMW()) {
+               if (nextnode == tonode)
+                       break;
+               fromnode = nextnode;
        }
 
-       edgeSrcNode->addEdge(tonode);   //Add edge to edgeSrcNode
+       fromnode->addEdge(tonode);      //Add edge to edgeSrcNode
 
        /* Propagate clock vector changes */
-       if (tonode->cv->merge(edgeSrcNode->cv)) {
-               queue->push_back(edgeSrcNode);
+       if (tonode->cv->merge(fromnode->cv)) {
+               queue->push_back(tonode);
                while(!queue->empty()) {
                        const CycleNode *node = queue->back();
+                       queue->pop_back();
                        unsigned int numedges = node->getNumEdges();
                        for(unsigned int i = 0;i < numedges;i++) {
                                CycleNode * enode = node->getEdge(i);
@@ -107,14 +106,13 @@ void CycleGraph::addNodeEdge(CycleNode *fromnode, CycleNode *tonode)
  * @param rmw The edge points to this ModelAction; this action must read from
  * the ModelAction from
  */
-void CycleGraph::addRMWEdge(const ModelAction *from, const ModelAction *rmw)
+void CycleGraph::addRMWEdge(ModelAction *from, ModelAction *rmw)
 {
        ASSERT(from);
        ASSERT(rmw);
 
        CycleNode *fromnode = getNode(from);
        CycleNode *rmwnode = getNode(rmw);
-
        /* We assume that this RMW has no RMW reading from it yet */
        ASSERT(!rmwnode->getRMW());
 
@@ -132,9 +130,41 @@ void CycleGraph::addRMWEdge(const ModelAction *from, const ModelAction *rmw)
                if (tonode != rmwnode) {
                        rmwnode->addEdge(tonode);
                }
+               tonode->removeInEdge(fromnode);
        }
+       fromnode->edges.clear();
+
+       addNodeEdge(fromnode, rmwnode, true);
+}
 
-       addNodeEdge(fromnode, rmwnode);
+void CycleGraph::addEdges(SnapList<ModelAction *> * edgeset, ModelAction *to) {
+       for(sllnode<ModelAction*> * it = edgeset->begin();it!=NULL;) {
+               ModelAction *act = it->getVal();
+               CycleNode *node = getNode(act);
+               sllnode<ModelAction*> * it2 = it;
+               it2=it2->getNext();
+               for(;it2!=NULL; ) {
+                       ModelAction *act2 = it2->getVal();
+                       CycleNode *node2 = getNode(act2);
+                       if (checkReachable(node, node2)) {
+                               it = edgeset->erase(it);
+                               goto endouterloop;
+                       } else if (checkReachable(node2, node)) {
+                               it2 = edgeset->erase(it2);
+                               goto endinnerloop;
+                       }
+                       it2=it2->getNext();
+endinnerloop:
+                       ;
+               }
+               it=it->getNext();
+endouterloop:
+               ;
+       }
+       for(sllnode<ModelAction*> *it = edgeset->begin();it!=NULL;it=it->getNext()) {
+               ModelAction *from = it->getVal();
+               addEdge(from, to, from->get_tid() == to->get_tid());
+       }
 }
 
 /**
@@ -151,7 +181,7 @@ void CycleGraph::addRMWEdge(const ModelAction *from, const ModelAction *rmw)
  * @return True, if new edge(s) are added; otherwise false
  */
 
-void CycleGraph::addEdge(const ModelAction *from, const ModelAction *to)
+void CycleGraph::addEdge(ModelAction *from, ModelAction *to)
 {
        ASSERT(from);
        ASSERT(to);
@@ -159,7 +189,18 @@ void CycleGraph::addEdge(const ModelAction *from, const ModelAction *to)
        CycleNode *fromnode = getNode(from);
        CycleNode *tonode = getNode(to);
 
-       addNodeEdge(fromnode, tonode);
+       addNodeEdge(fromnode, tonode, false);
+}
+
+void CycleGraph::addEdge(ModelAction *from, ModelAction *to, bool forceedge)
+{
+       ASSERT(from);
+       ASSERT(to);
+
+       CycleNode *fromnode = getNode(from);
+       CycleNode *tonode = getNode(to);
+
+       addNodeEdge(fromnode, tonode, forceedge);
 }
 
 #if SUPPORT_MOD_ORDER_DUMP
@@ -249,17 +290,54 @@ bool CycleGraph::checkReachable(const ModelAction *from, const ModelAction *to)
        return checkReachable(fromnode, tonode);
 }
 
+void CycleGraph::freeAction(const ModelAction * act) {
+       CycleNode *cn = actionToNode.remove(act);
+       for(unsigned int i=0;i<cn->edges.size();i++) {
+               CycleNode *dst = cn->edges[i];
+               dst->removeInEdge(cn);
+       }
+       for(unsigned int i=0;i<cn->inedges.size();i++) {
+               CycleNode *src = cn->inedges[i];
+               src->removeEdge(cn);
+       }
+       delete cn;
+}
+
 /**
  * @brief Constructor for a CycleNode
  * @param act The ModelAction for this node
  */
-CycleNode::CycleNode(const ModelAction *act) :
+CycleNode::CycleNode(ModelAction *act) :
        action(act),
        hasRMW(NULL),
        cv(new ClockVector(NULL, act))
 {
 }
 
+CycleNode::~CycleNode() {
+       delete cv;
+}
+
+void CycleNode::removeInEdge(CycleNode *src) {
+       for(unsigned int i=0;i < inedges.size();i++) {
+               if (inedges[i] == src) {
+                       inedges[i] = inedges[inedges.size()-1];
+                       inedges.pop_back();
+                       break;
+               }
+       }
+}
+
+void CycleNode::removeEdge(CycleNode *dst) {
+       for(unsigned int i=0;i < edges.size();i++) {
+               if (edges[i] == dst) {
+                       edges[i] = edges[edges.size()-1];
+                       edges.pop_back();
+                       break;
+               }
+       }
+}
+
 /**
  * @param i The index of the edge to return
  * @returns The CycleNode edge indexed by i
@@ -276,17 +354,18 @@ unsigned int CycleNode::getNumEdges() const
 }
 
 /**
- * @brief Remove a (forward) edge from this CycleNode
- * @return The CycleNode which was popped, if one exists; otherwise NULL
+ * @param i The index of the edge to return
+ * @returns The CycleNode edge indexed by i
  */
-CycleNode * CycleNode::removeEdge()
+CycleNode * CycleNode::getInEdge(unsigned int i) const
 {
-       if (edges.empty())
-               return NULL;
+       return inedges[i];
+}
 
-       CycleNode *ret = edges.back();
-       edges.pop_back();
-       return ret;
+/** @returns The number of edges leaving this CycleNode */
+unsigned int CycleNode::getNumInEdges() const
+{
+       return inedges.size();
 }
 
 /**
@@ -300,6 +379,7 @@ void CycleNode::addEdge(CycleNode *node)
                if (edges[i] == node)
                        return;
        edges.push_back(node);
+       node->inedges.push_back(this);
 }
 
 /** @returns the RMW CycleNode that reads from the current CycleNode */