model: flesh out set_backtracking()
[c11tester.git] / model.cc
1 #include <stdio.h>
2
3 #include "model.h"
4 #include "schedule.h"
5 #include "common.h"
6
7 ModelChecker *model;
8
9 ModelChecker::ModelChecker()
10 {
11         /* First thread created (system_thread) will have id 1 */
12         this->used_thread_id = 0;
13         /* Initialize default scheduler */
14         this->scheduler = new Scheduler();
15
16         this->current_action = NULL;
17
18         rootNode = new TreeNode(NULL);
19         currentNode = rootNode;
20 }
21
22 ModelChecker::~ModelChecker()
23 {
24         delete this->scheduler;
25         delete rootNode;
26 }
27
28 void ModelChecker::assign_id(Thread *t)
29 {
30         t->set_id(++used_thread_id);
31 }
32
33 void ModelChecker::add_system_thread(Thread *t)
34 {
35         this->system_thread = t;
36 }
37
38 void ModelChecker::set_backtracking(ModelAction *act)
39 {
40         ModelAction *prev;
41         TreeNode *node;
42
43         prev = get_last_conflict(act);
44         if (prev == NULL)
45                 return;
46
47         node = prev->get_node();
48
49         /* Check if this has been explored already */
50         if (node->hasBeenExplored(act->get_tid()))
51                 return;
52         /* If this is a new backtracking point, mark the tree */
53         if (node->setBacktrack(act->get_tid()) != 0)
54                 return;
55
56         printf("Setting backtrack: conflict = %d, instead tid = %d\n",
57                         prev->get_tid(), act->get_tid());
58         prev->print();
59         act->print();
60
61         /* FIXME */
62         //Backtrack *back = new Backtrack(prev, actionList);
63         //backtrackList->Append(back);
64 }
65
66 void ModelChecker::check_current_action(void)
67 {
68         ModelAction *next = this->current_action;
69
70         if (!next) {
71                 DEBUG("trying to push NULL action...\n");
72                 return;
73         }
74         next->set_node(currentNode);
75         set_backtracking(next);
76         currentNode = currentNode->exploreChild(next->get_tid());
77         this->action_trace.push_back(next);
78 }
79
80 void ModelChecker::print_trace(void)
81 {
82         std::list<class ModelAction *>::iterator it;
83
84         for (it = action_trace.begin(); it != action_trace.end(); it++) {
85                 DBG();
86                 (*it)->print();
87         }
88 }
89
90 int ModelChecker::add_thread(Thread *t)
91 {
92         thread_map[t->get_id()] = t;
93         return 0;
94 }
95
96 int ModelChecker::switch_to_master(ModelAction *act)
97 {
98         Thread *old, *next;
99
100         DBG();
101         old = thread_current();
102         set_current_action(act);
103         old->set_state(THREAD_READY);
104         next = system_thread;
105         return old->swap(next);
106 }
107
108 ModelAction::ModelAction(action_type_t type, memory_order order, void *loc, int value)
109 {
110         Thread *t = thread_current();
111         ModelAction *act = this;
112
113         act->type = type;
114         act->order = order;
115         act->location = loc;
116         act->tid = t->get_id();
117         act->value = value;
118 }
119
120 void ModelAction::print(void)
121 {
122         const char *type_str;
123         switch (this->type) {
124         case THREAD_CREATE:
125                 type_str = "thread create";
126                 break;
127         case THREAD_YIELD:
128                 type_str = "thread yield";
129                 break;
130         case THREAD_JOIN:
131                 type_str = "thread join";
132                 break;
133         case ATOMIC_READ:
134                 type_str = "atomic read";
135                 break;
136         case ATOMIC_WRITE:
137                 type_str = "atomic write";
138                 break;
139         default:
140                 type_str = "unknown type";
141         }
142
143         printf("Thread: %d\tAction: %s\tMO: %d\tLoc: %#014zx\tValue: %d\n", tid, type_str, order, (size_t)location, value);
144 }