Untested, but ported from Nachos project.
CC=g++
BIN=model
-SOURCE=libthreads.cc schedule.cc libatomic.cc userprog.c model.cc malloc.c threads.cc
-HEADERS=libthreads.h schedule.h common.h libatomic.h model.h threads.h
+SOURCE=libthreads.cc schedule.cc libatomic.cc userprog.c model.cc malloc.c threads.cc tree.cc
+HEADERS=libthreads.h schedule.h common.h libatomic.h model.h threads.h tree.h
FLAGS=-Wall -ldl -g
all: ${BIN}
--- /dev/null
+#include "tree.h"
+
+int TreeNode::totalNodes = 0;
+
+TreeNode::TreeNode(TreeNode *par)
+{
+ TreeNode::totalNodes++;
+ this->parent = par;
+}
+
+TreeNode::~TreeNode() {
+ std::map<tree_t, class TreeNode *>::iterator it;
+
+ for (it = children.begin(); it != children.end(); it++)
+ delete it->second;
+ delete &children;
+}
+
+TreeNode *TreeNode::exploreChild(tree_t id)
+{
+ TreeNode *n;
+ std::set<tree_t >::iterator it;
+
+ if (!hasBeenExplored(id)) {
+ n = new TreeNode(this);
+ children[id] = n;
+ } else {
+ n = children[id];
+ }
+ if ((it = backtrack.find(id)) != backtrack.end())
+ backtrack.erase(it);
+
+ return n;
+}
+
+int TreeNode::setBacktrack(tree_t id)
+{
+ if (backtrack.find(id) == backtrack.end())
+ return 1;
+ backtrack.insert(id);
+ return 0;
+}
+
+tree_t TreeNode::getNextBacktrack()
+{
+ if (backtrack.empty())
+ return NULL;
+ return *backtrack.begin();
+}
+
+TreeNode *TreeNode::getRoot()
+{
+ if (parent)
+ return parent->getRoot();
+ return this;
+}
--- /dev/null
+#include <set>
+#include <map>
+#include "threads.h"
+
+typedef thread_id_t tree_t;
+
+/*
+ * An n-ary tree
+ *
+ * A tree with n possible branches from each node - used for recording the
+ * execution paths we've executed / backtracked
+ */
+class TreeNode {
+public:
+ TreeNode(TreeNode *par);
+ ~TreeNode();
+ bool hasBeenExplored(tree_t id) { return children.find(id) != children.end(); }
+ TreeNode *exploreChild(tree_t id);
+ tree_t getNextBacktrack();
+
+ /* Return 1 if already in backtrack, 0 otherwise */
+ int setBacktrack(tree_t id);
+ TreeNode *getRoot();
+ static int getTotalNodes() { return TreeNode::totalNodes; }
+private:
+ TreeNode *parent;
+ std::map<tree_t, class TreeNode *> children;
+ std::set<tree_t> backtrack;
+ static int totalNodes;
+};