X-Git-Url: http://plrg.eecs.uci.edu/git/?p=c11tester.git;a=blobdiff_plain;f=cyclegraph.cc;h=7a3532830598684a7719f6f3329fcda746aa5ccc;hp=9a511952b0826470befc1a2bcc7ecde85619265c;hb=29f99ad8eea3c32b435ddb009c2d20fee7a13df2;hpb=8cebf02d9a4c9f0fe80af04f6276f4978f3b93f5 diff --git a/cyclegraph.cc b/cyclegraph.cc index 9a511952..7a353283 100644 --- a/cyclegraph.cc +++ b/cyclegraph.cc @@ -8,9 +8,7 @@ CycleGraph::CycleGraph() : discovered(new HashTable(16)), hasCycles(false), - oldCycles(false), - hasRMWViolation(false), - oldRMWViolation(false) + oldCycles(false) { } @@ -62,24 +60,28 @@ void CycleGraph::addEdge(const ModelAction *from, const ModelAction *to) CycleNode *fromnode = getNode(from); CycleNode *tonode = getNode(to); + addEdge(fromnode, tonode); +} + +/** + * Adds an edge between two CycleNodes. + * @param fromnode The edge comes from this CycleNode + * @param tonode The edge points to this CycleNode + */ +void CycleGraph::addEdge(CycleNode *fromnode, CycleNode *tonode) +{ if (!hasCycles) hasCycles = checkReachable(tonode, fromnode); if (fromnode->addEdge(tonode)) rollbackvector.push_back(fromnode); - - CycleNode *rmwnode = fromnode->getRMW(); - /* * If the fromnode has a rmwnode that is not the tonode, we should add * an edge between its rmwnode and the tonode - * - * If tonode is also a rmw, don't do this check as the execution is - * doomed and we'll catch the problem elsewhere, but we want to allow - * for the possibility of sending to's write value to rmwnode */ - if (rmwnode != NULL && !to->is_rmw()) { + CycleNode *rmwnode = fromnode->getRMW(); + if (rmwnode && rmwnode != tonode) { if (!hasCycles) hasCycles = checkReachable(tonode, rmwnode); @@ -88,10 +90,17 @@ void CycleGraph::addEdge(const ModelAction *from, const ModelAction *to) } } -/** Handles special case of a RMW action. The ModelAction rmw reads - * from the ModelAction from. The key differences are: (1) no write - * can occur in between the rmw and the from action. Only one RMW - * action can read from a given write. +/** + * @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 from. The key differences are: + * (1) no write can occur in between the rmw and the from action. + * (2) Only one RMW action can read from a given write. + * + * @param from The edge comes from this ModelAction + * @param rmw The edge points to this ModelAction; this action must read from + * ModelAction from */ void CycleGraph::addRMWEdge(const ModelAction *from, const ModelAction *rmw) { @@ -102,11 +111,10 @@ void CycleGraph::addRMWEdge(const ModelAction *from, const ModelAction *rmw) CycleNode *rmwnode = getNode(rmw); /* Two RMW actions cannot read from the same write. */ - if (fromnode->setRMW(rmwnode)) { - hasRMWViolation = true; - } else { + if (fromnode->setRMW(rmwnode)) + hasCycles = true; + else rmwrollbackvector.push_back(fromnode); - } /* Transfer all outgoing edges from the from node to the rmw node */ /* This process should not add a cycle because either: @@ -123,11 +131,7 @@ void CycleGraph::addRMWEdge(const ModelAction *from, const ModelAction *rmw) } } - if (!hasCycles) - hasCycles = checkReachable(rmwnode, fromnode); - - if (fromnode->addEdge(rmwnode)) - rollbackvector.push_back(fromnode); + addEdge(fromnode, rmwnode); } #if SUPPORT_MOD_ORDER_DUMP @@ -236,36 +240,31 @@ bool CycleGraph::checkPromise(const ModelAction *fromact, Promise *promise) cons void CycleGraph::startChanges() { - ASSERT(rollbackvector.size() == 0); - ASSERT(rmwrollbackvector.size() == 0); + ASSERT(rollbackvector.empty()); + ASSERT(rmwrollbackvector.empty()); ASSERT(oldCycles == hasCycles); - ASSERT(oldRMWViolation == hasRMWViolation); } /** Commit changes to the cyclegraph. */ void CycleGraph::commitChanges() { - rollbackvector.resize(0); - rmwrollbackvector.resize(0); + rollbackvector.clear(); + rmwrollbackvector.clear(); oldCycles = hasCycles; - oldRMWViolation = hasRMWViolation; } /** Rollback changes to the previous commit. */ void CycleGraph::rollbackChanges() { - for (unsigned int i = 0; i < rollbackvector.size(); i++) { + for (unsigned int i = 0; i < rollbackvector.size(); i++) rollbackvector[i]->popEdge(); - } - for (unsigned int i = 0; i < rmwrollbackvector.size(); i++) { + for (unsigned int i = 0; i < rmwrollbackvector.size(); i++) rmwrollbackvector[i]->clearRMW(); - } hasCycles = oldCycles; - hasRMWViolation = oldRMWViolation; - rollbackvector.resize(0); - rmwrollbackvector.resize(0); + rollbackvector.clear(); + rmwrollbackvector.clear(); } /** @returns whether a CycleGraph contains cycles. */ @@ -274,17 +273,24 @@ bool CycleGraph::checkForCycles() const return hasCycles; } -bool CycleGraph::checkForRMWViolation() const -{ - return hasRMWViolation; -} - /** * @brief Constructor for a CycleNode * @param act The ModelAction for this node */ CycleNode::CycleNode(const ModelAction *act) : action(act), + promise(NULL), + hasRMW(NULL) +{ +} + +/** + * @brief Constructor for a Promise CycleNode + * @param promise The Promise which was generated + */ +CycleNode::CycleNode(const Promise *promise) : + action(NULL), + promise(promise), hasRMW(NULL) { }