cyclegraph.h
ecba3e55
 /**
  * @file cyclegraph.h
  * @brief Data structure to track ordering constraints on modification order
  *
  * Used to determine whether a total order exists that satisfies the ordering
  * constraints.
  */
20926923
 
ecba3e55
 #ifndef __CYCLEGRAPH_H__
 #define __CYCLEGRAPH_H__
f7e1577b
 
c3292c33
 #include <inttypes.h>
e0f80c40
 #include <stdio.h>
 
 #include "hashtable.h"
e309adae
 #include "config.h"
04f478b2
 #include "mymemory.h"
5ea8e3d5
 #include "stl-model.h"
04f478b2
 
c832cb55
 class Promise;
f7e1577b
 class CycleNode;
1667e1f8
 class ModelAction;
f7e1577b
 
 /** @brief A graph of Model Actions for tracking cycles. */
 class CycleGraph {
  public:
 	CycleGraph();
0c0b705a
 	~CycleGraph();
07aa7baf
 
 	template <typename T, typename U>
fbacb5f4
 	bool addEdge(const T *from, const U *to);
07aa7baf
 
5d0c8be1
 	template <typename T>
 	void addRMWEdge(const T *from, const ModelAction *rmw);
 
ecba3e55
 	bool checkForCycles() const;
 	bool checkPromise(const ModelAction *from, Promise *p) const;
776fc720
 
5236e7a4
 	template <typename T, typename U>
 	bool checkReachable(const T *from, const U *to) const;
776fc720
 
a0562e07
 	void startChanges();
85747199
 	void commitChanges();
 	void rollbackChanges();
e309adae
 #if SUPPORT_MOD_ORDER_DUMP
ecba3e55
 	void dumpNodes(FILE *file) const;
 	void dumpGraphToFile(const char *filename) const;
e0f80c40
 
 	void dot_print_node(FILE *file, const ModelAction *act);
 	template <typename T, typename U>
 	void dot_print_edge(FILE *file, const T *from, const U *to, const char *prop);
e309adae
 #endif
d3f14b49
 
438b20cf
 	bool resolvePromise(const Promise *promise, ModelAction *writer);
d3dffe99
 
04f478b2
 	SNAPSHOTALLOC
f7e1577b
  private:
62dbff8d
 	bool addNodeEdge(CycleNode *fromnode, CycleNode *tonode);
023ee9d1
 	void putNode(const ModelAction *act, CycleNode *node);
f912ca72
 	void putNode(const Promise *promise, CycleNode *node);
 	void erasePromiseNode(const Promise *promise);
482c7447
 	CycleNode * getNode(const ModelAction *act);
84d49e8d
 	CycleNode * getNode(const Promise *promise);
482c7447
 	CycleNode * getNode_noCreate(const ModelAction *act) const;
 	CycleNode * getNode_noCreate(const Promise *promise) const;
438b20cf
 	bool mergeNodes(CycleNode *node1, CycleNode *node2);
84d49e8d
 
ecf4c35d
 	HashTable<const CycleNode *, const CycleNode *, uintptr_t, 4, model_malloc, model_calloc, model_free> *discovered;
5ea8e3d5
 	ModelVector<const CycleNode *> * queue;
0dc4895e
 
6c42e6f6
 
 	/** @brief A table for mapping ModelActions to CycleNodes */
0c0b705a
 	HashTable<const ModelAction *, CycleNode *, uintptr_t, 4> actionToNode;
3510b440
 	/** @brief A table for mapping Promises to CycleNodes */
 	HashTable<const Promise *, CycleNode *, uintptr_t, 4> promiseToNode;
84d49e8d
 
e309adae
 #if SUPPORT_MOD_ORDER_DUMP
5ea8e3d5
 	SnapVector<CycleNode *> nodeList;
e309adae
 #endif
6c42e6f6
 
ecf4c35d
 	bool checkReachable(const CycleNode *from, const CycleNode *to) const;
6c42e6f6
 
 	/** @brief A flag: true if this graph contains cycles */
f7e1577b
 	bool hasCycles;
4fa31aac
 	/** @brief The previous value of CycleGraph::hasCycles, for rollback */
85747199
 	bool oldCycles;
 
5ea8e3d5
 	SnapVector<CycleNode *> rollbackvector;
 	SnapVector<CycleNode *> rmwrollbackvector;
f7e1577b
 };
 
29f99ad8
 /**
  * @brief A node within a CycleGraph; corresponds either to one ModelAction or
  * to a promised future value
  */
f7e1577b
 class CycleNode {
  public:
ecba3e55
 	CycleNode(const ModelAction *act);
29f99ad8
 	CycleNode(const Promise *promise);
fc326119
 	bool addEdge(CycleNode *node);
2144dfc0
 	CycleNode * getEdge(unsigned int i) const;
 	unsigned int getNumEdges() const;
6152f84e
 	CycleNode * getBackEdge(unsigned int i) const;
 	unsigned int getNumBackEdges() const;
eb07120d
 	CycleNode * removeEdge();
 	CycleNode * removeBackEdge();
 
247e28f8
 	bool setRMW(CycleNode *);
fc326119
 	CycleNode * getRMW() const;
ca060d27
 	void clearRMW() { hasRMW = NULL; }
fc326119
 	const ModelAction * getAction() const { return action; }
5467ad92
 	const Promise * getPromise() const { return promise; }
29f99ad8
 	bool is_promise() const { return !action; }
5467ad92
 	void resolvePromise(const ModelAction *writer);
29f99ad8
 
04f478b2
 	SNAPSHOTALLOC
f7e1577b
  private:
6c42e6f6
 	/** @brief The ModelAction that this node represents */
0c0b705a
 	const ModelAction *action;
6c42e6f6
 
29f99ad8
 	/** @brief The promise represented by this node; only valid when action
 	 * is NULL */
 	const Promise *promise;
 
6c42e6f6
 	/** @brief The edges leading out from this node */
5ea8e3d5
 	SnapVector<CycleNode *> edges;
6c42e6f6
 
6152f84e
 	/** @brief The edges leading into this node */
5ea8e3d5
 	SnapVector<CycleNode *> back_edges;
6152f84e
 
6c42e6f6
 	/** Pointer to a RMW node that reads from this node, or NULL, if none
 	 * exists */
fc326119
 	CycleNode *hasRMW;
f7e1577b
 };
 
ecba3e55
 #endif /* __CYCLEGRAPH_H__ */