9 #define INITIAL_THREAD_ID 0
13 void free_action_list(action_list_t *list)
15 action_list_t::iterator it;
16 for (it = list->begin(); it != list->end(); it++)
21 ModelChecker::ModelChecker()
23 /* Initialize default scheduler */
24 scheduler(new Scheduler()),
25 /* First thread created will have id INITIAL_THREAD_ID */
26 next_thread_id(INITIAL_THREAD_ID),
27 used_sequence_numbers(0),
32 nextThread(THREAD_ID_T_NONE),
33 action_trace(new action_list_t()),
34 node_stack(new NodeStack()),
39 ModelChecker::~ModelChecker()
41 std::map<int, class Thread *>::iterator it;
42 for (it = thread_map.begin(); it != thread_map.end(); it++)
52 void ModelChecker::reset_to_initial_state()
54 DEBUG("+++ Resetting to initial state +++\n");
55 std::map<int, class Thread *>::iterator it;
56 for (it = thread_map.begin(); it != thread_map.end(); it++)
60 action_trace = new action_list_t();
61 node_stack->reset_execution();
62 current_action = NULL;
63 next_thread_id = INITIAL_THREAD_ID;
64 used_sequence_numbers = 0;
66 next_backtrack = NULL;
67 /* scheduler reset ? */
70 thread_id_t ModelChecker::get_next_id()
72 return next_thread_id++;
75 int ModelChecker::get_next_seq_num()
77 return ++used_sequence_numbers;
80 Thread * ModelChecker::schedule_next_thread()
83 if (nextThread == THREAD_ID_T_NONE)
85 t = thread_map[id_to_int(nextThread)];
93 * get_next_replay_thread() - Choose the next thread in the replay sequence
95 * If we've reached the 'diverge' point, then we pick a thread from the
97 * Otherwise, we simply return the next thread in the sequence.
99 thread_id_t ModelChecker::get_next_replay_thread()
104 /* Have we completed exploring the preselected path? */
106 return THREAD_ID_T_NONE;
108 /* Else, we are trying to replay an execution */
109 next = node_stack->get_next()->get_action();
111 if (next == diverge) {
112 Node *node = next->get_node();
114 /* Reached divergence point */
115 DEBUG("*** Divergence point ***\n");
116 tid = node->get_next_backtrack();
119 tid = next->get_tid();
121 DEBUG("*** ModelChecker chose next thread = %d ***\n", tid);
125 bool ModelChecker::next_execution()
131 if ((diverge = model->get_next_backtrack()) == NULL)
135 printf("Next execution will diverge at:\n");
139 model->reset_to_initial_state();
143 ModelAction * ModelChecker::get_last_conflict(ModelAction *act)
145 action_type type = act->get_type();
157 /* linear search: from most recent to oldest */
158 action_list_t::reverse_iterator rit;
159 for (rit = action_trace->rbegin(); rit != action_trace->rend(); rit++) {
160 ModelAction *prev = *rit;
161 if (act->is_dependent(prev))
167 void ModelChecker::set_backtracking(ModelAction *act)
171 Thread *t = get_thread(act->get_tid());
173 prev = get_last_conflict(act);
177 node = prev->get_node();
179 while (!node->is_enabled(t))
182 /* Check if this has been explored already */
183 if (node->has_been_explored(t->get_id()))
186 if (!next_backtrack || *prev > *next_backtrack)
187 next_backtrack = prev;
189 /* If this is a new backtracking point, mark the tree */
190 if (!node->set_backtrack(t->get_id()))
192 DEBUG("Setting backtrack: conflict = %d, instead tid = %d\n",
193 prev->get_tid(), t->get_id());
200 ModelAction * ModelChecker::get_next_backtrack()
202 ModelAction *next = next_backtrack;
203 next_backtrack = NULL;
207 void ModelChecker::check_current_action(void)
211 ModelAction *curr = this->current_action;
212 current_action = NULL;
214 DEBUG("trying to push NULL action...\n");
218 curr = node_stack->explore_action(curr);
219 nextThread = get_next_replay_thread();
221 currnode = curr->get_node();
223 if (!currnode->backtrack_empty())
224 if (!next_backtrack || *curr > *next_backtrack)
225 next_backtrack = curr;
227 set_backtracking(curr);
228 this->action_trace->push_back(curr);
231 void ModelChecker::print_summary(void)
234 printf("Number of executions: %d\n", num_executions);
235 printf("Total nodes created: %d\n", Node::get_total_nodes());
239 print_list(action_trace);
243 void ModelChecker::print_list(action_list_t *list)
245 action_list_t::iterator it;
247 printf("---------------------------------------------------------------------\n");
250 for (it = list->begin(); it != list->end(); it++) {
253 printf("---------------------------------------------------------------------\n");
256 int ModelChecker::add_thread(Thread *t)
258 thread_map[id_to_int(t->get_id())] = t;
259 scheduler->add_thread(t);
263 void ModelChecker::remove_thread(Thread *t)
265 scheduler->remove_thread(t);
268 int ModelChecker::switch_to_master(ModelAction *act)
273 old = thread_current();
274 set_current_action(act);
275 old->set_state(THREAD_READY);
276 return Thread::swap(old, get_system_context());