X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=cyclegraph.cc;h=321ebe9e2f242babe1adad4e233dd7fe51427e71;hb=61db3a1768f1b90ad997e648a7e622c7ef47b69b;hp=0a3d8858e795849f16ab1cae667b2e34bb1367cc;hpb=59b62a130c9615c9ccd23c4354c7bc827d5eda3b;p=model-checker.git diff --git a/cyclegraph.cc b/cyclegraph.cc index 0a3d885..321ebe9 100644 --- a/cyclegraph.cc +++ b/cyclegraph.cc @@ -25,6 +25,9 @@ CycleNode * CycleGraph::getNode(const ModelAction *action) { if (node==NULL) { node=new CycleNode(action); actionToNode.put(action, node); +#if SUPPORT_MOD_ORDER_DUMP + nodeList.push_back(node); +#endif } return node; } @@ -38,6 +41,7 @@ CycleNode * CycleGraph::getNode(const ModelAction *action) { void CycleGraph::addEdge(const ModelAction *from, const ModelAction *to) { ASSERT(from); ASSERT(to); + ASSERT(from != to); CycleNode *fromnode=getNode(from); CycleNode *tonode=getNode(to); @@ -47,8 +51,9 @@ void CycleGraph::addEdge(const ModelAction *from, const ModelAction *to) { hasCycles=checkReachable(tonode, fromnode); } - rollbackvector.push_back(fromnode); - fromnode->addEdge(tonode); + if (fromnode->addEdge(tonode)) + rollbackvector.push_back(fromnode); + CycleNode * rmwnode=fromnode->getRMW(); @@ -64,8 +69,9 @@ void CycleGraph::addEdge(const ModelAction *from, const ModelAction *to) { // Check for Cycles hasCycles=checkReachable(tonode, rmwnode); } - rollbackvector.push_back(rmwnode); - rmwnode->addEdge(tonode); + + if (rmwnode->addEdge(tonode)) + rollbackvector.push_back(rmwnode); } } @@ -77,6 +83,7 @@ void CycleGraph::addEdge(const ModelAction *from, const ModelAction *to) { void CycleGraph::addRMWEdge(const ModelAction *from, const ModelAction *rmw) { ASSERT(from); ASSERT(rmw); + ASSERT(from != rmw); CycleNode *fromnode=getNode(from); CycleNode *rmwnode=getNode(rmw); @@ -89,29 +96,59 @@ void CycleGraph::addRMWEdge(const ModelAction *from, const ModelAction *rmw) { } /* Transfer all outgoing edges from the from node to the rmw node */ - /* This process should not add a cycle because either: + /* This process should not add a cycle because either: * (1) The rmw should not have any incoming edges yet if it is the * new node or - * (2) the fromnode is the new node and therefore it should not + * (2) the fromnode is the new node and therefore it should not * have any outgoing edges. */ std::vector * edges=fromnode->getEdges(); for(unsigned int i=0;isize();i++) { CycleNode * tonode=(*edges)[i]; if (tonode!=rmwnode) { - rollbackvector.push_back(rmwnode); - rmwnode->addEdge(tonode); + if (rmwnode->addEdge(tonode)) + rollbackvector.push_back(rmwnode); } } - rollbackvector.push_back(fromnode); + if (!hasCycles) { // With promises we could be setting up a cycle here if we aren't // careful...avoid it.. hasCycles=checkReachable(rmwnode, fromnode); } - fromnode->addEdge(rmwnode); + if(fromnode->addEdge(rmwnode)) + rollbackvector.push_back(fromnode); +} + +#if SUPPORT_MOD_ORDER_DUMP +void CycleGraph::dumpNodes(FILE *file) { + for(unsigned int i=0;i * edges=cn->getEdges(); + const ModelAction *action=cn->getAction(); + fprintf(file, "N%u [label=\"%u, T%u\"];\n",action->get_seq_number(),action->get_seq_number(), action->get_tid()); + if (cn->getRMW()!=NULL) { + fprintf(file, "N%u -> N%u[style=dotted];\n", action->get_seq_number(), cn->getRMW()->getAction()->get_seq_number()); + } + for(unsigned int j=0;jsize();j++) { + CycleNode *dst=(*edges)[j]; + const ModelAction *dstaction=dst->getAction(); + fprintf(file, "N%u -> N%u;\n", action->get_seq_number(), dstaction->get_seq_number()); + } + } +} + +void CycleGraph::dumpGraphToFile(const char *filename) { + char buffer[200]; + sprintf(buffer, "%s.dot",filename); + FILE *file=fopen(buffer, "w"); + fprintf(file, "digraph %s {\n",filename); + dumpNodes(file); + fprintf(file,"}\n"); + fclose(file); } +#endif /** * Checks whether one ModelAction can reach another. @@ -136,8 +173,8 @@ bool CycleGraph::checkReachable(const ModelAction *from, const ModelAction *to) * @return True, @a from can reach @a to; otherwise, false */ bool CycleGraph::checkReachable(CycleNode *from, CycleNode *to) { - std::vector queue; - HashTable discovered; + std::vector > queue; + HashTable discovered; queue.push_back(from); discovered.put(from, from); @@ -217,8 +254,12 @@ std::vector * CycleNode::getEdges() { * Adds an edge from this CycleNode to another CycleNode. * @param node The node to which we add a directed edge */ -void CycleNode::addEdge(CycleNode *node) { +bool CycleNode::addEdge(CycleNode *node) { + for(unsigned int i=0;i