X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=cyclegraph.cc;h=eaddc8e1714629f8834a5b11c891f8009b2e1237;hb=ae1340cbd7d2f75d76a4199597f454290badcc8b;hp=46b0d4ac4eb803df74d57e53148d0d463f343e26;hpb=d3dffe991352938e5c2ab738ce70e3ec0f069d5f;p=model-checker.git diff --git a/cyclegraph.cc b/cyclegraph.cc index 46b0d4a..eaddc8e 100644 --- a/cyclegraph.cc +++ b/cyclegraph.cc @@ -31,14 +31,29 @@ void CycleGraph::putNode(const ModelAction *act, CycleNode *node) #endif } +/** @return The corresponding CycleNode, if exists; otherwise NULL */ +CycleNode * CycleGraph::getNode_noCreate(const ModelAction *act) const +{ + return actionToNode.get(act); +} + +/** @return The corresponding CycleNode, if exists; otherwise NULL */ +CycleNode * CycleGraph::getNode_noCreate(const Promise *promise) const +{ + return readerToPromiseNode.get(promise->get_action()); +} + /** * @brief Returns the CycleNode corresponding to a given ModelAction + * + * Gets (or creates, if none exist) a CycleNode corresponding to a ModelAction + * * @param action The ModelAction to find a node for * @return The CycleNode paired with this action */ CycleNode * CycleGraph::getNode(const ModelAction *action) { - CycleNode *node = actionToNode.get(action); + CycleNode *node = getNode_noCreate(action); if (node == NULL) { node = new CycleNode(action); putNode(action, node); @@ -58,7 +73,7 @@ CycleNode * CycleGraph::getNode(const ModelAction *action) CycleNode * CycleGraph::getNode(const Promise *promise) { const ModelAction *reader = promise->get_action(); - CycleNode *node = readerToPromiseNode.get(reader); + CycleNode *node = getNode_noCreate(promise); if (node == NULL) { node = new CycleNode(promise); readerToPromiseNode.put(reader, node); @@ -66,30 +81,6 @@ CycleNode * CycleGraph::getNode(const Promise *promise) return node; } -/* - * @brief Adds an edge between objects - * - * This function will add an edge between any two objects which can be - * associated with a CycleNode. That is, if they have a CycleGraph::getNode - * implementation. - * - * The object to is ordered after the object from. - * - * @param to The edge points to this object, of type T - * @param from The edge comes from this object, of type U - */ -template -void CycleGraph::addEdge(const T from, const U to) -{ - ASSERT(from); - ASSERT(to); - - CycleNode *fromnode = getNode(from); - CycleNode *tonode = getNode(to); - - addNodeEdge(fromnode, tonode); -} - /** * @return false if the resolution results in a cycle; true otherwise */ @@ -177,13 +168,16 @@ bool CycleGraph::mergeNodes(CycleNode *w_node, CycleNode *p_node, * Adds an edge between two CycleNodes. * @param fromnode The edge comes from this CycleNode * @param tonode The edge points to this CycleNode + * @return True, if new edge(s) are added; otherwise false */ -void CycleGraph::addNodeEdge(CycleNode *fromnode, CycleNode *tonode) +bool CycleGraph::addNodeEdge(CycleNode *fromnode, CycleNode *tonode) { + bool added; + if (!hasCycles) hasCycles = checkReachable(tonode, fromnode); - if (fromnode->addEdge(tonode)) + if ((added = fromnode->addEdge(tonode))) rollbackvector.push_back(fromnode); /* @@ -195,9 +189,12 @@ void CycleGraph::addNodeEdge(CycleNode *fromnode, CycleNode *tonode) if (!hasCycles) hasCycles = checkReachable(tonode, rmwnode); - if (rmwnode->addEdge(tonode)) + if (rmwnode->addEdge(tonode)) { rollbackvector.push_back(rmwnode); + added = true; + } } + return added; } /** @@ -274,23 +271,6 @@ void CycleGraph::dumpGraphToFile(const char *filename) const } #endif -/** - * Checks whether one ModelAction can reach another. - * @param from The ModelAction from which to begin exploration - * @param to The ModelAction to reach - * @return True, @a from can reach @a to; otherwise, false - */ -bool CycleGraph::checkReachable(const ModelAction *from, const ModelAction *to) const -{ - CycleNode *fromnode = actionToNode.get(from); - CycleNode *tonode = actionToNode.get(to); - - if (!fromnode || !tonode) - return false; - - return checkReachable(fromnode, tonode); -} - /** * Checks whether one CycleNode can reach another. * @param from The CycleNode from which to begin exploration @@ -321,6 +301,7 @@ bool CycleGraph::checkReachable(const CycleNode *from, const CycleNode *to) cons return false; } +/** @return True, if the promise has failed; false otherwise */ bool CycleGraph::checkPromise(const ModelAction *fromact, Promise *promise) const { std::vector< CycleNode *, ModelAlloc > queue; @@ -333,9 +314,9 @@ bool CycleGraph::checkPromise(const ModelAction *fromact, Promise *promise) cons CycleNode *node = queue.back(); queue.pop_back(); - if (promise->eliminate_thread(node->getAction()->get_tid())) { + if (!node->is_promise() && + promise->eliminate_thread(node->getAction()->get_tid())) return true; - } for (unsigned int i = 0; i < node->getNumEdges(); i++) { CycleNode *next = node->getEdge(i);