X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=cyclegraph.cc;h=7e5e95602408b47f5d4ff5b746e64db88287366f;hb=130a35155171503883aaf18e57f8957ce63d06e8;hp=8d37dea8b9fc6ea6770528e57238df13d2b5a323;hpb=5ea8e3d5d861ed363e5ac5f3b20b8181dd197efb;p=model-checker.git diff --git a/cyclegraph.cc b/cyclegraph.cc index 8d37dea..7e5e956 100644 --- a/cyclegraph.cc +++ b/cyclegraph.cc @@ -2,7 +2,6 @@ #include "action.h" #include "common.h" #include "promise.h" -#include "model.h" #include "threads-model.h" /** Initializes a CycleGraph object. */ @@ -198,29 +197,33 @@ bool CycleGraph::mergeNodes(CycleNode *w_node, CycleNode *p_node) */ bool CycleGraph::addNodeEdge(CycleNode *fromnode, CycleNode *tonode) { - bool added; - - if ((added = fromnode->addEdge(tonode))) { + if (fromnode->addEdge(tonode)) { rollbackvector.push_back(fromnode); if (!hasCycles) hasCycles = checkReachable(tonode, fromnode); - } + } else + return false; /* No new edge */ /* - * If the fromnode has a rmwnode that is not the tonode, we should add - * an edge between its rmwnode and the tonode + * If the fromnode has a rmwnode that is not the tonode, we should + * follow its RMW chain to add an edge at the end, unless we encounter + * tonode along the way */ CycleNode *rmwnode = fromnode->getRMW(); - if (rmwnode && rmwnode != tonode) { - if (rmwnode->addEdge(tonode)) { - if (!hasCycles) - hasCycles = checkReachable(tonode, rmwnode); + if (rmwnode) { + while (rmwnode != tonode && rmwnode->getRMW()) + rmwnode = rmwnode->getRMW(); + + if (rmwnode != tonode) { + if (rmwnode->addEdge(tonode)) { + if (!hasCycles) + hasCycles = checkReachable(tonode, rmwnode); - rollbackvector.push_back(rmwnode); - added = true; + rollbackvector.push_back(rmwnode); + } } } - return added; + return true; } /** @@ -228,8 +231,8 @@ bool CycleGraph::addNodeEdge(CycleNode *fromnode, CycleNode *tonode) * * Handles special case of a RMW action, where the ModelAction rmw reads from * 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. + * -# No write can occur in between the @a rmw and @a from actions. + * -# Only one RMW action can read from a given write. * * @param from The edge comes from this ModelAction/Promise * @param rmw The edge points to this ModelAction; this action must read from @@ -244,6 +247,9 @@ void CycleGraph::addRMWEdge(const T *from, const ModelAction *rmw) CycleNode *fromnode = getNode(from); CycleNode *rmwnode = getNode(rmw); + /* We assume that this RMW has no RMW reading from it yet */ + ASSERT(!rmwnode->getRMW()); + /* Two RMW actions cannot read from the same write. */ if (fromnode->setRMW(rmwnode)) hasCycles = true; @@ -307,12 +313,12 @@ static void print_node(FILE *file, const CycleNode *node, int label) { if (node->is_promise()) { const Promise *promise = node->getPromise(); - int idx = model->get_promise_number(promise); + int idx = promise->get_index(); fprintf(file, "P%u", idx); if (label) { int first = 1; fprintf(file, " [label=\"P%d, T", idx); - for (unsigned int i = 0 ; i < model->get_num_threads(); i++) + for (unsigned int i = 0 ; i < promise->max_available_thread_idx(); i++) if (promise->thread_is_available(int_to_id(i))) { fprintf(file, "%s%u", first ? "": ",", i); first = 0; @@ -465,6 +471,7 @@ bool CycleGraph::checkPromise(const ModelAction *fromact, Promise *promise) cons return false; } +/** @brief Begin a new sequence of graph additions which can be rolled back */ void CycleGraph::startChanges() { ASSERT(rollbackvector.empty()); @@ -524,7 +531,7 @@ CycleNode::CycleNode(const Promise *promise) : /** * @param i The index of the edge to return - * @returns The a CycleNode edge indexed by i + * @returns The CycleNode edge indexed by i */ CycleNode * CycleNode::getEdge(unsigned int i) const { @@ -537,11 +544,16 @@ unsigned int CycleNode::getNumEdges() const return edges.size(); } +/** + * @param i The index of the back edge to return + * @returns The CycleNode back-edge indexed by i + */ CycleNode * CycleNode::getBackEdge(unsigned int i) const { return back_edges[i]; } +/** @returns The number of edges entering this CycleNode */ unsigned int CycleNode::getNumBackEdges() const { return back_edges.size();