libthreads: thrd_join() always return 0
[c11tester.git] / cyclegraph.cc
1 #include "cyclegraph.h"
2 #include "action.h"
3
4 /** Initializes a CycleGraph object. */
5 CycleGraph::CycleGraph() {
6         hasCycles=false;
7 }
8
9 /** Returns the CycleNode for a given ModelAction. */
10 CycleNode * CycleGraph::getNode(ModelAction * action) {
11         CycleNode *node=actionToNode.get(action);
12         if (node==NULL) {
13                 node=new CycleNode(action);
14                 actionToNode.put(action, node);
15         }
16         return node;
17 }
18
19 /** Adds an edge between two ModelActions. */
20 void CycleGraph::addEdge(ModelAction *from, ModelAction *to) {
21         CycleNode *fromnode=getNode(from);
22         CycleNode *tonode=getNode(to);
23         if (!hasCycles) {
24                 // Check for Cycles
25                 hasCycles=checkReachable(fromnode, tonode);
26         }
27         fromnode->addEdge(tonode);
28 }
29
30 /** Checks whether the first CycleNode can reach the second one. */
31 bool CycleGraph::checkReachable(CycleNode *from, CycleNode *to) {
32         std::vector<CycleNode *> queue;
33         HashTable<CycleNode *, CycleNode *, uintptr_t, 4> discovered;
34
35         queue.push_back(from);
36         discovered.put(from, from);
37         while(!queue.empty()) {
38                 CycleNode * node=queue.back();
39                 queue.pop_back();
40                 if (node==to)
41                         return true;
42
43                 for(unsigned int i=0;i<node->getEdges()->size();i++) {
44                         CycleNode *next=(*node->getEdges())[i];
45                         if (!discovered.contains(next)) {
46                                 discovered.put(next,next);
47                                 queue.push_back(next);
48                         }
49                 }
50         }
51         return false;
52 }
53
54 /** Returns whether a CycleGraph contains cycles. */
55 bool CycleGraph::checkForCycles() {
56         return hasCycles;
57 }
58
59 /** Constructor for a CycleNode. */
60 CycleNode::CycleNode(ModelAction *modelaction) {
61         action=modelaction;
62 }
63
64 /** Returns a vector of the edges from a CycleNode. */
65 std::vector<CycleNode *> * CycleNode::getEdges() {
66         return &edges;
67 }
68
69 /** Adds an edge to a CycleNode. */
70 void CycleNode::addEdge(CycleNode * node) {
71         edges.push_back(node);
72 }