Eliminate annoying warning.
fromnode->addEdge(tonode);
}
+void CycleGraph::addRMWEdge(const ModelAction *from, const ModelAction *rmw) {
+ CycleNode *fromnode=getNode(from);
+ CycleNode *rmwnode=getNode(rmw);
+
+ /* Two RMW actions cannot read from the same write. */
+ if (fromnode->setRMW())
+ hasCycles=true;
+
+ /* 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.*/
+ std::vector<CycleNode *> * edges=fromnode->getEdges();
+ for(unsigned int i=0;edges->size();i++) {
+ CycleNode * tonode=(*edges)[i];
+ rmwnode->addEdge(tonode);
+ }
+ if (!hasCycles) {
+ hasCycles=checkReachable(rmwnode, fromnode);
+ }
+ fromnode->addEdge(rmwnode);
+}
+
+
/** Checks whether the first CycleNode can reach the second one. */
bool CycleGraph::checkReachable(CycleNode *from, CycleNode *to) {
std::vector<CycleNode *> queue;
void CycleNode::addEdge(CycleNode * node) {
edges.push_back(node);
}
+
+bool CycleNode::setRMW() {
+ bool oldhasRMW=hasRMW;
+ hasRMW=true;
+ return oldhasRMW;
+}
~CycleGraph();
void addEdge(const ModelAction *from, const ModelAction *to);
bool checkForCycles();
+ void addRMWEdge(const ModelAction *from, const ModelAction *to);
private:
CycleNode * getNode(const ModelAction *);
CycleNode(const ModelAction *action);
void addEdge(CycleNode * node);
std::vector<CycleNode *> * getEdges();
+ bool setRMW();
private:
const ModelAction *action;
std::vector<CycleNode *> edges;
+ bool hasRMW;
};
#endif
/** Process a RMW by converting previous read into a RMW. */
void ModelChecker::process_rmw(ModelAction * act) {
int tid = id_to_int(act->get_tid());
- std::vector<action_list_t> *vec = &(*obj_thrd_map)[act->get_location()];
- ASSERT(tid < (int) vec->size());
- ModelAction *lastread=(*vec)[tid].back();
+ ModelAction *lastread=get_last_action(tid);
lastread->upgrade_rmw(act);
+ cyclegraph->addRMWEdge(lastread->get_reads_from(),lastread);
}
/**
if (buf[0]=='\n')
break;
- sscanf(buf, "%22s %p-%p [%5dK] %c%c%c/%c%c%c SM=%3s %200s\n", &type, &begin, &end, &size, &r, &w, &x, &mr, &mw, &mx, smstr, regionname);
+ sscanf(buf, "%22s %p-%p [%5dK] %c%c%c/%c%c%c SM=%3s %200s\n", type, &begin, &end, &size, &r, &w, &x, &mr, &mw, &mx, smstr, regionname);
if (w == 'w' && (strstr(regionname, MYBINARYNAME) || strstr(regionname, MYLIBRARYNAME))) {
size_t len = ((uintptr_t)end - (uintptr_t)begin) / PAGESIZE;