X-Git-Url: http://plrg.eecs.uci.edu/git/?p=model-checker.git;a=blobdiff_plain;f=cyclegraph.cc;h=33f8cda85cedacffdea92d344be05ddf4f4b10e4;hp=2bfe76ac424c274bf8152638543ad7dd6bc1d31f;hb=d884d14a6288f1ee1809158e81ffb05bf83f483b;hpb=1aeeeebeeed5c45f49649c7e94d9c5d682e2942f diff --git a/cyclegraph.cc b/cyclegraph.cc index 2bfe76a..33f8cda 100644 --- a/cyclegraph.cc +++ b/cyclegraph.cc @@ -1,6 +1,8 @@ #include "cyclegraph.h" #include "action.h" #include "common.h" +#include "promise.h" +#include "model.h" /** Initializes a CycleGraph object. */ CycleGraph::CycleGraph() : @@ -41,11 +43,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); @@ -83,7 +88,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); @@ -112,22 +116,22 @@ 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::dumpGraphToFile(const char *filename) { - char buffer[200]; - sprintf(buffer, "%s.dot",filename); - FILE *file=fopen(buffer, "w"); - fprintf(file, "digraph %s {\n",filename); - for(unsigned int i=0;i * edges=cn->getEdges(); const ModelAction *action=cn->getAction(); @@ -135,14 +139,22 @@ void CycleGraph::dumpGraphToFile(const char *filename) { 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;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()); - } + fprintf(file, "N%u -> N%u;\n", action->get_seq_number(), dstaction->get_seq_number()); + } } - fprintf(file,"}\n"); - fclose(file); +} + +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 @@ -169,8 +181,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(64); queue.push_back(from); discovered.put(from, from); @@ -191,6 +203,33 @@ bool CycleGraph::checkReachable(CycleNode *from, CycleNode *to) { return false; } +bool CycleGraph::checkPromise(const ModelAction *fromact, Promise *promise) { + std::vector > queue; + HashTable discovered(64); + CycleNode *from = actionToNode.get(fromact); + + + queue.push_back(from); + discovered.put(from, from); + while(!queue.empty()) { + CycleNode * node=queue.back(); + queue.pop_back(); + + if (promise->increment_threads(node->getAction()->get_tid())) { + return true; + } + + for(unsigned int i=0;igetEdges()->size();i++) { + CycleNode *next=(*node->getEdges())[i]; + if (!discovered.contains(next)) { + discovered.put(next,next); + queue.push_back(next); + } + } + } + return false; +} + void CycleGraph::startChanges() { ASSERT(rollbackvector.size()==0); ASSERT(rmwrollbackvector.size()==0);