X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=cyclegraph.cc;h=8f095dc580afa72ab0f48756b29df97e092d6749;hb=63e202b2db7a90e176db54c864d2e54ec535c03f;hp=e834cb672b5a360077c9cb877ea164a986880acb;hpb=d7e26717ec76b225475afe69a463b6e21e026f26;p=model-checker.git diff --git a/cyclegraph.cc b/cyclegraph.cc index e834cb6..8f095dc 100644 --- a/cyclegraph.cc +++ b/cyclegraph.cc @@ -118,12 +118,18 @@ bool CycleGraph::mergeNodes(CycleNode *w_node, CycleNode *p_node, { ASSERT(!w_node->is_promise()); ASSERT(p_node->is_promise()); + const Promise *promise = p_node->getPromise(); if (!promise->is_compatible(w_node->getAction())) { hasCycles = true; return false; } + /* Transfer the RMW */ + CycleNode *promise_rmw = p_node->getRMW(); + if (promise_rmw && promise_rmw != w_node->getRMW() && w_node->setRMW(promise_rmw)) + hasCycles = true; + /* Transfer back edges to w_node */ while (p_node->getNumBackEdges() > 0) { CycleNode *back = p_node->removeBackEdge(); @@ -201,15 +207,16 @@ bool CycleGraph::addNodeEdge(CycleNode *fromnode, CycleNode *tonode) * @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: + * the ModelAction/Promise 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 from The edge comes from this ModelAction/Promise * @param rmw The edge points to this ModelAction; this action must read from - * ModelAction from + * the ModelAction/Promise from */ -void CycleGraph::addRMWEdge(const ModelAction *from, const ModelAction *rmw) +template +void CycleGraph::addRMWEdge(const T *from, const ModelAction *rmw) { ASSERT(from); ASSERT(rmw); @@ -240,6 +247,38 @@ void CycleGraph::addRMWEdge(const ModelAction *from, const ModelAction *rmw) addNodeEdge(fromnode, rmwnode); } +/* Instantiate two forms of CycleGraph::addRMWEdge */ +template void CycleGraph::addRMWEdge(const ModelAction *from, const ModelAction *rmw); +template void CycleGraph::addRMWEdge(const Promise *from, const ModelAction *rmw); + +/** + * @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 + * @return True, if new edge(s) are added; otherwise false + */ +template +bool CycleGraph::addEdge(const T *from, const U *to) +{ + ASSERT(from); + ASSERT(to); + + CycleNode *fromnode = getNode(from); + CycleNode *tonode = getNode(to); + + return addNodeEdge(fromnode, tonode); +} +/* Instantiate three forms of CycleGraph::addEdge */ +template bool CycleGraph::addEdge(const ModelAction *from, const ModelAction *to); +template bool CycleGraph::addEdge(const ModelAction *from, const Promise *to); +template bool CycleGraph::addEdge(const Promise *from, const ModelAction *to); #if SUPPORT_MOD_ORDER_DUMP void CycleGraph::dumpNodes(FILE *file) const @@ -301,6 +340,29 @@ bool CycleGraph::checkReachable(const CycleNode *from, const CycleNode *to) cons return false; } +/** + * Checks whether one ModelAction can reach another ModelAction/Promise + * @param from The ModelAction from which to begin exploration + * @param to The ModelAction or Promise to reach + * @return True, @a from can reach @a to; otherwise, false + */ +template +bool CycleGraph::checkReachable(const ModelAction *from, const T *to) const +{ + CycleNode *fromnode = getNode_noCreate(from); + CycleNode *tonode = getNode_noCreate(to); + + if (!fromnode || !tonode) + return false; + + return checkReachable(fromnode, tonode); +} +/* Instantiate two forms of CycleGraph::checkReachable */ +template bool CycleGraph::checkReachable(const ModelAction *from, + const ModelAction *to) const; +template bool CycleGraph::checkReachable(const ModelAction *from, + const Promise *to) const; + /** @return True, if the promise has failed; false otherwise */ bool CycleGraph::checkPromise(const ModelAction *fromact, Promise *promise) const {