/** Initializes a CycleGraph object. */
CycleGraph::CycleGraph() :
- hasCycles(false)
+ hasCycles(false),
+ oldCycles(false)
{
}
// Check for Cycles
hasCycles=checkReachable(tonode, fromnode);
}
+
+ rollbackvector.push_back(fromnode);
fromnode->addEdge(tonode);
CycleNode * rmwnode=fromnode->getRMW();
// Check for Cycles
hasCycles=checkReachable(tonode, rmwnode);
}
+ rollbackvector.push_back(rmwnode);
rmwnode->addEdge(tonode);
}
}
/* Two RMW actions cannot read from the same write. */
if (fromnode->setRMW(rmwnode)) {
hasCycles=true;
+ } else {
+ rmwrollbackvector.push_back(fromnode);
}
/* Transfer all outgoing edges from the from node to the rmw node */
std::vector<CycleNode *> * edges=fromnode->getEdges();
for(unsigned int i=0;i<edges->size();i++) {
CycleNode * tonode=(*edges)[i];
+ rollbackvector.push_back(rmwnode);
rmwnode->addEdge(tonode);
}
-
+ rollbackvector.push_back(fromnode);
fromnode->addEdge(rmwnode);
}
return false;
}
+/** Commit changes to the cyclegraph. */
+void CycleGraph::commitChanges() {
+ rollbackvector.resize(0);
+ rmwrollbackvector.resize(0);
+ oldCycles=hasCycles;
+}
+
+/** Rollback changes to the previous commit. */
+void CycleGraph::rollbackChanges() {
+ for (unsigned int i = 0; i < rollbackvector.size(); i++) {
+ rollbackvector[i]->popEdge();
+ }
+
+ for (unsigned int i = 0; i < rmwrollbackvector.size(); i++) {
+ rmwrollbackvector[i]->clearRMW();
+ }
+
+ hasCycles = oldCycles;
+ rollbackvector.resize(0);
+ rmwrollbackvector.resize(0);
+}
+
/** @returns whether a CycleGraph contains cycles. */
bool CycleGraph::checkForCycles() {
return hasCycles;
* @see CycleGraph::addRMWEdge
*/
bool CycleNode::setRMW(CycleNode *node) {
- CycleNode * oldhasRMW=hasRMW;
+ if (hasRMW!=NULL)
+ return true;
hasRMW=node;
- return (oldhasRMW!=NULL);
+ return false;
}
void addRMWEdge(const ModelAction *from, const ModelAction *rmw);
bool checkReachable(const ModelAction *from, const ModelAction *to);
+ void commitChanges();
+ void rollbackChanges();
private:
CycleNode * getNode(const ModelAction *);
/** @brief A flag: true if this graph contains cycles */
bool hasCycles;
+
+ bool oldCycles;
+
+ std::vector<CycleNode *> rollbackvector;
+ std::vector<CycleNode *> rmwrollbackvector;
};
/** @brief A node within a CycleGraph; corresponds to one ModelAction */
std::vector<CycleNode *> * getEdges();
bool setRMW(CycleNode *);
CycleNode* getRMW();
+ void popEdge() {
+ edges.pop_back();
+ };
+ void clearRMW() {
+ hasRMW=NULL;
+ }
private:
/** @brief The ModelAction that this node represents */