X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=cyclegraph.cc;h=0528029a12e100f239b754b62492f639d8759762;hb=2144dfc0d165ac48d12bbc3cad43f1c2cd8355c7;hp=2280e76e3e208b8ac6ce6e2044433c1a866d2c85;hpb=c832cb55af09e735821ae3463bc37c29d3fa27c8;p=model-checker.git diff --git a/cyclegraph.cc b/cyclegraph.cc index 2280e76..0528029 100644 --- a/cyclegraph.cc +++ b/cyclegraph.cc @@ -6,6 +6,7 @@ /** Initializes a CycleGraph object. */ CycleGraph::CycleGraph() : + discovered(new HashTable(16)), hasCycles(false), oldCycles(false), hasRMWViolation(false), @@ -43,11 +44,14 @@ 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); + if (!hasCycles) { + // Reflexive edges are cycles + hasCycles = (from == to); + } if (!hasCycles) { // Check for Cycles hasCycles=checkReachable(tonode, fromnode); @@ -85,7 +89,6 @@ 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); @@ -104,9 +107,8 @@ void CycleGraph::addRMWEdge(const ModelAction *from, const ModelAction *rmw) { * (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]; + 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); @@ -114,41 +116,44 @@ void CycleGraph::addRMWEdge(const ModelAction *from, const ModelAction *rmw) { } + if (!hasCycles) { + // Reflexive edges are cycles + hasCycles = (from == rmw); + } if (!hasCycles) { // With promises we could be setting up a cycle here if we aren't // careful...avoid it.. hasCycles=checkReachable(rmwnode, fromnode); } - if(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]; + for (unsigned int j = 0; j < cn->getNumEdges(); j++) { + CycleNode *dst = cn->getEdge(j); const ModelAction *dstaction=dst->getAction(); - fprintf(file, "N%u -> N%u;\n", action->get_seq_number(), dstaction->get_seq_number()); - } + 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); + sprintf(buffer, "%s.dot",filename); + FILE *file=fopen(buffer, "w"); + fprintf(file, "digraph %s {\n",filename); dumpNodes(file); - fprintf(file,"}\n"); - fclose(file); + fprintf(file,"}\n"); + fclose(file); } #endif @@ -176,20 +181,20 @@ bool CycleGraph::checkReachable(const ModelAction *from, const ModelAction *to) */ bool CycleGraph::checkReachable(CycleNode *from, CycleNode *to) { std::vector > queue; - HashTable discovered(64); + discovered->reset(); queue.push_back(from); - discovered.put(from, from); + discovered->put(from, from); while(!queue.empty()) { CycleNode * node=queue.back(); queue.pop_back(); if (node==to) return true; - for(unsigned int i=0;igetEdges()->size();i++) { - CycleNode *next=(*node->getEdges())[i]; - if (!discovered.contains(next)) { - discovered.put(next,next); + 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); } } @@ -199,12 +204,12 @@ bool CycleGraph::checkReachable(CycleNode *from, CycleNode *to) { bool CycleGraph::checkPromise(const ModelAction *fromact, Promise *promise) { std::vector > queue; - HashTable discovered(64); + discovered->reset(); CycleNode *from = actionToNode.get(fromact); queue.push_back(from); - discovered.put(from, from); + discovered->put(from, from); while(!queue.empty()) { CycleNode * node=queue.back(); queue.pop_back(); @@ -213,10 +218,10 @@ bool CycleGraph::checkPromise(const ModelAction *fromact, Promise *promise) { return true; } - for(unsigned int i=0;igetEdges()->size();i++) { - CycleNode *next=(*node->getEdges())[i]; - if (!discovered.contains(next)) { - discovered.put(next,next); + 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); } } @@ -274,9 +279,19 @@ CycleNode::CycleNode(const ModelAction *modelaction) : { } -/** @returns a vector of the edges from a CycleNode. */ -std::vector * CycleNode::getEdges() { - return &edges; +/** + * @param i The index of the edge to return + * @returns The a CycleNode edge indexed by i + */ +CycleNode * CycleNode::getEdge(unsigned int i) const +{ + return edges[i]; +} + +/** @returns The number of edges leaving this CycleNode */ +unsigned int CycleNode::getNumEdges() const +{ + return edges.size(); } /**