#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);
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);
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 <typename T, typename U>
-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
*/
* 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);
/*
if (!hasCycles)
hasCycles = checkReachable(tonode, rmwnode);
- if (rmwnode->addEdge(tonode))
+ if (rmwnode->addEdge(tonode)) {
rollbackvector.push_back(rmwnode);
+ added = true;
+ }
}
+ return added;
}
/**
}
#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
return false;
}
+/** @return True, if the promise has failed; false otherwise */
bool CycleGraph::checkPromise(const ModelAction *fromact, Promise *promise) const
{
std::vector< CycleNode *, ModelAlloc<CycleNode *> > queue;
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);