}
/* Transfer all outgoing edges from the from node to the rmw node */
- /* This process cannot add a cycle because rmw should not have any
- incoming edges yet.*/
+ /* This process should not add a cycle because either:
+ * (1) The rmw should not have any incoming edges yet if it is the
+ * new node or
+ * (2) the fromnode is the new node and therefore it should not
+ * have any outgoing edges.
+ */
std::vector<CycleNode *> * edges=fromnode->getEdges();
for(unsigned int i=0;i<edges->size();i++) {
CycleNode * tonode=(*edges)[i];
rmwnode->addEdge(tonode);
}
rollbackvector.push_back(fromnode);
+
+ if (!hasCycles) {
+ // With promises we could be setting up a cycle here if we aren't
+ // careful...avoid it..
+ hasCycles=checkReachable(rmwnode, fromnode);
+ }
fromnode->addEdge(rmwnode);
}
mo_graph(new CycleGraph()),
failed_promise(false),
too_many_reads(false),
- asserted(false),
- rmw_cycle(false)
+ asserted(false)
{
/* Allocate this "size" on the snapshotting heap */
priv = (struct model_snapshot_members *)calloc(1, sizeof(*priv));
node_stack->reset_execution();
failed_promise = false;
too_many_reads = false;
- rmw_cycle=false;
reset_asserted();
snapshotObject->backTrackBeforeStep(0);
}
}
-/** Checks whether making the ModelAction read read_from the
- ModelAction write will introduce a cycle in the reads_from
- relation.
-
-@return true if making it read from will be fine, false otherwise.
-
-*/
-
-bool ModelChecker::ensure_rmw_acyclic(const ModelAction * read, const ModelAction *write) {
- if (!read->is_rmw())
- return true;
- if (!write->is_rmw())
- return true;
- while(write!=NULL) {
- if (write==read) {
- rmw_cycle=true;
- return false;
- }
- write=write->get_reads_from();
- }
- return true;
-}
-
/**
* Processes a read or rmw model action.
* @param curr is the read model action to process.
mo_graph->startChanges();
value = reads_from->get_value();
- /* Assign reads_from, perform release/acquire synchronization */
- if (ensure_rmw_acyclic(curr, reads_from))
- curr->read_from(reads_from);
+
if (!second_part_of_rmw) {
check_recency(curr,false);
}
continue;
}
+ curr->read_from(reads_from);
mo_graph->commitChanges();
updated |= r_status;
} else if (!second_part_of_rmw) {
/** @returns whether the current partial trace is feasible other than
* multiple RMW reading from the same store. */
bool ModelChecker::isfeasibleotherthanRMW() {
- return !mo_graph->checkForCycles() && !failed_promise && !too_many_reads && !rmw_cycle && !promises_expired();
+ return !mo_graph->checkForCycles() && !failed_promise && !too_many_reads && !promises_expired();
}
/** Returns whether the current completed trace is feasible. */
Promise *promise = (*promises)[promise_index];
if (write->get_node()->get_promise(i)) {
ModelAction *read = promise->get_action();
- if (ensure_rmw_acyclic(read, write))
- read->read_from(write);
+ read->read_from(write);
if (read->is_rmw()) {
mo_graph->addRMWEdge(write, read);
}