From: Brian Demsky Date: Fri, 14 Sep 2012 05:04:45 +0000 (-0700) Subject: add support for dumping cyclegraphs as dot files... also eliminate redundant edges... X-Git-Url: http://plrg.eecs.uci.edu/git/?p=c11tester.git;a=commitdiff_plain;h=e309adaee27786a638bcd44303ecb88351074257 add support for dumping cyclegraphs as dot files... also eliminate redundant edges to make them easier to view --- diff --git a/config.h b/config.h index 1d0b6380..ab54e3ab 100644 --- a/config.h +++ b/config.h @@ -11,6 +11,9 @@ #endif */ +/** Turn on support for dumping cyclegraphs as dot files at each + * printed summary.*/ +#define SUPPORT_MOD_ORDER_DUMP 0 /** Do we have a 48 bit virtual address (64 bit machine) or 32 bit addresses. * Set to 1 for 48-bit, 0 for 32-bit. */ diff --git a/cyclegraph.cc b/cyclegraph.cc index 26235d65..c7bb69b9 100644 --- a/cyclegraph.cc +++ b/cyclegraph.cc @@ -25,6 +25,9 @@ CycleNode * CycleGraph::getNode(const ModelAction *action) { if (node==NULL) { node=new CycleNode(action); actionToNode.put(action, node); +#if SUPPORT_MOD_ORDER_DUMP + nodeList.push_back(node); +#endif } return node; } @@ -47,8 +50,9 @@ void CycleGraph::addEdge(const ModelAction *from, const ModelAction *to) { hasCycles=checkReachable(tonode, fromnode); } - rollbackvector.push_back(fromnode); - fromnode->addEdge(tonode); + if (fromnode->addEdge(tonode)) + rollbackvector.push_back(fromnode); + CycleNode * rmwnode=fromnode->getRMW(); @@ -64,8 +68,9 @@ void CycleGraph::addEdge(const ModelAction *from, const ModelAction *to) { // Check for Cycles hasCycles=checkReachable(tonode, rmwnode); } - rollbackvector.push_back(rmwnode); - rmwnode->addEdge(tonode); + + if (rmwnode->addEdge(tonode)) + rollbackvector.push_back(rmwnode); } } @@ -99,19 +104,42 @@ void CycleGraph::addRMWEdge(const ModelAction *from, const ModelAction *rmw) { for(unsigned int i=0;isize();i++) { CycleNode * tonode=(*edges)[i]; if (tonode!=rmwnode) { - rollbackvector.push_back(rmwnode); - rmwnode->addEdge(tonode); + if (rmwnode->addEdge(tonode)) + rollbackvector.push_back(rmwnode); } } - 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); + if(fromnode->addEdge(rmwnode)) + rollbackvector.push_back(fromnode); +} + +#if SUPPORT_MOD_ORDER_DUMP +void CycleGraph::dumpGraphToFile(const char *filename) { + char buffer[200]; + sprintf(buffer, "%s.dot",filename); + FILE *file=fopen(buffer, "w"); + fprintf(file, "digraph %s {\n",filename); + for(unsigned int i=0;i * edges=cn->getEdges(); + const ModelAction *action=cn->getAction(); + fprintf(file, "N%u [label=\"%u, T%u\"];\n",action->get_seq_number(),action->get_seq_number(), action->get_tid()); + for(unsigned int j=0;jsize();j++) { + CycleNode *dst=(*edges)[j]; + const ModelAction *dstaction=dst->getAction(); + fprintf(file, "N%u -> N%u;\n", action->get_seq_number(), dstaction->get_seq_number()); + } + } + fprintf(file,"}\n"); + fclose(file); } +#endif /** * Checks whether one ModelAction can reach another. @@ -136,8 +164,8 @@ bool CycleGraph::checkReachable(const ModelAction *from, const ModelAction *to) * @return True, @a from can reach @a to; otherwise, false */ bool CycleGraph::checkReachable(CycleNode *from, CycleNode *to) { - std::vector queue; - HashTable discovered; + std::vector > queue; + HashTable discovered; queue.push_back(from); discovered.put(from, from); @@ -217,8 +245,12 @@ std::vector * CycleNode::getEdges() { * Adds an edge from this CycleNode to another CycleNode. * @param node The node to which we add a directed edge */ -void CycleNode::addEdge(CycleNode *node) { +bool CycleNode::addEdge(CycleNode *node) { + for(unsigned int i=0;i #include - +#include "config.h" #include "mymemory.h" class CycleNode; @@ -28,6 +28,9 @@ class CycleGraph { void startChanges(); void commitChanges(); void rollbackChanges(); +#if SUPPORT_MOD_ORDER_DUMP + void dumpGraphToFile(const char * filename); +#endif SNAPSHOTALLOC private: @@ -35,6 +38,9 @@ class CycleGraph { /** @brief A table for mapping ModelActions to CycleNodes */ HashTable actionToNode; +#if SUPPORT_MOD_ORDER_DUMP + std::vector nodeList; +#endif bool checkReachable(CycleNode *from, CycleNode *to); @@ -53,10 +59,12 @@ class CycleGraph { class CycleNode { public: CycleNode(const ModelAction *action); - void addEdge(CycleNode * node); + bool addEdge(CycleNode * node); std::vector * getEdges(); bool setRMW(CycleNode *); CycleNode* getRMW(); + const ModelAction * getAction() {return action;}; + void popEdge() { edges.pop_back(); }; diff --git a/model.cc b/model.cc index 031f6a93..1712a60a 100644 --- a/model.cc +++ b/model.cc @@ -1184,7 +1184,12 @@ void ModelChecker::print_summary() printf("Number of executions: %d\n", num_executions); printf("Total nodes created: %d\n", node_stack->get_total_nodes()); +#if SUPPORT_MOD_ORDER_DUMP scheduler->print(); + char buffername[100]; + sprintf(buffername, "exec%u",num_executions); + mo_graph->dumpGraphToFile(buffername); +#endif if (!isfinalfeasible()) printf("INFEASIBLE EXECUTION!\n"); diff --git a/test/rmwprog.c b/test/rmwprog.c index 14929ee2..c3a5ea82 100644 --- a/test/rmwprog.c +++ b/test/rmwprog.c @@ -17,7 +17,6 @@ void user_main() thrd_t t1, t2; atomic_init(&x, 0); - thrd_create(&t1, (thrd_start_t)&a, NULL); thrd_create(&t2, (thrd_start_t)&a, NULL);