model: use helper 'get_thread()'
[c11tester.git] / model.cc
1 #include <stdio.h>
2 #include <algorithm>
3 #include <mutex>
4 #include <new>
5
6 #include "model.h"
7 #include "action.h"
8 #include "nodestack.h"
9 #include "schedule.h"
10 #include "snapshot-interface.h"
11 #include "common.h"
12 #include "clockvector.h"
13 #include "cyclegraph.h"
14 #include "promise.h"
15 #include "datarace.h"
16 #include "threads-model.h"
17 #include "output.h"
18
19 #define INITIAL_THREAD_ID       0
20
21 ModelChecker *model;
22
23 struct bug_message {
24         bug_message(const char *str) {
25                 const char *fmt = "  [BUG] %s\n";
26                 msg = (char *)snapshot_malloc(strlen(fmt) + strlen(str));
27                 sprintf(msg, fmt, str);
28         }
29         ~bug_message() { if (msg) snapshot_free(msg); }
30
31         char *msg;
32         void print() { model_print("%s", msg); }
33
34         SNAPSHOTALLOC
35 };
36
37 /**
38  * Structure for holding small ModelChecker members that should be snapshotted
39  */
40 struct model_snapshot_members {
41         model_snapshot_members() :
42                 current_action(NULL),
43                 /* First thread created will have id INITIAL_THREAD_ID */
44                 next_thread_id(INITIAL_THREAD_ID),
45                 used_sequence_numbers(0),
46                 next_backtrack(NULL),
47                 bugs(),
48                 stats(),
49                 failed_promise(false),
50                 too_many_reads(false),
51                 bad_synchronization(false),
52                 asserted(false)
53         { }
54
55         ~model_snapshot_members() {
56                 for (unsigned int i = 0; i < bugs.size(); i++)
57                         delete bugs[i];
58                 bugs.clear();
59         }
60
61         ModelAction *current_action;
62         unsigned int next_thread_id;
63         modelclock_t used_sequence_numbers;
64         ModelAction *next_backtrack;
65         std::vector< bug_message *, SnapshotAlloc<bug_message *> > bugs;
66         struct execution_stats stats;
67         bool failed_promise;
68         bool too_many_reads;
69         /** @brief Incorrectly-ordered synchronization was made */
70         bool bad_synchronization;
71         bool asserted;
72
73         SNAPSHOTALLOC
74 };
75
76 /** @brief Constructor */
77 ModelChecker::ModelChecker(struct model_params params) :
78         /* Initialize default scheduler */
79         params(params),
80         scheduler(new Scheduler()),
81         diverge(NULL),
82         earliest_diverge(NULL),
83         action_trace(new action_list_t()),
84         thread_map(new HashTable<int, Thread *, int>()),
85         obj_map(new HashTable<const void *, action_list_t *, uintptr_t, 4>()),
86         lock_waiters_map(new HashTable<const void *, action_list_t *, uintptr_t, 4>()),
87         condvar_waiters_map(new HashTable<const void *, action_list_t *, uintptr_t, 4>()),
88         obj_thrd_map(new HashTable<void *, std::vector<action_list_t> *, uintptr_t, 4 >()),
89         promises(new std::vector< Promise *, SnapshotAlloc<Promise *> >()),
90         futurevalues(new std::vector< struct PendingFutureValue, SnapshotAlloc<struct PendingFutureValue> >()),
91         pending_rel_seqs(new std::vector< struct release_seq *, SnapshotAlloc<struct release_seq *> >()),
92         thrd_last_action(new std::vector< ModelAction *, SnapshotAlloc<ModelAction *> >(1)),
93         thrd_last_fence_release(new std::vector< ModelAction *, SnapshotAlloc<ModelAction *> >()),
94         node_stack(new NodeStack()),
95         priv(new struct model_snapshot_members()),
96         mo_graph(new CycleGraph())
97 {
98         /* Initialize a model-checker thread, for special ModelActions */
99         model_thread = new Thread(get_next_id());
100         thread_map->put(id_to_int(model_thread->get_id()), model_thread);
101 }
102
103 /** @brief Destructor */
104 ModelChecker::~ModelChecker()
105 {
106         for (unsigned int i = 0; i < get_num_threads(); i++)
107                 delete thread_map->get(i);
108         delete thread_map;
109
110         delete obj_thrd_map;
111         delete obj_map;
112         delete lock_waiters_map;
113         delete condvar_waiters_map;
114         delete action_trace;
115
116         for (unsigned int i = 0; i < promises->size(); i++)
117                 delete (*promises)[i];
118         delete promises;
119
120         delete pending_rel_seqs;
121
122         delete thrd_last_action;
123         delete thrd_last_fence_release;
124         delete node_stack;
125         delete scheduler;
126         delete mo_graph;
127         delete priv;
128 }
129
130 static action_list_t * get_safe_ptr_action(HashTable<const void *, action_list_t *, uintptr_t, 4> * hash, void * ptr)
131 {
132         action_list_t *tmp = hash->get(ptr);
133         if (tmp == NULL) {
134                 tmp = new action_list_t();
135                 hash->put(ptr, tmp);
136         }
137         return tmp;
138 }
139
140 static std::vector<action_list_t> * get_safe_ptr_vect_action(HashTable<void *, std::vector<action_list_t> *, uintptr_t, 4> * hash, void * ptr)
141 {
142         std::vector<action_list_t> *tmp = hash->get(ptr);
143         if (tmp == NULL) {
144                 tmp = new std::vector<action_list_t>();
145                 hash->put(ptr, tmp);
146         }
147         return tmp;
148 }
149
150 /**
151  * Restores user program to initial state and resets all model-checker data
152  * structures.
153  */
154 void ModelChecker::reset_to_initial_state()
155 {
156         DEBUG("+++ Resetting to initial state +++\n");
157         node_stack->reset_execution();
158
159         /* Print all model-checker output before rollback */
160         fflush(model_out);
161
162         snapshotObject->backTrackBeforeStep(0);
163 }
164
165 /** @return a thread ID for a new Thread */
166 thread_id_t ModelChecker::get_next_id()
167 {
168         return priv->next_thread_id++;
169 }
170
171 /** @return the number of user threads created during this execution */
172 unsigned int ModelChecker::get_num_threads() const
173 {
174         return priv->next_thread_id;
175 }
176
177 /** @return The currently executing Thread. */
178 Thread * ModelChecker::get_current_thread() const
179 {
180         return scheduler->get_current_thread();
181 }
182
183 /** @return a sequence number for a new ModelAction */
184 modelclock_t ModelChecker::get_next_seq_num()
185 {
186         return ++priv->used_sequence_numbers;
187 }
188
189 Node * ModelChecker::get_curr_node() const
190 {
191         return node_stack->get_head();
192 }
193
194 /**
195  * @brief Choose the next thread to execute.
196  *
197  * This function chooses the next thread that should execute. It can force the
198  * adjacency of read/write portions of a RMW action, force THREAD_CREATE to be
199  * followed by a THREAD_START, or it can enforce execution replay/backtracking.
200  * The model-checker may have no preference regarding the next thread (i.e.,
201  * when exploring a new execution ordering), in which case this will return
202  * NULL.
203  * @param curr The current ModelAction. This action might guide the choice of
204  * next thread.
205  * @return The next thread to run. If the model-checker has no preference, NULL.
206  */
207 Thread * ModelChecker::get_next_thread(ModelAction *curr)
208 {
209         thread_id_t tid;
210
211         if (curr != NULL) {
212                 /* Do not split atomic actions. */
213                 if (curr->is_rmwr())
214                         return thread_current();
215                 /* The THREAD_CREATE action points to the created Thread */
216                 else if (curr->get_type() == THREAD_CREATE)
217                         return (Thread *)curr->get_location();
218         }
219
220         /* Have we completed exploring the preselected path? */
221         if (diverge == NULL)
222                 return NULL;
223
224         /* Else, we are trying to replay an execution */
225         ModelAction *next = node_stack->get_next()->get_action();
226
227         if (next == diverge) {
228                 if (earliest_diverge == NULL || *diverge < *earliest_diverge)
229                         earliest_diverge = diverge;
230
231                 Node *nextnode = next->get_node();
232                 Node *prevnode = nextnode->get_parent();
233                 scheduler->update_sleep_set(prevnode);
234
235                 /* Reached divergence point */
236                 if (nextnode->increment_misc()) {
237                         /* The next node will try to satisfy a different misc_index values. */
238                         tid = next->get_tid();
239                         node_stack->pop_restofstack(2);
240                 } else if (nextnode->increment_promise()) {
241                         /* The next node will try to satisfy a different set of promises. */
242                         tid = next->get_tid();
243                         node_stack->pop_restofstack(2);
244                 } else if (nextnode->increment_read_from()) {
245                         /* The next node will read from a different value. */
246                         tid = next->get_tid();
247                         node_stack->pop_restofstack(2);
248                 } else if (nextnode->increment_future_value()) {
249                         /* The next node will try to read from a different future value. */
250                         tid = next->get_tid();
251                         node_stack->pop_restofstack(2);
252                 } else if (nextnode->increment_relseq_break()) {
253                         /* The next node will try to resolve a release sequence differently */
254                         tid = next->get_tid();
255                         node_stack->pop_restofstack(2);
256                 } else {
257                         /* Make a different thread execute for next step */
258                         scheduler->add_sleep(get_thread(next->get_tid()));
259                         tid = prevnode->get_next_backtrack();
260                         /* Make sure the backtracked thread isn't sleeping. */
261                         node_stack->pop_restofstack(1);
262                         if (diverge == earliest_diverge) {
263                                 earliest_diverge = prevnode->get_action();
264                         }
265                 }
266                 /* The correct sleep set is in the parent node. */
267                 execute_sleep_set();
268
269                 DEBUG("*** Divergence point ***\n");
270
271                 diverge = NULL;
272         } else {
273                 tid = next->get_tid();
274         }
275         DEBUG("*** ModelChecker chose next thread = %d ***\n", id_to_int(tid));
276         ASSERT(tid != THREAD_ID_T_NONE);
277         return thread_map->get(id_to_int(tid));
278 }
279
280 /**
281  * We need to know what the next actions of all threads in the sleep
282  * set will be.  This method computes them and stores the actions at
283  * the corresponding thread object's pending action.
284  */
285
286 void ModelChecker::execute_sleep_set()
287 {
288         for (unsigned int i = 0; i < get_num_threads(); i++) {
289                 thread_id_t tid = int_to_id(i);
290                 Thread *thr = get_thread(tid);
291                 if (scheduler->is_sleep_set(thr) && thr->get_pending() == NULL) {
292                         thr->set_state(THREAD_RUNNING);
293                         scheduler->next_thread(thr);
294                         Thread::swap(&system_context, thr);
295                         priv->current_action->set_sleep_flag();
296                         thr->set_pending(priv->current_action);
297                 }
298         }
299 }
300
301 void ModelChecker::wake_up_sleeping_actions(ModelAction *curr)
302 {
303         for (unsigned int i = 0; i < get_num_threads(); i++) {
304                 Thread *thr = get_thread(int_to_id(i));
305                 if (scheduler->is_sleep_set(thr)) {
306                         ModelAction *pending_act = thr->get_pending();
307                         if ((!curr->is_rmwr()) && pending_act->could_synchronize_with(curr))
308                                 //Remove this thread from sleep set
309                                 scheduler->remove_sleep(thr);
310                 }
311         }
312 }
313
314 /** @brief Alert the model-checker that an incorrectly-ordered
315  * synchronization was made */
316 void ModelChecker::set_bad_synchronization()
317 {
318         priv->bad_synchronization = true;
319 }
320
321 bool ModelChecker::has_asserted() const
322 {
323         return priv->asserted;
324 }
325
326 void ModelChecker::set_assert()
327 {
328         priv->asserted = true;
329 }
330
331 /**
332  * Check if we are in a deadlock. Should only be called at the end of an
333  * execution, although it should not give false positives in the middle of an
334  * execution (there should be some ENABLED thread).
335  *
336  * @return True if program is in a deadlock; false otherwise
337  */
338 bool ModelChecker::is_deadlocked() const
339 {
340         bool blocking_threads = false;
341         for (unsigned int i = 0; i < get_num_threads(); i++) {
342                 thread_id_t tid = int_to_id(i);
343                 if (is_enabled(tid))
344                         return false;
345                 Thread *t = get_thread(tid);
346                 if (!t->is_model_thread() && t->get_pending())
347                         blocking_threads = true;
348         }
349         return blocking_threads;
350 }
351
352 /**
353  * Check if this is a complete execution. That is, have all thread completed
354  * execution (rather than exiting because sleep sets have forced a redundant
355  * execution).
356  *
357  * @return True if the execution is complete.
358  */
359 bool ModelChecker::is_complete_execution() const
360 {
361         for (unsigned int i = 0; i < get_num_threads(); i++)
362                 if (is_enabled(int_to_id(i)))
363                         return false;
364         return true;
365 }
366
367 /**
368  * @brief Assert a bug in the executing program.
369  *
370  * Use this function to assert any sort of bug in the user program. If the
371  * current trace is feasible (actually, a prefix of some feasible execution),
372  * then this execution will be aborted, printing the appropriate message. If
373  * the current trace is not yet feasible, the error message will be stashed and
374  * printed if the execution ever becomes feasible.
375  *
376  * @param msg Descriptive message for the bug (do not include newline char)
377  * @return True if bug is immediately-feasible
378  */
379 bool ModelChecker::assert_bug(const char *msg)
380 {
381         priv->bugs.push_back(new bug_message(msg));
382
383         if (isfeasibleprefix()) {
384                 set_assert();
385                 return true;
386         }
387         return false;
388 }
389
390 /**
391  * @brief Assert a bug in the executing program, asserted by a user thread
392  * @see ModelChecker::assert_bug
393  * @param msg Descriptive message for the bug (do not include newline char)
394  */
395 void ModelChecker::assert_user_bug(const char *msg)
396 {
397         /* If feasible bug, bail out now */
398         if (assert_bug(msg))
399                 switch_to_master(NULL);
400 }
401
402 /** @return True, if any bugs have been reported for this execution */
403 bool ModelChecker::have_bug_reports() const
404 {
405         return priv->bugs.size() != 0;
406 }
407
408 /** @brief Print bug report listing for this execution (if any bugs exist) */
409 void ModelChecker::print_bugs() const
410 {
411         if (have_bug_reports()) {
412                 model_print("Bug report: %zu bug%s detected\n",
413                                 priv->bugs.size(),
414                                 priv->bugs.size() > 1 ? "s" : "");
415                 for (unsigned int i = 0; i < priv->bugs.size(); i++)
416                         priv->bugs[i]->print();
417         }
418 }
419
420 /**
421  * @brief Record end-of-execution stats
422  *
423  * Must be run when exiting an execution. Records various stats.
424  * @see struct execution_stats
425  */
426 void ModelChecker::record_stats()
427 {
428         stats.num_total++;
429         if (!isfeasibleprefix())
430                 stats.num_infeasible++;
431         else if (have_bug_reports())
432                 stats.num_buggy_executions++;
433         else if (is_complete_execution())
434                 stats.num_complete++;
435         else
436                 stats.num_redundant++;
437 }
438
439 /** @brief Print execution stats */
440 void ModelChecker::print_stats() const
441 {
442         model_print("Number of complete, bug-free executions: %d\n", stats.num_complete);
443         model_print("Number of redundant executions: %d\n", stats.num_redundant);
444         model_print("Number of buggy executions: %d\n", stats.num_buggy_executions);
445         model_print("Number of infeasible executions: %d\n", stats.num_infeasible);
446         model_print("Total executions: %d\n", stats.num_total);
447         model_print("Total nodes created: %d\n", node_stack->get_total_nodes());
448 }
449
450 /**
451  * @brief End-of-exeuction print
452  * @param printbugs Should any existing bugs be printed?
453  */
454 void ModelChecker::print_execution(bool printbugs) const
455 {
456         print_program_output();
457
458         if (DBG_ENABLED() || params.verbose) {
459                 model_print("Earliest divergence point since last feasible execution:\n");
460                 if (earliest_diverge)
461                         earliest_diverge->print();
462                 else
463                         model_print("(Not set)\n");
464
465                 model_print("\n");
466                 print_stats();
467         }
468
469         /* Don't print invalid bugs */
470         if (printbugs)
471                 print_bugs();
472
473         model_print("\n");
474         print_summary();
475 }
476
477 /**
478  * Queries the model-checker for more executions to explore and, if one
479  * exists, resets the model-checker state to execute a new execution.
480  *
481  * @return If there are more executions to explore, return true. Otherwise,
482  * return false.
483  */
484 bool ModelChecker::next_execution()
485 {
486         DBG();
487         /* Is this execution a feasible execution that's worth bug-checking? */
488         bool complete = isfeasibleprefix() && (is_complete_execution() ||
489                         have_bug_reports());
490
491         /* End-of-execution bug checks */
492         if (complete) {
493                 if (is_deadlocked())
494                         assert_bug("Deadlock detected");
495
496                 checkDataRaces();
497         }
498
499         record_stats();
500
501         /* Output */
502         if (DBG_ENABLED() || params.verbose || (complete && have_bug_reports()))
503                 print_execution(complete);
504         else
505                 clear_program_output();
506
507         if (complete)
508                 earliest_diverge = NULL;
509
510         if ((diverge = get_next_backtrack()) == NULL)
511                 return false;
512
513         if (DBG_ENABLED()) {
514                 model_print("Next execution will diverge at:\n");
515                 diverge->print();
516         }
517
518         reset_to_initial_state();
519         return true;
520 }
521
522 ModelAction * ModelChecker::get_last_conflict(ModelAction *act)
523 {
524         switch (act->get_type()) {
525         case ATOMIC_FENCE:
526         case ATOMIC_READ:
527         case ATOMIC_WRITE:
528         case ATOMIC_RMW: {
529                 /* Optimization: relaxed operations don't need backtracking */
530                 if (act->is_relaxed())
531                         return NULL;
532                 /* linear search: from most recent to oldest */
533                 action_list_t *list = get_safe_ptr_action(obj_map, act->get_location());
534                 action_list_t::reverse_iterator rit;
535                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
536                         ModelAction *prev = *rit;
537                         if (prev->could_synchronize_with(act))
538                                 return prev;
539                 }
540                 break;
541         }
542         case ATOMIC_LOCK:
543         case ATOMIC_TRYLOCK: {
544                 /* linear search: from most recent to oldest */
545                 action_list_t *list = get_safe_ptr_action(obj_map, act->get_location());
546                 action_list_t::reverse_iterator rit;
547                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
548                         ModelAction *prev = *rit;
549                         if (act->is_conflicting_lock(prev))
550                                 return prev;
551                 }
552                 break;
553         }
554         case ATOMIC_UNLOCK: {
555                 /* linear search: from most recent to oldest */
556                 action_list_t *list = get_safe_ptr_action(obj_map, act->get_location());
557                 action_list_t::reverse_iterator rit;
558                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
559                         ModelAction *prev = *rit;
560                         if (!act->same_thread(prev) && prev->is_failed_trylock())
561                                 return prev;
562                 }
563                 break;
564         }
565         case ATOMIC_WAIT: {
566                 /* linear search: from most recent to oldest */
567                 action_list_t *list = get_safe_ptr_action(obj_map, act->get_location());
568                 action_list_t::reverse_iterator rit;
569                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
570                         ModelAction *prev = *rit;
571                         if (!act->same_thread(prev) && prev->is_failed_trylock())
572                                 return prev;
573                         if (!act->same_thread(prev) && prev->is_notify())
574                                 return prev;
575                 }
576                 break;
577         }
578
579         case ATOMIC_NOTIFY_ALL:
580         case ATOMIC_NOTIFY_ONE: {
581                 /* linear search: from most recent to oldest */
582                 action_list_t *list = get_safe_ptr_action(obj_map, act->get_location());
583                 action_list_t::reverse_iterator rit;
584                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
585                         ModelAction *prev = *rit;
586                         if (!act->same_thread(prev) && prev->is_wait())
587                                 return prev;
588                 }
589                 break;
590         }
591         default:
592                 break;
593         }
594         return NULL;
595 }
596
597 /** This method finds backtracking points where we should try to
598  * reorder the parameter ModelAction against.
599  *
600  * @param the ModelAction to find backtracking points for.
601  */
602 void ModelChecker::set_backtracking(ModelAction *act)
603 {
604         Thread *t = get_thread(act);
605         ModelAction *prev = get_last_conflict(act);
606         if (prev == NULL)
607                 return;
608
609         Node *node = prev->get_node()->get_parent();
610
611         int low_tid, high_tid;
612         if (node->is_enabled(t)) {
613                 low_tid = id_to_int(act->get_tid());
614                 high_tid = low_tid + 1;
615         } else {
616                 low_tid = 0;
617                 high_tid = get_num_threads();
618         }
619
620         for (int i = low_tid; i < high_tid; i++) {
621                 thread_id_t tid = int_to_id(i);
622
623                 /* Make sure this thread can be enabled here. */
624                 if (i >= node->get_num_threads())
625                         break;
626
627                 /* Don't backtrack into a point where the thread is disabled or sleeping. */
628                 if (node->enabled_status(tid) != THREAD_ENABLED)
629                         continue;
630
631                 /* Check if this has been explored already */
632                 if (node->has_been_explored(tid))
633                         continue;
634
635                 /* See if fairness allows */
636                 if (model->params.fairwindow != 0 && !node->has_priority(tid)) {
637                         bool unfair = false;
638                         for (int t = 0; t < node->get_num_threads(); t++) {
639                                 thread_id_t tother = int_to_id(t);
640                                 if (node->is_enabled(tother) && node->has_priority(tother)) {
641                                         unfair = true;
642                                         break;
643                                 }
644                         }
645                         if (unfair)
646                                 continue;
647                 }
648                 /* Cache the latest backtracking point */
649                 set_latest_backtrack(prev);
650
651                 /* If this is a new backtracking point, mark the tree */
652                 if (!node->set_backtrack(tid))
653                         continue;
654                 DEBUG("Setting backtrack: conflict = %d, instead tid = %d\n",
655                                         id_to_int(prev->get_tid()),
656                                         id_to_int(t->get_id()));
657                 if (DBG_ENABLED()) {
658                         prev->print();
659                         act->print();
660                 }
661         }
662 }
663
664 /**
665  * @brief Cache the a backtracking point as the "most recent", if eligible
666  *
667  * Note that this does not prepare the NodeStack for this backtracking
668  * operation, it only caches the action on a per-execution basis
669  *
670  * @param act The operation at which we should explore a different next action
671  * (i.e., backtracking point)
672  * @return True, if this action is now the most recent backtracking point;
673  * false otherwise
674  */
675 bool ModelChecker::set_latest_backtrack(ModelAction *act)
676 {
677         if (!priv->next_backtrack || *act > *priv->next_backtrack) {
678                 priv->next_backtrack = act;
679                 return true;
680         }
681         return false;
682 }
683
684 /**
685  * Returns last backtracking point. The model checker will explore a different
686  * path for this point in the next execution.
687  * @return The ModelAction at which the next execution should diverge.
688  */
689 ModelAction * ModelChecker::get_next_backtrack()
690 {
691         ModelAction *next = priv->next_backtrack;
692         priv->next_backtrack = NULL;
693         return next;
694 }
695
696 /**
697  * Processes a read or rmw model action.
698  * @param curr is the read model action to process.
699  * @param second_part_of_rmw is boolean that is true is this is the second action of a rmw.
700  * @return True if processing this read updates the mo_graph.
701  */
702 bool ModelChecker::process_read(ModelAction *curr, bool second_part_of_rmw)
703 {
704         uint64_t value = VALUE_NONE;
705         bool updated = false;
706         while (true) {
707                 const ModelAction *reads_from = curr->get_node()->get_read_from();
708                 if (reads_from != NULL) {
709                         mo_graph->startChanges();
710
711                         value = reads_from->get_value();
712                         bool r_status = false;
713
714                         if (!second_part_of_rmw) {
715                                 check_recency(curr, reads_from);
716                                 r_status = r_modification_order(curr, reads_from);
717                         }
718
719
720                         if (!second_part_of_rmw && is_infeasible() && (curr->get_node()->increment_read_from() || curr->get_node()->increment_future_value())) {
721                                 mo_graph->rollbackChanges();
722                                 priv->too_many_reads = false;
723                                 continue;
724                         }
725
726                         read_from(curr, reads_from);
727                         mo_graph->commitChanges();
728                         mo_check_promises(curr->get_tid(), reads_from);
729
730                         updated |= r_status;
731                 } else if (!second_part_of_rmw) {
732                         /* Read from future value */
733                         value = curr->get_node()->get_future_value();
734                         modelclock_t expiration = curr->get_node()->get_future_value_expiration();
735                         curr->set_read_from(NULL);
736                         Promise *valuepromise = new Promise(curr, value, expiration);
737                         promises->push_back(valuepromise);
738                 }
739                 get_thread(curr)->set_return_value(value);
740                 return updated;
741         }
742 }
743
744 /**
745  * Processes a lock, trylock, or unlock model action.  @param curr is
746  * the read model action to process.
747  *
748  * The try lock operation checks whether the lock is taken.  If not,
749  * it falls to the normal lock operation case.  If so, it returns
750  * fail.
751  *
752  * The lock operation has already been checked that it is enabled, so
753  * it just grabs the lock and synchronizes with the previous unlock.
754  *
755  * The unlock operation has to re-enable all of the threads that are
756  * waiting on the lock.
757  *
758  * @return True if synchronization was updated; false otherwise
759  */
760 bool ModelChecker::process_mutex(ModelAction *curr)
761 {
762         std::mutex *mutex = NULL;
763         struct std::mutex_state *state = NULL;
764
765         if (curr->is_trylock() || curr->is_lock() || curr->is_unlock()) {
766                 mutex = (std::mutex *)curr->get_location();
767                 state = mutex->get_state();
768         } else if (curr->is_wait()) {
769                 mutex = (std::mutex *)curr->get_value();
770                 state = mutex->get_state();
771         }
772
773         switch (curr->get_type()) {
774         case ATOMIC_TRYLOCK: {
775                 bool success = !state->islocked;
776                 curr->set_try_lock(success);
777                 if (!success) {
778                         get_thread(curr)->set_return_value(0);
779                         break;
780                 }
781                 get_thread(curr)->set_return_value(1);
782         }
783                 //otherwise fall into the lock case
784         case ATOMIC_LOCK: {
785                 if (curr->get_cv()->getClock(state->alloc_tid) <= state->alloc_clock)
786                         assert_bug("Lock access before initialization");
787                 state->islocked = true;
788                 ModelAction *unlock = get_last_unlock(curr);
789                 //synchronize with the previous unlock statement
790                 if (unlock != NULL) {
791                         curr->synchronize_with(unlock);
792                         return true;
793                 }
794                 break;
795         }
796         case ATOMIC_UNLOCK: {
797                 //unlock the lock
798                 state->islocked = false;
799                 //wake up the other threads
800                 action_list_t *waiters = get_safe_ptr_action(lock_waiters_map, curr->get_location());
801                 //activate all the waiting threads
802                 for (action_list_t::iterator rit = waiters->begin(); rit != waiters->end(); rit++) {
803                         scheduler->wake(get_thread(*rit));
804                 }
805                 waiters->clear();
806                 break;
807         }
808         case ATOMIC_WAIT: {
809                 //unlock the lock
810                 state->islocked = false;
811                 //wake up the other threads
812                 action_list_t *waiters = get_safe_ptr_action(lock_waiters_map, (void *) curr->get_value());
813                 //activate all the waiting threads
814                 for (action_list_t::iterator rit = waiters->begin(); rit != waiters->end(); rit++) {
815                         scheduler->wake(get_thread(*rit));
816                 }
817                 waiters->clear();
818                 //check whether we should go to sleep or not...simulate spurious failures
819                 if (curr->get_node()->get_misc() == 0) {
820                         get_safe_ptr_action(condvar_waiters_map, curr->get_location())->push_back(curr);
821                         //disable us
822                         scheduler->sleep(get_current_thread());
823                 }
824                 break;
825         }
826         case ATOMIC_NOTIFY_ALL: {
827                 action_list_t *waiters = get_safe_ptr_action(condvar_waiters_map, curr->get_location());
828                 //activate all the waiting threads
829                 for (action_list_t::iterator rit = waiters->begin(); rit != waiters->end(); rit++) {
830                         scheduler->wake(get_thread(*rit));
831                 }
832                 waiters->clear();
833                 break;
834         }
835         case ATOMIC_NOTIFY_ONE: {
836                 action_list_t *waiters = get_safe_ptr_action(condvar_waiters_map, curr->get_location());
837                 int wakeupthread = curr->get_node()->get_misc();
838                 action_list_t::iterator it = waiters->begin();
839                 advance(it, wakeupthread);
840                 scheduler->wake(get_thread(*it));
841                 waiters->erase(it);
842                 break;
843         }
844
845         default:
846                 ASSERT(0);
847         }
848         return false;
849 }
850
851 /**
852  * Process a write ModelAction
853  * @param curr The ModelAction to process
854  * @return True if the mo_graph was updated or promises were resolved
855  */
856 bool ModelChecker::process_write(ModelAction *curr)
857 {
858         bool updated_mod_order = w_modification_order(curr);
859         bool updated_promises = resolve_promises(curr);
860
861         if (promises->size() == 0) {
862                 for (unsigned int i = 0; i < futurevalues->size(); i++) {
863                         struct PendingFutureValue pfv = (*futurevalues)[i];
864                         //Do more ambitious checks now that mo is more complete
865                         if (mo_may_allow(pfv.writer, pfv.act) &&
866                                         pfv.act->get_node()->add_future_value(pfv.writer->get_value(), pfv.writer->get_seq_number() + params.maxfuturedelay))
867                                 set_latest_backtrack(pfv.act);
868                 }
869                 futurevalues->resize(0);
870         }
871
872         mo_graph->commitChanges();
873         mo_check_promises(curr->get_tid(), curr);
874
875         get_thread(curr)->set_return_value(VALUE_NONE);
876         return updated_mod_order || updated_promises;
877 }
878
879 /**
880  * Process a fence ModelAction
881  * @param curr The ModelAction to process
882  * @return True if synchronization was updated
883  */
884 bool ModelChecker::process_fence(ModelAction *curr)
885 {
886         /*
887          * fence-relaxed: no-op
888          * fence-release: only log the occurence (not in this function), for
889          *   use in later synchronization
890          * fence-acquire (this function): search for hypothetical release
891          *   sequences
892          */
893         bool updated = false;
894         if (curr->is_acquire()) {
895                 action_list_t *list = action_trace;
896                 action_list_t::reverse_iterator rit;
897                 /* Find X : is_read(X) && X --sb-> curr */
898                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
899                         ModelAction *act = *rit;
900                         if (act == curr)
901                                 continue;
902                         if (act->get_tid() != curr->get_tid())
903                                 continue;
904                         /* Stop at the beginning of the thread */
905                         if (act->is_thread_start())
906                                 break;
907                         /* Stop once we reach a prior fence-acquire */
908                         if (act->is_fence() && act->is_acquire())
909                                 break;
910                         if (!act->is_read())
911                                 continue;
912                         /* read-acquire will find its own release sequences */
913                         if (act->is_acquire())
914                                 continue;
915
916                         /* Establish hypothetical release sequences */
917                         rel_heads_list_t release_heads;
918                         get_release_seq_heads(curr, act, &release_heads);
919                         for (unsigned int i = 0; i < release_heads.size(); i++)
920                                 if (!curr->synchronize_with(release_heads[i]))
921                                         set_bad_synchronization();
922                         if (release_heads.size() != 0)
923                                 updated = true;
924                 }
925         }
926         return updated;
927 }
928
929 /**
930  * @brief Process the current action for thread-related activity
931  *
932  * Performs current-action processing for a THREAD_* ModelAction. Proccesses
933  * may include setting Thread status, completing THREAD_FINISH/THREAD_JOIN
934  * synchronization, etc.  This function is a no-op for non-THREAD actions
935  * (e.g., ATOMIC_{READ,WRITE,RMW,LOCK}, etc.)
936  *
937  * @param curr The current action
938  * @return True if synchronization was updated or a thread completed
939  */
940 bool ModelChecker::process_thread_action(ModelAction *curr)
941 {
942         bool updated = false;
943
944         switch (curr->get_type()) {
945         case THREAD_CREATE: {
946                 Thread *th = (Thread *)curr->get_location();
947                 th->set_creation(curr);
948                 break;
949         }
950         case THREAD_JOIN: {
951                 Thread *blocking = (Thread *)curr->get_location();
952                 ModelAction *act = get_last_action(blocking->get_id());
953                 curr->synchronize_with(act);
954                 updated = true; /* trigger rel-seq checks */
955                 break;
956         }
957         case THREAD_FINISH: {
958                 Thread *th = get_thread(curr);
959                 while (!th->wait_list_empty()) {
960                         ModelAction *act = th->pop_wait_list();
961                         scheduler->wake(get_thread(act));
962                 }
963                 th->complete();
964                 updated = true; /* trigger rel-seq checks */
965                 break;
966         }
967         case THREAD_START: {
968                 check_promises(curr->get_tid(), NULL, curr->get_cv());
969                 break;
970         }
971         default:
972                 break;
973         }
974
975         return updated;
976 }
977
978 /**
979  * @brief Process the current action for release sequence fixup activity
980  *
981  * Performs model-checker release sequence fixups for the current action,
982  * forcing a single pending release sequence to break (with a given, potential
983  * "loose" write) or to complete (i.e., synchronize). If a pending release
984  * sequence forms a complete release sequence, then we must perform the fixup
985  * synchronization, mo_graph additions, etc.
986  *
987  * @param curr The current action; must be a release sequence fixup action
988  * @param work_queue The work queue to which to add work items as they are
989  * generated
990  */
991 void ModelChecker::process_relseq_fixup(ModelAction *curr, work_queue_t *work_queue)
992 {
993         const ModelAction *write = curr->get_node()->get_relseq_break();
994         struct release_seq *sequence = pending_rel_seqs->back();
995         pending_rel_seqs->pop_back();
996         ASSERT(sequence);
997         ModelAction *acquire = sequence->acquire;
998         const ModelAction *rf = sequence->rf;
999         const ModelAction *release = sequence->release;
1000         ASSERT(acquire);
1001         ASSERT(release);
1002         ASSERT(rf);
1003         ASSERT(release->same_thread(rf));
1004
1005         if (write == NULL) {
1006                 /**
1007                  * @todo Forcing a synchronization requires that we set
1008                  * modification order constraints. For instance, we can't allow
1009                  * a fixup sequence in which two separate read-acquire
1010                  * operations read from the same sequence, where the first one
1011                  * synchronizes and the other doesn't. Essentially, we can't
1012                  * allow any writes to insert themselves between 'release' and
1013                  * 'rf'
1014                  */
1015
1016                 /* Must synchronize */
1017                 if (!acquire->synchronize_with(release)) {
1018                         set_bad_synchronization();
1019                         return;
1020                 }
1021                 /* Re-check all pending release sequences */
1022                 work_queue->push_back(CheckRelSeqWorkEntry(NULL));
1023                 /* Re-check act for mo_graph edges */
1024                 work_queue->push_back(MOEdgeWorkEntry(acquire));
1025
1026                 /* propagate synchronization to later actions */
1027                 action_list_t::reverse_iterator rit = action_trace->rbegin();
1028                 for (; (*rit) != acquire; rit++) {
1029                         ModelAction *propagate = *rit;
1030                         if (acquire->happens_before(propagate)) {
1031                                 propagate->synchronize_with(acquire);
1032                                 /* Re-check 'propagate' for mo_graph edges */
1033                                 work_queue->push_back(MOEdgeWorkEntry(propagate));
1034                         }
1035                 }
1036         } else {
1037                 /* Break release sequence with new edges:
1038                  *   release --mo--> write --mo--> rf */
1039                 mo_graph->addEdge(release, write);
1040                 mo_graph->addEdge(write, rf);
1041         }
1042
1043         /* See if we have realized a data race */
1044         checkDataRaces();
1045 }
1046
1047 /**
1048  * Initialize the current action by performing one or more of the following
1049  * actions, as appropriate: merging RMWR and RMWC/RMW actions, stepping forward
1050  * in the NodeStack, manipulating backtracking sets, allocating and
1051  * initializing clock vectors, and computing the promises to fulfill.
1052  *
1053  * @param curr The current action, as passed from the user context; may be
1054  * freed/invalidated after the execution of this function, with a different
1055  * action "returned" its place (pass-by-reference)
1056  * @return True if curr is a newly-explored action; false otherwise
1057  */
1058 bool ModelChecker::initialize_curr_action(ModelAction **curr)
1059 {
1060         ModelAction *newcurr;
1061
1062         if ((*curr)->is_rmwc() || (*curr)->is_rmw()) {
1063                 newcurr = process_rmw(*curr);
1064                 delete *curr;
1065
1066                 if (newcurr->is_rmw())
1067                         compute_promises(newcurr);
1068
1069                 *curr = newcurr;
1070                 return false;
1071         }
1072
1073         (*curr)->set_seq_number(get_next_seq_num());
1074
1075         newcurr = node_stack->explore_action(*curr, scheduler->get_enabled_array());
1076         if (newcurr) {
1077                 /* First restore type and order in case of RMW operation */
1078                 if ((*curr)->is_rmwr())
1079                         newcurr->copy_typeandorder(*curr);
1080
1081                 ASSERT((*curr)->get_location() == newcurr->get_location());
1082                 newcurr->copy_from_new(*curr);
1083
1084                 /* Discard duplicate ModelAction; use action from NodeStack */
1085                 delete *curr;
1086
1087                 /* Always compute new clock vector */
1088                 newcurr->create_cv(get_parent_action(newcurr->get_tid()));
1089
1090                 *curr = newcurr;
1091                 return false; /* Action was explored previously */
1092         } else {
1093                 newcurr = *curr;
1094
1095                 /* Always compute new clock vector */
1096                 newcurr->create_cv(get_parent_action(newcurr->get_tid()));
1097
1098                 /* Assign most recent release fence */
1099                 newcurr->set_last_fence_release(get_last_fence_release(newcurr->get_tid()));
1100
1101                 /*
1102                  * Perform one-time actions when pushing new ModelAction onto
1103                  * NodeStack
1104                  */
1105                 if (newcurr->is_write())
1106                         compute_promises(newcurr);
1107                 else if (newcurr->is_relseq_fixup())
1108                         compute_relseq_breakwrites(newcurr);
1109                 else if (newcurr->is_wait())
1110                         newcurr->get_node()->set_misc_max(2);
1111                 else if (newcurr->is_notify_one()) {
1112                         newcurr->get_node()->set_misc_max(get_safe_ptr_action(condvar_waiters_map, newcurr->get_location())->size());
1113                 }
1114                 return true; /* This was a new ModelAction */
1115         }
1116 }
1117
1118 /**
1119  * @brief Establish reads-from relation between two actions
1120  *
1121  * Perform basic operations involved with establishing a concrete rf relation,
1122  * including setting the ModelAction data and checking for release sequences.
1123  *
1124  * @param act The action that is reading (must be a read)
1125  * @param rf The action from which we are reading (must be a write)
1126  *
1127  * @return True if this read established synchronization
1128  */
1129 bool ModelChecker::read_from(ModelAction *act, const ModelAction *rf)
1130 {
1131         act->set_read_from(rf);
1132         if (rf != NULL && act->is_acquire()) {
1133                 rel_heads_list_t release_heads;
1134                 get_release_seq_heads(act, act, &release_heads);
1135                 int num_heads = release_heads.size();
1136                 for (unsigned int i = 0; i < release_heads.size(); i++)
1137                         if (!act->synchronize_with(release_heads[i])) {
1138                                 set_bad_synchronization();
1139                                 num_heads--;
1140                         }
1141                 return num_heads > 0;
1142         }
1143         return false;
1144 }
1145
1146 /**
1147  * @brief Check whether a model action is enabled.
1148  *
1149  * Checks whether a lock or join operation would be successful (i.e., is the
1150  * lock already locked, or is the joined thread already complete). If not, put
1151  * the action in a waiter list.
1152  *
1153  * @param curr is the ModelAction to check whether it is enabled.
1154  * @return a bool that indicates whether the action is enabled.
1155  */
1156 bool ModelChecker::check_action_enabled(ModelAction *curr) {
1157         if (curr->is_lock()) {
1158                 std::mutex *lock = (std::mutex *)curr->get_location();
1159                 struct std::mutex_state *state = lock->get_state();
1160                 if (state->islocked) {
1161                         //Stick the action in the appropriate waiting queue
1162                         get_safe_ptr_action(lock_waiters_map, curr->get_location())->push_back(curr);
1163                         return false;
1164                 }
1165         } else if (curr->get_type() == THREAD_JOIN) {
1166                 Thread *blocking = (Thread *)curr->get_location();
1167                 if (!blocking->is_complete()) {
1168                         blocking->push_wait_list(curr);
1169                         return false;
1170                 }
1171         }
1172
1173         return true;
1174 }
1175
1176 /**
1177  * Stores the ModelAction for the current thread action.  Call this
1178  * immediately before switching from user- to system-context to pass
1179  * data between them.
1180  * @param act The ModelAction created by the user-thread action
1181  */
1182 void ModelChecker::set_current_action(ModelAction *act) {
1183         priv->current_action = act;
1184 }
1185
1186 /**
1187  * This is the heart of the model checker routine. It performs model-checking
1188  * actions corresponding to a given "current action." Among other processes, it
1189  * calculates reads-from relationships, updates synchronization clock vectors,
1190  * forms a memory_order constraints graph, and handles replay/backtrack
1191  * execution when running permutations of previously-observed executions.
1192  *
1193  * @param curr The current action to process
1194  * @return The next Thread that must be executed. May be NULL if ModelChecker
1195  * makes no choice (e.g., according to replay execution, combining RMW actions,
1196  * etc.)
1197  */
1198 Thread * ModelChecker::check_current_action(ModelAction *curr)
1199 {
1200         ASSERT(curr);
1201         bool second_part_of_rmw = curr->is_rmwc() || curr->is_rmw();
1202
1203         if (!check_action_enabled(curr)) {
1204                 /* Make the execution look like we chose to run this action
1205                  * much later, when a lock/join can succeed */
1206                 get_current_thread()->set_pending(curr);
1207                 scheduler->sleep(get_current_thread());
1208                 return get_next_thread(NULL);
1209         }
1210
1211         bool newly_explored = initialize_curr_action(&curr);
1212
1213         wake_up_sleeping_actions(curr);
1214
1215         /* Add the action to lists before any other model-checking tasks */
1216         if (!second_part_of_rmw)
1217                 add_action_to_lists(curr);
1218
1219         /* Build may_read_from set for newly-created actions */
1220         if (newly_explored && curr->is_read())
1221                 build_reads_from_past(curr);
1222
1223         /* Initialize work_queue with the "current action" work */
1224         work_queue_t work_queue(1, CheckCurrWorkEntry(curr));
1225         while (!work_queue.empty() && !has_asserted()) {
1226                 WorkQueueEntry work = work_queue.front();
1227                 work_queue.pop_front();
1228
1229                 switch (work.type) {
1230                 case WORK_CHECK_CURR_ACTION: {
1231                         ModelAction *act = work.action;
1232                         bool update = false; /* update this location's release seq's */
1233                         bool update_all = false; /* update all release seq's */
1234
1235                         if (process_thread_action(curr))
1236                                 update_all = true;
1237
1238                         if (act->is_read() && process_read(act, second_part_of_rmw))
1239                                 update = true;
1240
1241                         if (act->is_write() && process_write(act))
1242                                 update = true;
1243
1244                         if (act->is_fence() && process_fence(act))
1245                                 update_all = true;
1246
1247                         if (act->is_mutex_op() && process_mutex(act))
1248                                 update_all = true;
1249
1250                         if (act->is_relseq_fixup())
1251                                 process_relseq_fixup(curr, &work_queue);
1252
1253                         if (update_all)
1254                                 work_queue.push_back(CheckRelSeqWorkEntry(NULL));
1255                         else if (update)
1256                                 work_queue.push_back(CheckRelSeqWorkEntry(act->get_location()));
1257                         break;
1258                 }
1259                 case WORK_CHECK_RELEASE_SEQ:
1260                         resolve_release_sequences(work.location, &work_queue);
1261                         break;
1262                 case WORK_CHECK_MO_EDGES: {
1263                         /** @todo Complete verification of work_queue */
1264                         ModelAction *act = work.action;
1265                         bool updated = false;
1266
1267                         if (act->is_read()) {
1268                                 const ModelAction *rf = act->get_reads_from();
1269                                 if (rf != NULL && r_modification_order(act, rf))
1270                                         updated = true;
1271                         }
1272                         if (act->is_write()) {
1273                                 if (w_modification_order(act))
1274                                         updated = true;
1275                         }
1276                         mo_graph->commitChanges();
1277
1278                         if (updated)
1279                                 work_queue.push_back(CheckRelSeqWorkEntry(act->get_location()));
1280                         break;
1281                 }
1282                 default:
1283                         ASSERT(false);
1284                         break;
1285                 }
1286         }
1287
1288         check_curr_backtracking(curr);
1289         set_backtracking(curr);
1290         return get_next_thread(curr);
1291 }
1292
1293 void ModelChecker::check_curr_backtracking(ModelAction *curr)
1294 {
1295         Node *currnode = curr->get_node();
1296         Node *parnode = currnode->get_parent();
1297
1298         if (!parnode->backtrack_empty() ||
1299                          !currnode->misc_empty() ||
1300                          !currnode->read_from_empty() ||
1301                          !currnode->future_value_empty() ||
1302                          !currnode->promise_empty() ||
1303                          !currnode->relseq_break_empty()) {
1304                 set_latest_backtrack(curr);
1305         }
1306 }
1307
1308 bool ModelChecker::promises_expired() const
1309 {
1310         for (unsigned int i = 0; i < promises->size(); i++) {
1311                 Promise *promise = (*promises)[i];
1312                 if (promise->get_expiration() < priv->used_sequence_numbers)
1313                         return true;
1314         }
1315         return false;
1316 }
1317
1318 /**
1319  * This is the strongest feasibility check available.
1320  * @return whether the current trace (partial or complete) must be a prefix of
1321  * a feasible trace.
1322  */
1323 bool ModelChecker::isfeasibleprefix() const
1324 {
1325         return pending_rel_seqs->size() == 0 && is_feasible_prefix_ignore_relseq();
1326 }
1327
1328 /**
1329  * Returns whether the current completed trace is feasible, except for pending
1330  * release sequences.
1331  */
1332 bool ModelChecker::is_feasible_prefix_ignore_relseq() const
1333 {
1334         if (DBG_ENABLED() && promises->size() != 0)
1335                 DEBUG("Infeasible: unrevolved promises\n");
1336
1337         return !is_infeasible() && promises->size() == 0;
1338 }
1339
1340 /**
1341  * Check if the current partial trace is infeasible. Does not check any
1342  * end-of-execution flags, which might rule out the execution. Thus, this is
1343  * useful only for ruling an execution as infeasible.
1344  * @return whether the current partial trace is infeasible.
1345  */
1346 bool ModelChecker::is_infeasible() const
1347 {
1348         if (DBG_ENABLED() && mo_graph->checkForRMWViolation())
1349                 DEBUG("Infeasible: RMW violation\n");
1350
1351         return mo_graph->checkForRMWViolation() || is_infeasible_ignoreRMW();
1352 }
1353
1354 /**
1355  * Check If the current partial trace is infeasible, while ignoring
1356  * infeasibility related to 2 RMW's reading from the same store. It does not
1357  * check end-of-execution feasibility.
1358  * @see ModelChecker::is_infeasible
1359  * @return whether the current partial trace is infeasible, ignoring multiple
1360  * RMWs reading from the same store.
1361  * */
1362 bool ModelChecker::is_infeasible_ignoreRMW() const
1363 {
1364         if (DBG_ENABLED()) {
1365                 if (mo_graph->checkForCycles())
1366                         DEBUG("Infeasible: modification order cycles\n");
1367                 if (priv->failed_promise)
1368                         DEBUG("Infeasible: failed promise\n");
1369                 if (priv->too_many_reads)
1370                         DEBUG("Infeasible: too many reads\n");
1371                 if (priv->bad_synchronization)
1372                         DEBUG("Infeasible: bad synchronization ordering\n");
1373                 if (promises_expired())
1374                         DEBUG("Infeasible: promises expired\n");
1375         }
1376         return mo_graph->checkForCycles() || priv->failed_promise ||
1377                 priv->too_many_reads || priv->bad_synchronization ||
1378                 promises_expired();
1379 }
1380
1381 /** Close out a RMWR by converting previous RMWR into a RMW or READ. */
1382 ModelAction * ModelChecker::process_rmw(ModelAction *act) {
1383         ModelAction *lastread = get_last_action(act->get_tid());
1384         lastread->process_rmw(act);
1385         if (act->is_rmw() && lastread->get_reads_from() != NULL) {
1386                 mo_graph->addRMWEdge(lastread->get_reads_from(), lastread);
1387                 mo_graph->commitChanges();
1388         }
1389         return lastread;
1390 }
1391
1392 /**
1393  * Checks whether a thread has read from the same write for too many times
1394  * without seeing the effects of a later write.
1395  *
1396  * Basic idea:
1397  * 1) there must a different write that we could read from that would satisfy the modification order,
1398  * 2) we must have read from the same value in excess of maxreads times, and
1399  * 3) that other write must have been in the reads_from set for maxreads times.
1400  *
1401  * If so, we decide that the execution is no longer feasible.
1402  */
1403 void ModelChecker::check_recency(ModelAction *curr, const ModelAction *rf)
1404 {
1405         if (params.maxreads != 0) {
1406                 if (curr->get_node()->get_read_from_size() <= 1)
1407                         return;
1408                 //Must make sure that execution is currently feasible...  We could
1409                 //accidentally clear by rolling back
1410                 if (is_infeasible())
1411                         return;
1412                 std::vector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
1413                 int tid = id_to_int(curr->get_tid());
1414
1415                 /* Skip checks */
1416                 if ((int)thrd_lists->size() <= tid)
1417                         return;
1418                 action_list_t *list = &(*thrd_lists)[tid];
1419
1420                 action_list_t::reverse_iterator rit = list->rbegin();
1421                 /* Skip past curr */
1422                 for (; (*rit) != curr; rit++)
1423                         ;
1424                 /* go past curr now */
1425                 rit++;
1426
1427                 action_list_t::reverse_iterator ritcopy = rit;
1428                 //See if we have enough reads from the same value
1429                 int count = 0;
1430                 for (; count < params.maxreads; rit++, count++) {
1431                         if (rit == list->rend())
1432                                 return;
1433                         ModelAction *act = *rit;
1434                         if (!act->is_read())
1435                                 return;
1436
1437                         if (act->get_reads_from() != rf)
1438                                 return;
1439                         if (act->get_node()->get_read_from_size() <= 1)
1440                                 return;
1441                 }
1442                 for (int i = 0; i < curr->get_node()->get_read_from_size(); i++) {
1443                         /* Get write */
1444                         const ModelAction *write = curr->get_node()->get_read_from_at(i);
1445
1446                         /* Need a different write */
1447                         if (write == rf)
1448                                 continue;
1449
1450                         /* Test to see whether this is a feasible write to read from */
1451                         mo_graph->startChanges();
1452                         r_modification_order(curr, write);
1453                         bool feasiblereadfrom = !is_infeasible();
1454                         mo_graph->rollbackChanges();
1455
1456                         if (!feasiblereadfrom)
1457                                 continue;
1458                         rit = ritcopy;
1459
1460                         bool feasiblewrite = true;
1461                         //new we need to see if this write works for everyone
1462
1463                         for (int loop = count; loop > 0; loop--, rit++) {
1464                                 ModelAction *act = *rit;
1465                                 bool foundvalue = false;
1466                                 for (int j = 0; j < act->get_node()->get_read_from_size(); j++) {
1467                                         if (act->get_node()->get_read_from_at(j) == write) {
1468                                                 foundvalue = true;
1469                                                 break;
1470                                         }
1471                                 }
1472                                 if (!foundvalue) {
1473                                         feasiblewrite = false;
1474                                         break;
1475                                 }
1476                         }
1477                         if (feasiblewrite) {
1478                                 priv->too_many_reads = true;
1479                                 return;
1480                         }
1481                 }
1482         }
1483 }
1484
1485 /**
1486  * Updates the mo_graph with the constraints imposed from the current
1487  * read.
1488  *
1489  * Basic idea is the following: Go through each other thread and find
1490  * the lastest action that happened before our read.  Two cases:
1491  *
1492  * (1) The action is a write => that write must either occur before
1493  * the write we read from or be the write we read from.
1494  *
1495  * (2) The action is a read => the write that that action read from
1496  * must occur before the write we read from or be the same write.
1497  *
1498  * @param curr The current action. Must be a read.
1499  * @param rf The action that curr reads from. Must be a write.
1500  * @return True if modification order edges were added; false otherwise
1501  */
1502 bool ModelChecker::r_modification_order(ModelAction *curr, const ModelAction *rf)
1503 {
1504         std::vector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
1505         unsigned int i;
1506         bool added = false;
1507         ASSERT(curr->is_read());
1508
1509         /* Last SC fence in the current thread */
1510         ModelAction *last_sc_fence_local = get_last_seq_cst_fence(curr->get_tid(), NULL);
1511
1512         /* Iterate over all threads */
1513         for (i = 0; i < thrd_lists->size(); i++) {
1514                 /* Last SC fence in thread i */
1515                 ModelAction *last_sc_fence_thread_local = NULL;
1516                 if (int_to_id((int)i) != curr->get_tid())
1517                         last_sc_fence_thread_local = get_last_seq_cst_fence(int_to_id(i), NULL);
1518
1519                 /* Last SC fence in thread i, before last SC fence in current thread */
1520                 ModelAction *last_sc_fence_thread_before = NULL;
1521                 if (last_sc_fence_local)
1522                         last_sc_fence_thread_before = get_last_seq_cst_fence(int_to_id(i), last_sc_fence_local);
1523
1524                 /* Iterate over actions in thread, starting from most recent */
1525                 action_list_t *list = &(*thrd_lists)[i];
1526                 action_list_t::reverse_iterator rit;
1527                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
1528                         ModelAction *act = *rit;
1529
1530                         if (act->is_write() && act != rf && act != curr) {
1531                                 /* C++, Section 29.3 statement 5 */
1532                                 if (curr->is_seqcst() && last_sc_fence_thread_local &&
1533                                                 *act < *last_sc_fence_thread_local) {
1534                                         mo_graph->addEdge(act, rf);
1535                                         added = true;
1536                                         break;
1537                                 }
1538                                 /* C++, Section 29.3 statement 4 */
1539                                 else if (act->is_seqcst() && last_sc_fence_local &&
1540                                                 *act < *last_sc_fence_local) {
1541                                         mo_graph->addEdge(act, rf);
1542                                         added = true;
1543                                         break;
1544                                 }
1545                                 /* C++, Section 29.3 statement 6 */
1546                                 else if (last_sc_fence_thread_before &&
1547                                                 *act < *last_sc_fence_thread_before) {
1548                                         mo_graph->addEdge(act, rf);
1549                                         added = true;
1550                                         break;
1551                                 }
1552                         }
1553
1554                         /*
1555                          * Include at most one act per-thread that "happens
1556                          * before" curr. Don't consider reflexively.
1557                          */
1558                         if (act->happens_before(curr) && act != curr) {
1559                                 if (act->is_write()) {
1560                                         if (rf != act) {
1561                                                 mo_graph->addEdge(act, rf);
1562                                                 added = true;
1563                                         }
1564                                 } else {
1565                                         const ModelAction *prevreadfrom = act->get_reads_from();
1566                                         //if the previous read is unresolved, keep going...
1567                                         if (prevreadfrom == NULL)
1568                                                 continue;
1569
1570                                         if (rf != prevreadfrom) {
1571                                                 mo_graph->addEdge(prevreadfrom, rf);
1572                                                 added = true;
1573                                         }
1574                                 }
1575                                 break;
1576                         }
1577                 }
1578         }
1579
1580         return added;
1581 }
1582
1583 /** This method fixes up the modification order when we resolve a
1584  *  promises.  The basic problem is that actions that occur after the
1585  *  read curr could not property add items to the modification order
1586  *  for our read.
1587  *
1588  *  So for each thread, we find the earliest item that happens after
1589  *  the read curr.  This is the item we have to fix up with additional
1590  *  constraints.  If that action is write, we add a MO edge between
1591  *  the Action rf and that action.  If the action is a read, we add a
1592  *  MO edge between the Action rf, and whatever the read accessed.
1593  *
1594  * @param curr is the read ModelAction that we are fixing up MO edges for.
1595  * @param rf is the write ModelAction that curr reads from.
1596  *
1597  */
1598 void ModelChecker::post_r_modification_order(ModelAction *curr, const ModelAction *rf)
1599 {
1600         std::vector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
1601         unsigned int i;
1602         ASSERT(curr->is_read());
1603
1604         /* Iterate over all threads */
1605         for (i = 0; i < thrd_lists->size(); i++) {
1606                 /* Iterate over actions in thread, starting from most recent */
1607                 action_list_t *list = &(*thrd_lists)[i];
1608                 action_list_t::reverse_iterator rit;
1609                 ModelAction *lastact = NULL;
1610
1611                 /* Find last action that happens after curr that is either not curr or a rmw */
1612                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
1613                         ModelAction *act = *rit;
1614                         if (curr->happens_before(act) && (curr != act || curr->is_rmw())) {
1615                                 lastact = act;
1616                         } else
1617                                 break;
1618                 }
1619
1620                         /* Include at most one act per-thread that "happens before" curr */
1621                 if (lastact != NULL) {
1622                         if (lastact == curr) {
1623                                 //Case 1: The resolved read is a RMW, and we need to make sure
1624                                 //that the write portion of the RMW mod order after rf
1625
1626                                 mo_graph->addEdge(rf, lastact);
1627                         } else if (lastact->is_read()) {
1628                                 //Case 2: The resolved read is a normal read and the next
1629                                 //operation is a read, and we need to make sure the value read
1630                                 //is mod ordered after rf
1631
1632                                 const ModelAction *postreadfrom = lastact->get_reads_from();
1633                                 if (postreadfrom != NULL && rf != postreadfrom)
1634                                         mo_graph->addEdge(rf, postreadfrom);
1635                         } else {
1636                                 //Case 3: The resolved read is a normal read and the next
1637                                 //operation is a write, and we need to make sure that the
1638                                 //write is mod ordered after rf
1639                                 if (lastact != rf)
1640                                         mo_graph->addEdge(rf, lastact);
1641                         }
1642                         break;
1643                 }
1644         }
1645 }
1646
1647 /**
1648  * Updates the mo_graph with the constraints imposed from the current write.
1649  *
1650  * Basic idea is the following: Go through each other thread and find
1651  * the lastest action that happened before our write.  Two cases:
1652  *
1653  * (1) The action is a write => that write must occur before
1654  * the current write
1655  *
1656  * (2) The action is a read => the write that that action read from
1657  * must occur before the current write.
1658  *
1659  * This method also handles two other issues:
1660  *
1661  * (I) Sequential Consistency: Making sure that if the current write is
1662  * seq_cst, that it occurs after the previous seq_cst write.
1663  *
1664  * (II) Sending the write back to non-synchronizing reads.
1665  *
1666  * @param curr The current action. Must be a write.
1667  * @return True if modification order edges were added; false otherwise
1668  */
1669 bool ModelChecker::w_modification_order(ModelAction *curr)
1670 {
1671         std::vector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
1672         unsigned int i;
1673         bool added = false;
1674         ASSERT(curr->is_write());
1675
1676         if (curr->is_seqcst()) {
1677                 /* We have to at least see the last sequentially consistent write,
1678                          so we are initialized. */
1679                 ModelAction *last_seq_cst = get_last_seq_cst_write(curr);
1680                 if (last_seq_cst != NULL) {
1681                         mo_graph->addEdge(last_seq_cst, curr);
1682                         added = true;
1683                 }
1684         }
1685
1686         /* Last SC fence in the current thread */
1687         ModelAction *last_sc_fence_local = get_last_seq_cst_fence(curr->get_tid(), NULL);
1688
1689         /* Iterate over all threads */
1690         for (i = 0; i < thrd_lists->size(); i++) {
1691                 /* Last SC fence in thread i, before last SC fence in current thread */
1692                 ModelAction *last_sc_fence_thread_before = NULL;
1693                 if (last_sc_fence_local && int_to_id((int)i) != curr->get_tid())
1694                         last_sc_fence_thread_before = get_last_seq_cst_fence(int_to_id(i), last_sc_fence_local);
1695
1696                 /* Iterate over actions in thread, starting from most recent */
1697                 action_list_t *list = &(*thrd_lists)[i];
1698                 action_list_t::reverse_iterator rit;
1699                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
1700                         ModelAction *act = *rit;
1701                         if (act == curr) {
1702                                 /*
1703                                  * 1) If RMW and it actually read from something, then we
1704                                  * already have all relevant edges, so just skip to next
1705                                  * thread.
1706                                  *
1707                                  * 2) If RMW and it didn't read from anything, we should
1708                                  * whatever edge we can get to speed up convergence.
1709                                  *
1710                                  * 3) If normal write, we need to look at earlier actions, so
1711                                  * continue processing list.
1712                                  */
1713                                 if (curr->is_rmw()) {
1714                                         if (curr->get_reads_from() != NULL)
1715                                                 break;
1716                                         else
1717                                                 continue;
1718                                 } else
1719                                         continue;
1720                         }
1721
1722                         /* C++, Section 29.3 statement 7 */
1723                         if (last_sc_fence_thread_before && act->is_write() &&
1724                                         *act < *last_sc_fence_thread_before) {
1725                                 mo_graph->addEdge(act, curr);
1726                                 added = true;
1727                                 break;
1728                         }
1729
1730                         /*
1731                          * Include at most one act per-thread that "happens
1732                          * before" curr
1733                          */
1734                         if (act->happens_before(curr)) {
1735                                 /*
1736                                  * Note: if act is RMW, just add edge:
1737                                  *   act --mo--> curr
1738                                  * The following edge should be handled elsewhere:
1739                                  *   readfrom(act) --mo--> act
1740                                  */
1741                                 if (act->is_write())
1742                                         mo_graph->addEdge(act, curr);
1743                                 else if (act->is_read()) {
1744                                         //if previous read accessed a null, just keep going
1745                                         if (act->get_reads_from() == NULL)
1746                                                 continue;
1747                                         mo_graph->addEdge(act->get_reads_from(), curr);
1748                                 }
1749                                 added = true;
1750                                 break;
1751                         } else if (act->is_read() && !act->could_synchronize_with(curr) &&
1752                                                      !act->same_thread(curr)) {
1753                                 /* We have an action that:
1754                                    (1) did not happen before us
1755                                    (2) is a read and we are a write
1756                                    (3) cannot synchronize with us
1757                                    (4) is in a different thread
1758                                    =>
1759                                    that read could potentially read from our write.  Note that
1760                                    these checks are overly conservative at this point, we'll
1761                                    do more checks before actually removing the
1762                                    pendingfuturevalue.
1763
1764                                  */
1765                                 if (thin_air_constraint_may_allow(curr, act)) {
1766                                         if (!is_infeasible() ||
1767                                                         (curr->is_rmw() && act->is_rmw() && curr->get_reads_from() == act->get_reads_from() && !is_infeasible_ignoreRMW())) {
1768                                                 struct PendingFutureValue pfv = {curr, act};
1769                                                 futurevalues->push_back(pfv);
1770                                         }
1771                                 }
1772                         }
1773                 }
1774         }
1775
1776         return added;
1777 }
1778
1779 /** Arbitrary reads from the future are not allowed.  Section 29.3
1780  * part 9 places some constraints.  This method checks one result of constraint
1781  * constraint.  Others require compiler support. */
1782 bool ModelChecker::thin_air_constraint_may_allow(const ModelAction *writer, const ModelAction *reader)
1783 {
1784         if (!writer->is_rmw())
1785                 return true;
1786
1787         if (!reader->is_rmw())
1788                 return true;
1789
1790         for (const ModelAction *search = writer->get_reads_from(); search != NULL; search = search->get_reads_from()) {
1791                 if (search == reader)
1792                         return false;
1793                 if (search->get_tid() == reader->get_tid() &&
1794                                 search->happens_before(reader))
1795                         break;
1796         }
1797
1798         return true;
1799 }
1800
1801 /**
1802  * Arbitrary reads from the future are not allowed. Section 29.3 part 9 places
1803  * some constraints. This method checks one the following constraint (others
1804  * require compiler support):
1805  *
1806  *   If X --hb-> Y --mo-> Z, then X should not read from Z.
1807  */
1808 bool ModelChecker::mo_may_allow(const ModelAction *writer, const ModelAction *reader)
1809 {
1810         std::vector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, reader->get_location());
1811         unsigned int i;
1812         /* Iterate over all threads */
1813         for (i = 0; i < thrd_lists->size(); i++) {
1814                 const ModelAction *write_after_read = NULL;
1815
1816                 /* Iterate over actions in thread, starting from most recent */
1817                 action_list_t *list = &(*thrd_lists)[i];
1818                 action_list_t::reverse_iterator rit;
1819                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
1820                         ModelAction *act = *rit;
1821
1822                         /* Don't disallow due to act == reader */
1823                         if (!reader->happens_before(act) || reader == act)
1824                                 break;
1825                         else if (act->is_write())
1826                                 write_after_read = act;
1827                         else if (act->is_read() && act->get_reads_from() != NULL)
1828                                 write_after_read = act->get_reads_from();
1829                 }
1830
1831                 if (write_after_read && write_after_read != writer && mo_graph->checkReachable(write_after_read, writer))
1832                         return false;
1833         }
1834         return true;
1835 }
1836
1837 /**
1838  * Finds the head(s) of the release sequence(s) containing a given ModelAction.
1839  * The ModelAction under consideration is expected to be taking part in
1840  * release/acquire synchronization as an object of the "reads from" relation.
1841  * Note that this can only provide release sequence support for RMW chains
1842  * which do not read from the future, as those actions cannot be traced until
1843  * their "promise" is fulfilled. Similarly, we may not even establish the
1844  * presence of a release sequence with certainty, as some modification order
1845  * constraints may be decided further in the future. Thus, this function
1846  * "returns" two pieces of data: a pass-by-reference vector of @a release_heads
1847  * and a boolean representing certainty.
1848  *
1849  * @param rf The action that might be part of a release sequence. Must be a
1850  * write.
1851  * @param release_heads A pass-by-reference style return parameter. After
1852  * execution of this function, release_heads will contain the heads of all the
1853  * relevant release sequences, if any exists with certainty
1854  * @param pending A pass-by-reference style return parameter which is only used
1855  * when returning false (i.e., uncertain). Returns most information regarding
1856  * an uncertain release sequence, including any write operations that might
1857  * break the sequence.
1858  * @return true, if the ModelChecker is certain that release_heads is complete;
1859  * false otherwise
1860  */
1861 bool ModelChecker::release_seq_heads(const ModelAction *rf,
1862                 rel_heads_list_t *release_heads,
1863                 struct release_seq *pending) const
1864 {
1865         /* Only check for release sequences if there are no cycles */
1866         if (mo_graph->checkForCycles())
1867                 return false;
1868
1869         while (rf) {
1870                 ASSERT(rf->is_write());
1871
1872                 if (rf->is_release())
1873                         release_heads->push_back(rf);
1874                 else if (rf->get_last_fence_release())
1875                         release_heads->push_back(rf->get_last_fence_release());
1876                 if (!rf->is_rmw())
1877                         break; /* End of RMW chain */
1878
1879                 /** @todo Need to be smarter here...  In the linux lock
1880                  * example, this will run to the beginning of the program for
1881                  * every acquire. */
1882                 /** @todo The way to be smarter here is to keep going until 1
1883                  * thread has a release preceded by an acquire and you've seen
1884                  *       both. */
1885
1886                 /* acq_rel RMW is a sufficient stopping condition */
1887                 if (rf->is_acquire() && rf->is_release())
1888                         return true; /* complete */
1889
1890                 rf = rf->get_reads_from();
1891         };
1892         if (!rf) {
1893                 /* read from future: need to settle this later */
1894                 pending->rf = NULL;
1895                 return false; /* incomplete */
1896         }
1897
1898         if (rf->is_release())
1899                 return true; /* complete */
1900
1901         /* else relaxed write
1902          * - check for fence-release in the same thread (29.8, stmt. 3)
1903          * - check modification order for contiguous subsequence
1904          *   -> rf must be same thread as release */
1905
1906         const ModelAction *fence_release = rf->get_last_fence_release();
1907         /* Synchronize with a fence-release unconditionally; we don't need to
1908          * find any more "contiguous subsequence..." for it */
1909         if (fence_release)
1910                 release_heads->push_back(fence_release);
1911
1912         int tid = id_to_int(rf->get_tid());
1913         std::vector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, rf->get_location());
1914         action_list_t *list = &(*thrd_lists)[tid];
1915         action_list_t::const_reverse_iterator rit;
1916
1917         /* Find rf in the thread list */
1918         rit = std::find(list->rbegin(), list->rend(), rf);
1919         ASSERT(rit != list->rend());
1920
1921         /* Find the last {write,fence}-release */
1922         for (; rit != list->rend(); rit++) {
1923                 if (fence_release && *(*rit) < *fence_release)
1924                         break;
1925                 if ((*rit)->is_release())
1926                         break;
1927         }
1928         if (rit == list->rend()) {
1929                 /* No write-release in this thread */
1930                 return true; /* complete */
1931         } else if (fence_release && *(*rit) < *fence_release) {
1932                 /* The fence-release is more recent (and so, "stronger") than
1933                  * the most recent write-release */
1934                 return true; /* complete */
1935         } /* else, need to establish contiguous release sequence */
1936         ModelAction *release = *rit;
1937
1938         ASSERT(rf->same_thread(release));
1939
1940         pending->writes.clear();
1941
1942         bool certain = true;
1943         for (unsigned int i = 0; i < thrd_lists->size(); i++) {
1944                 if (id_to_int(rf->get_tid()) == (int)i)
1945                         continue;
1946                 list = &(*thrd_lists)[i];
1947
1948                 /* Can we ensure no future writes from this thread may break
1949                  * the release seq? */
1950                 bool future_ordered = false;
1951
1952                 ModelAction *last = get_last_action(int_to_id(i));
1953                 Thread *th = get_thread(int_to_id(i));
1954                 if ((last && rf->happens_before(last)) ||
1955                                 !is_enabled(th) ||
1956                                 th->is_complete())
1957                         future_ordered = true;
1958
1959                 ASSERT(!th->is_model_thread() || future_ordered);
1960
1961                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
1962                         const ModelAction *act = *rit;
1963                         /* Reach synchronization -> this thread is complete */
1964                         if (act->happens_before(release))
1965                                 break;
1966                         if (rf->happens_before(act)) {
1967                                 future_ordered = true;
1968                                 continue;
1969                         }
1970
1971                         /* Only non-RMW writes can break release sequences */
1972                         if (!act->is_write() || act->is_rmw())
1973                                 continue;
1974
1975                         /* Check modification order */
1976                         if (mo_graph->checkReachable(rf, act)) {
1977                                 /* rf --mo--> act */
1978                                 future_ordered = true;
1979                                 continue;
1980                         }
1981                         if (mo_graph->checkReachable(act, release))
1982                                 /* act --mo--> release */
1983                                 break;
1984                         if (mo_graph->checkReachable(release, act) &&
1985                                       mo_graph->checkReachable(act, rf)) {
1986                                 /* release --mo-> act --mo--> rf */
1987                                 return true; /* complete */
1988                         }
1989                         /* act may break release sequence */
1990                         pending->writes.push_back(act);
1991                         certain = false;
1992                 }
1993                 if (!future_ordered)
1994                         certain = false; /* This thread is uncertain */
1995         }
1996
1997         if (certain) {
1998                 release_heads->push_back(release);
1999                 pending->writes.clear();
2000         } else {
2001                 pending->release = release;
2002                 pending->rf = rf;
2003         }
2004         return certain;
2005 }
2006
2007 /**
2008  * An interface for getting the release sequence head(s) with which a
2009  * given ModelAction must synchronize. This function only returns a non-empty
2010  * result when it can locate a release sequence head with certainty. Otherwise,
2011  * it may mark the internal state of the ModelChecker so that it will handle
2012  * the release sequence at a later time, causing @a acquire to update its
2013  * synchronization at some later point in execution.
2014  *
2015  * @param acquire The 'acquire' action that may synchronize with a release
2016  * sequence
2017  * @param read The read action that may read from a release sequence; this may
2018  * be the same as acquire, or else an earlier action in the same thread (i.e.,
2019  * when 'acquire' is a fence-acquire)
2020  * @param release_heads A pass-by-reference return parameter. Will be filled
2021  * with the head(s) of the release sequence(s), if they exists with certainty.
2022  * @see ModelChecker::release_seq_heads
2023  */
2024 void ModelChecker::get_release_seq_heads(ModelAction *acquire,
2025                 ModelAction *read, rel_heads_list_t *release_heads)
2026 {
2027         const ModelAction *rf = read->get_reads_from();
2028         struct release_seq *sequence = (struct release_seq *)snapshot_calloc(1, sizeof(struct release_seq));
2029         sequence->acquire = acquire;
2030         sequence->read = read;
2031
2032         if (!release_seq_heads(rf, release_heads, sequence)) {
2033                 /* add act to 'lazy checking' list */
2034                 pending_rel_seqs->push_back(sequence);
2035         } else {
2036                 snapshot_free(sequence);
2037         }
2038 }
2039
2040 /**
2041  * Attempt to resolve all stashed operations that might synchronize with a
2042  * release sequence for a given location. This implements the "lazy" portion of
2043  * determining whether or not a release sequence was contiguous, since not all
2044  * modification order information is present at the time an action occurs.
2045  *
2046  * @param location The location/object that should be checked for release
2047  * sequence resolutions. A NULL value means to check all locations.
2048  * @param work_queue The work queue to which to add work items as they are
2049  * generated
2050  * @return True if any updates occurred (new synchronization, new mo_graph
2051  * edges)
2052  */
2053 bool ModelChecker::resolve_release_sequences(void *location, work_queue_t *work_queue)
2054 {
2055         bool updated = false;
2056         std::vector< struct release_seq *, SnapshotAlloc<struct release_seq *> >::iterator it = pending_rel_seqs->begin();
2057         while (it != pending_rel_seqs->end()) {
2058                 struct release_seq *pending = *it;
2059                 ModelAction *acquire = pending->acquire;
2060                 const ModelAction *read = pending->read;
2061
2062                 /* Only resolve sequences on the given location, if provided */
2063                 if (location && read->get_location() != location) {
2064                         it++;
2065                         continue;
2066                 }
2067
2068                 const ModelAction *rf = read->get_reads_from();
2069                 rel_heads_list_t release_heads;
2070                 bool complete;
2071                 complete = release_seq_heads(rf, &release_heads, pending);
2072                 for (unsigned int i = 0; i < release_heads.size(); i++) {
2073                         if (!acquire->has_synchronized_with(release_heads[i])) {
2074                                 if (acquire->synchronize_with(release_heads[i]))
2075                                         updated = true;
2076                                 else
2077                                         set_bad_synchronization();
2078                         }
2079                 }
2080
2081                 if (updated) {
2082                         /* Re-check all pending release sequences */
2083                         work_queue->push_back(CheckRelSeqWorkEntry(NULL));
2084                         /* Re-check read-acquire for mo_graph edges */
2085                         if (acquire->is_read())
2086                                 work_queue->push_back(MOEdgeWorkEntry(acquire));
2087
2088                         /* propagate synchronization to later actions */
2089                         action_list_t::reverse_iterator rit = action_trace->rbegin();
2090                         for (; (*rit) != acquire; rit++) {
2091                                 ModelAction *propagate = *rit;
2092                                 if (acquire->happens_before(propagate)) {
2093                                         propagate->synchronize_with(acquire);
2094                                         /* Re-check 'propagate' for mo_graph edges */
2095                                         work_queue->push_back(MOEdgeWorkEntry(propagate));
2096                                 }
2097                         }
2098                 }
2099                 if (complete) {
2100                         it = pending_rel_seqs->erase(it);
2101                         snapshot_free(pending);
2102                 } else {
2103                         it++;
2104                 }
2105         }
2106
2107         // If we resolved promises or data races, see if we have realized a data race.
2108         checkDataRaces();
2109
2110         return updated;
2111 }
2112
2113 /**
2114  * Performs various bookkeeping operations for the current ModelAction. For
2115  * instance, adds action to the per-object, per-thread action vector and to the
2116  * action trace list of all thread actions.
2117  *
2118  * @param act is the ModelAction to add.
2119  */
2120 void ModelChecker::add_action_to_lists(ModelAction *act)
2121 {
2122         int tid = id_to_int(act->get_tid());
2123         ModelAction *uninit = NULL;
2124         int uninit_id = -1;
2125         action_list_t *list = get_safe_ptr_action(obj_map, act->get_location());
2126         if (list->empty() && act->is_atomic_var()) {
2127                 uninit = new_uninitialized_action(act->get_location());
2128                 uninit_id = id_to_int(uninit->get_tid());
2129                 list->push_back(uninit);
2130         }
2131         list->push_back(act);
2132
2133         action_trace->push_back(act);
2134         if (uninit)
2135                 action_trace->push_front(uninit);
2136
2137         std::vector<action_list_t> *vec = get_safe_ptr_vect_action(obj_thrd_map, act->get_location());
2138         if (tid >= (int)vec->size())
2139                 vec->resize(priv->next_thread_id);
2140         (*vec)[tid].push_back(act);
2141         if (uninit)
2142                 (*vec)[uninit_id].push_front(uninit);
2143
2144         if ((int)thrd_last_action->size() <= tid)
2145                 thrd_last_action->resize(get_num_threads());
2146         (*thrd_last_action)[tid] = act;
2147         if (uninit)
2148                 (*thrd_last_action)[uninit_id] = uninit;
2149
2150         if (act->is_fence() && act->is_release()) {
2151                 if ((int)thrd_last_fence_release->size() <= tid)
2152                         thrd_last_fence_release->resize(get_num_threads());
2153                 (*thrd_last_fence_release)[tid] = act;
2154         }
2155
2156         if (act->is_wait()) {
2157                 void *mutex_loc = (void *) act->get_value();
2158                 get_safe_ptr_action(obj_map, mutex_loc)->push_back(act);
2159
2160                 std::vector<action_list_t> *vec = get_safe_ptr_vect_action(obj_thrd_map, mutex_loc);
2161                 if (tid >= (int)vec->size())
2162                         vec->resize(priv->next_thread_id);
2163                 (*vec)[tid].push_back(act);
2164         }
2165 }
2166
2167 /**
2168  * @brief Get the last action performed by a particular Thread
2169  * @param tid The thread ID of the Thread in question
2170  * @return The last action in the thread
2171  */
2172 ModelAction * ModelChecker::get_last_action(thread_id_t tid) const
2173 {
2174         int threadid = id_to_int(tid);
2175         if (threadid < (int)thrd_last_action->size())
2176                 return (*thrd_last_action)[id_to_int(tid)];
2177         else
2178                 return NULL;
2179 }
2180
2181 /**
2182  * @brief Get the last fence release performed by a particular Thread
2183  * @param tid The thread ID of the Thread in question
2184  * @return The last fence release in the thread, if one exists; NULL otherwise
2185  */
2186 ModelAction * ModelChecker::get_last_fence_release(thread_id_t tid) const
2187 {
2188         int threadid = id_to_int(tid);
2189         if (threadid < (int)thrd_last_fence_release->size())
2190                 return (*thrd_last_fence_release)[id_to_int(tid)];
2191         else
2192                 return NULL;
2193 }
2194
2195 /**
2196  * Gets the last memory_order_seq_cst write (in the total global sequence)
2197  * performed on a particular object (i.e., memory location), not including the
2198  * current action.
2199  * @param curr The current ModelAction; also denotes the object location to
2200  * check
2201  * @return The last seq_cst write
2202  */
2203 ModelAction * ModelChecker::get_last_seq_cst_write(ModelAction *curr) const
2204 {
2205         void *location = curr->get_location();
2206         action_list_t *list = get_safe_ptr_action(obj_map, location);
2207         /* Find: max({i in dom(S) | seq_cst(t_i) && isWrite(t_i) && samevar(t_i, t)}) */
2208         action_list_t::reverse_iterator rit;
2209         for (rit = list->rbegin(); rit != list->rend(); rit++)
2210                 if ((*rit)->is_write() && (*rit)->is_seqcst() && (*rit) != curr)
2211                         return *rit;
2212         return NULL;
2213 }
2214
2215 /**
2216  * Gets the last memory_order_seq_cst fence (in the total global sequence)
2217  * performed in a particular thread, prior to a particular fence.
2218  * @param tid The ID of the thread to check
2219  * @param before_fence The fence from which to begin the search; if NULL, then
2220  * search for the most recent fence in the thread.
2221  * @return The last prior seq_cst fence in the thread, if exists; otherwise, NULL
2222  */
2223 ModelAction * ModelChecker::get_last_seq_cst_fence(thread_id_t tid, const ModelAction *before_fence) const
2224 {
2225         /* All fences should have NULL location */
2226         action_list_t *list = get_safe_ptr_action(obj_map, NULL);
2227         action_list_t::reverse_iterator rit = list->rbegin();
2228
2229         if (before_fence) {
2230                 for (; rit != list->rend(); rit++)
2231                         if (*rit == before_fence)
2232                                 break;
2233
2234                 ASSERT(*rit == before_fence);
2235                 rit++;
2236         }
2237
2238         for (; rit != list->rend(); rit++)
2239                 if ((*rit)->is_fence() && (tid == (*rit)->get_tid()) && (*rit)->is_seqcst())
2240                         return *rit;
2241         return NULL;
2242 }
2243
2244 /**
2245  * Gets the last unlock operation performed on a particular mutex (i.e., memory
2246  * location). This function identifies the mutex according to the current
2247  * action, which is presumed to perform on the same mutex.
2248  * @param curr The current ModelAction; also denotes the object location to
2249  * check
2250  * @return The last unlock operation
2251  */
2252 ModelAction * ModelChecker::get_last_unlock(ModelAction *curr) const
2253 {
2254         void *location = curr->get_location();
2255         action_list_t *list = get_safe_ptr_action(obj_map, location);
2256         /* Find: max({i in dom(S) | isUnlock(t_i) && samevar(t_i, t)}) */
2257         action_list_t::reverse_iterator rit;
2258         for (rit = list->rbegin(); rit != list->rend(); rit++)
2259                 if ((*rit)->is_unlock() || (*rit)->is_wait())
2260                         return *rit;
2261         return NULL;
2262 }
2263
2264 ModelAction * ModelChecker::get_parent_action(thread_id_t tid) const
2265 {
2266         ModelAction *parent = get_last_action(tid);
2267         if (!parent)
2268                 parent = get_thread(tid)->get_creation();
2269         return parent;
2270 }
2271
2272 /**
2273  * Returns the clock vector for a given thread.
2274  * @param tid The thread whose clock vector we want
2275  * @return Desired clock vector
2276  */
2277 ClockVector * ModelChecker::get_cv(thread_id_t tid) const
2278 {
2279         return get_parent_action(tid)->get_cv();
2280 }
2281
2282 /**
2283  * Resolve a set of Promises with a current write. The set is provided in the
2284  * Node corresponding to @a write.
2285  * @param write The ModelAction that is fulfilling Promises
2286  * @return True if promises were resolved; false otherwise
2287  */
2288 bool ModelChecker::resolve_promises(ModelAction *write)
2289 {
2290         bool resolved = false;
2291         std::vector< thread_id_t, ModelAlloc<thread_id_t> > threads_to_check;
2292
2293         for (unsigned int i = 0, promise_index = 0; promise_index < promises->size(); i++) {
2294                 Promise *promise = (*promises)[promise_index];
2295                 if (write->get_node()->get_promise(i)) {
2296                         ModelAction *read = promise->get_action();
2297                         if (read->is_rmw()) {
2298                                 mo_graph->addRMWEdge(write, read);
2299                         }
2300                         read_from(read, write);
2301                         //First fix up the modification order for actions that happened
2302                         //before the read
2303                         r_modification_order(read, write);
2304                         //Next fix up the modification order for actions that happened
2305                         //after the read.
2306                         post_r_modification_order(read, write);
2307                         //Make sure the promise's value matches the write's value
2308                         ASSERT(promise->get_value() == write->get_value());
2309                         delete(promise);
2310
2311                         promises->erase(promises->begin() + promise_index);
2312                         threads_to_check.push_back(read->get_tid());
2313
2314                         resolved = true;
2315                 } else
2316                         promise_index++;
2317         }
2318
2319         //Check whether reading these writes has made threads unable to
2320         //resolve promises
2321
2322         for (unsigned int i = 0; i < threads_to_check.size(); i++)
2323                 mo_check_promises(threads_to_check[i], write);
2324
2325         return resolved;
2326 }
2327
2328 /**
2329  * Compute the set of promises that could potentially be satisfied by this
2330  * action. Note that the set computation actually appears in the Node, not in
2331  * ModelChecker.
2332  * @param curr The ModelAction that may satisfy promises
2333  */
2334 void ModelChecker::compute_promises(ModelAction *curr)
2335 {
2336         for (unsigned int i = 0; i < promises->size(); i++) {
2337                 Promise *promise = (*promises)[i];
2338                 const ModelAction *act = promise->get_action();
2339                 if (!act->happens_before(curr) &&
2340                                 act->is_read() &&
2341                                 !act->could_synchronize_with(curr) &&
2342                                 !act->same_thread(curr) &&
2343                                 act->get_location() == curr->get_location() &&
2344                                 promise->get_value() == curr->get_value()) {
2345                         curr->get_node()->set_promise(i, act->is_rmw());
2346                 }
2347         }
2348 }
2349
2350 /** Checks promises in response to change in ClockVector Threads. */
2351 void ModelChecker::check_promises(thread_id_t tid, ClockVector *old_cv, ClockVector *merge_cv)
2352 {
2353         for (unsigned int i = 0; i < promises->size(); i++) {
2354                 Promise *promise = (*promises)[i];
2355                 const ModelAction *act = promise->get_action();
2356                 if ((old_cv == NULL || !old_cv->synchronized_since(act)) &&
2357                                 merge_cv->synchronized_since(act)) {
2358                         if (promise->increment_threads(tid)) {
2359                                 //Promise has failed
2360                                 priv->failed_promise = true;
2361                                 return;
2362                         }
2363                 }
2364         }
2365 }
2366
2367 void ModelChecker::check_promises_thread_disabled() {
2368         for (unsigned int i = 0; i < promises->size(); i++) {
2369                 Promise *promise = (*promises)[i];
2370                 if (promise->check_promise()) {
2371                         priv->failed_promise = true;
2372                         return;
2373                 }
2374         }
2375 }
2376
2377 /** Checks promises in response to addition to modification order for threads.
2378  * Definitions:
2379  * pthread is the thread that performed the read that created the promise
2380  *
2381  * pread is the read that created the promise
2382  *
2383  * pwrite is either the first write to same location as pread by
2384  * pthread that is sequenced after pread or the value read by the
2385  * first read to the same lcoation as pread by pthread that is
2386  * sequenced after pread..
2387  *
2388  *      1. If tid=pthread, then we check what other threads are reachable
2389  * through the mode order starting with pwrite.  Those threads cannot
2390  * perform a write that will resolve the promise due to modification
2391  * order constraints.
2392  *
2393  * 2. If the tid is not pthread, we check whether pwrite can reach the
2394  * action write through the modification order.  If so, that thread
2395  * cannot perform a future write that will resolve the promise due to
2396  * modificatin order constraints.
2397  *
2398  *      @param tid The thread that either read from the model action
2399  *      write, or actually did the model action write.
2400  *
2401  *      @param write The ModelAction representing the relevant write.
2402  */
2403 void ModelChecker::mo_check_promises(thread_id_t tid, const ModelAction *write)
2404 {
2405         void *location = write->get_location();
2406         for (unsigned int i = 0; i < promises->size(); i++) {
2407                 Promise *promise = (*promises)[i];
2408                 const ModelAction *act = promise->get_action();
2409
2410                 //Is this promise on the same location?
2411                 if (act->get_location() != location)
2412                         continue;
2413
2414                 //same thread as the promise
2415                 if (act->get_tid() == tid) {
2416
2417                         //do we have a pwrite for the promise, if not, set it
2418                         if (promise->get_write() == NULL) {
2419                                 promise->set_write(write);
2420                                 //The pwrite cannot happen before the promise
2421                                 if (write->happens_before(act) && (write != act)) {
2422                                         priv->failed_promise = true;
2423                                         return;
2424                                 }
2425                         }
2426                         if (mo_graph->checkPromise(write, promise)) {
2427                                 priv->failed_promise = true;
2428                                 return;
2429                         }
2430                 }
2431
2432                 //Don't do any lookups twice for the same thread
2433                 if (promise->has_sync_thread(tid))
2434                         continue;
2435
2436                 if (promise->get_write() && mo_graph->checkReachable(promise->get_write(), write)) {
2437                         if (promise->increment_threads(tid)) {
2438                                 priv->failed_promise = true;
2439                                 return;
2440                         }
2441                 }
2442         }
2443 }
2444
2445 /**
2446  * Compute the set of writes that may break the current pending release
2447  * sequence. This information is extracted from previou release sequence
2448  * calculations.
2449  *
2450  * @param curr The current ModelAction. Must be a release sequence fixup
2451  * action.
2452  */
2453 void ModelChecker::compute_relseq_breakwrites(ModelAction *curr)
2454 {
2455         if (pending_rel_seqs->empty())
2456                 return;
2457
2458         struct release_seq *pending = pending_rel_seqs->back();
2459         for (unsigned int i = 0; i < pending->writes.size(); i++) {
2460                 const ModelAction *write = pending->writes[i];
2461                 curr->get_node()->add_relseq_break(write);
2462         }
2463
2464         /* NULL means don't break the sequence; just synchronize */
2465         curr->get_node()->add_relseq_break(NULL);
2466 }
2467
2468 /**
2469  * Build up an initial set of all past writes that this 'read' action may read
2470  * from. This set is determined by the clock vector's "happens before"
2471  * relationship.
2472  * @param curr is the current ModelAction that we are exploring; it must be a
2473  * 'read' operation.
2474  */
2475 void ModelChecker::build_reads_from_past(ModelAction *curr)
2476 {
2477         std::vector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
2478         unsigned int i;
2479         ASSERT(curr->is_read());
2480
2481         ModelAction *last_sc_write = NULL;
2482
2483         if (curr->is_seqcst())
2484                 last_sc_write = get_last_seq_cst_write(curr);
2485
2486         /* Iterate over all threads */
2487         for (i = 0; i < thrd_lists->size(); i++) {
2488                 /* Iterate over actions in thread, starting from most recent */
2489                 action_list_t *list = &(*thrd_lists)[i];
2490                 action_list_t::reverse_iterator rit;
2491                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
2492                         ModelAction *act = *rit;
2493
2494                         /* Only consider 'write' actions */
2495                         if (!act->is_write() || act == curr)
2496                                 continue;
2497
2498                         /* Don't consider more than one seq_cst write if we are a seq_cst read. */
2499                         bool allow_read = true;
2500
2501                         if (curr->is_seqcst() && (act->is_seqcst() || (last_sc_write != NULL && act->happens_before(last_sc_write))) && act != last_sc_write)
2502                                 allow_read = false;
2503                         else if (curr->get_sleep_flag() && !curr->is_seqcst() && !sleep_can_read_from(curr, act))
2504                                 allow_read = false;
2505
2506                         if (allow_read) {
2507                                 DEBUG("Adding action to may_read_from:\n");
2508                                 if (DBG_ENABLED()) {
2509                                         act->print();
2510                                         curr->print();
2511                                 }
2512                                 curr->get_node()->add_read_from(act);
2513                         }
2514
2515                         /* Include at most one act per-thread that "happens before" curr */
2516                         if (act->happens_before(curr))
2517                                 break;
2518                 }
2519         }
2520
2521         if (DBG_ENABLED()) {
2522                 model_print("Reached read action:\n");
2523                 curr->print();
2524                 model_print("Printing may_read_from\n");
2525                 curr->get_node()->print_may_read_from();
2526                 model_print("End printing may_read_from\n");
2527         }
2528 }
2529
2530 bool ModelChecker::sleep_can_read_from(ModelAction *curr, const ModelAction *write)
2531 {
2532         while (true) {
2533                 /* UNINIT actions don't have a Node, and they never sleep */
2534                 if (write->is_uninitialized())
2535                         return true;
2536                 Node *prevnode = write->get_node()->get_parent();
2537
2538                 bool thread_sleep = prevnode->enabled_status(curr->get_tid()) == THREAD_SLEEP_SET;
2539                 if (write->is_release() && thread_sleep)
2540                         return true;
2541                 if (!write->is_rmw()) {
2542                         return false;
2543                 }
2544                 if (write->get_reads_from() == NULL)
2545                         return true;
2546                 write = write->get_reads_from();
2547         }
2548 }
2549
2550 /**
2551  * @brief Create a new action representing an uninitialized atomic
2552  * @param location The memory location of the atomic object
2553  * @return A pointer to a new ModelAction
2554  */
2555 ModelAction * ModelChecker::new_uninitialized_action(void *location) const
2556 {
2557         ModelAction *act = (ModelAction *)snapshot_malloc(sizeof(class ModelAction));
2558         act = new (act) ModelAction(ATOMIC_UNINIT, std::memory_order_relaxed, location, 0, model_thread);
2559         act->create_cv(NULL);
2560         return act;
2561 }
2562
2563 static void print_list(action_list_t *list, int exec_num = -1)
2564 {
2565         action_list_t::iterator it;
2566
2567         model_print("---------------------------------------------------------------------\n");
2568         if (exec_num >= 0)
2569                 model_print("Execution %d:\n", exec_num);
2570
2571         unsigned int hash = 0;
2572
2573         for (it = list->begin(); it != list->end(); it++) {
2574                 (*it)->print();
2575                 hash = hash^(hash<<3)^((*it)->hash());
2576         }
2577         model_print("HASH %u\n", hash);
2578         model_print("---------------------------------------------------------------------\n");
2579 }
2580
2581 #if SUPPORT_MOD_ORDER_DUMP
2582 void ModelChecker::dumpGraph(char *filename) const
2583 {
2584         char buffer[200];
2585         sprintf(buffer, "%s.dot", filename);
2586         FILE *file = fopen(buffer, "w");
2587         fprintf(file, "digraph %s {\n", filename);
2588         mo_graph->dumpNodes(file);
2589         ModelAction **thread_array = (ModelAction **)model_calloc(1, sizeof(ModelAction *) * get_num_threads());
2590
2591         for (action_list_t::iterator it = action_trace->begin(); it != action_trace->end(); it++) {
2592                 ModelAction *action = *it;
2593                 if (action->is_read()) {
2594                         fprintf(file, "N%u [label=\"%u, T%u\"];\n", action->get_seq_number(), action->get_seq_number(), action->get_tid());
2595                         if (action->get_reads_from() != NULL)
2596                                 fprintf(file, "N%u -> N%u[label=\"rf\", color=red];\n", action->get_seq_number(), action->get_reads_from()->get_seq_number());
2597                 }
2598                 if (thread_array[action->get_tid()] != NULL) {
2599                         fprintf(file, "N%u -> N%u[label=\"sb\", color=blue];\n", thread_array[action->get_tid()]->get_seq_number(), action->get_seq_number());
2600                 }
2601
2602                 thread_array[action->get_tid()] = action;
2603         }
2604         fprintf(file, "}\n");
2605         model_free(thread_array);
2606         fclose(file);
2607 }
2608 #endif
2609
2610 /** @brief Prints an execution trace summary. */
2611 void ModelChecker::print_summary() const
2612 {
2613 #if SUPPORT_MOD_ORDER_DUMP
2614         scheduler->print();
2615         char buffername[100];
2616         sprintf(buffername, "exec%04u", stats.num_total);
2617         mo_graph->dumpGraphToFile(buffername);
2618         sprintf(buffername, "graph%04u", stats.num_total);
2619         dumpGraph(buffername);
2620 #endif
2621
2622         if (!isfeasibleprefix())
2623                 model_print("INFEASIBLE EXECUTION!\n");
2624         print_list(action_trace, stats.num_total);
2625         model_print("\n");
2626 }
2627
2628 /**
2629  * Add a Thread to the system for the first time. Should only be called once
2630  * per thread.
2631  * @param t The Thread to add
2632  */
2633 void ModelChecker::add_thread(Thread *t)
2634 {
2635         thread_map->put(id_to_int(t->get_id()), t);
2636         scheduler->add_thread(t);
2637 }
2638
2639 /**
2640  * Removes a thread from the scheduler.
2641  * @param the thread to remove.
2642  */
2643 void ModelChecker::remove_thread(Thread *t)
2644 {
2645         scheduler->remove_thread(t);
2646 }
2647
2648 /**
2649  * @brief Get a Thread reference by its ID
2650  * @param tid The Thread's ID
2651  * @return A Thread reference
2652  */
2653 Thread * ModelChecker::get_thread(thread_id_t tid) const
2654 {
2655         return thread_map->get(id_to_int(tid));
2656 }
2657
2658 /**
2659  * @brief Get a reference to the Thread in which a ModelAction was executed
2660  * @param act The ModelAction
2661  * @return A Thread reference
2662  */
2663 Thread * ModelChecker::get_thread(ModelAction *act) const
2664 {
2665         return get_thread(act->get_tid());
2666 }
2667
2668 /**
2669  * @brief Check if a Thread is currently enabled
2670  * @param t The Thread to check
2671  * @return True if the Thread is currently enabled
2672  */
2673 bool ModelChecker::is_enabled(Thread *t) const
2674 {
2675         return scheduler->is_enabled(t);
2676 }
2677
2678 /**
2679  * @brief Check if a Thread is currently enabled
2680  * @param tid The ID of the Thread to check
2681  * @return True if the Thread is currently enabled
2682  */
2683 bool ModelChecker::is_enabled(thread_id_t tid) const
2684 {
2685         return scheduler->is_enabled(tid);
2686 }
2687
2688 /**
2689  * Switch from a user-context to the "master thread" context (a.k.a. system
2690  * context). This switch is made with the intention of exploring a particular
2691  * model-checking action (described by a ModelAction object). Must be called
2692  * from a user-thread context.
2693  *
2694  * @param act The current action that will be explored. May be NULL only if
2695  * trace is exiting via an assertion (see ModelChecker::set_assert and
2696  * ModelChecker::has_asserted).
2697  * @return Return the value returned by the current action
2698  */
2699 uint64_t ModelChecker::switch_to_master(ModelAction *act)
2700 {
2701         DBG();
2702         Thread *old = thread_current();
2703         set_current_action(act);
2704         old->set_state(THREAD_READY);
2705         if (Thread::swap(old, &system_context) < 0) {
2706                 perror("swap threads");
2707                 exit(EXIT_FAILURE);
2708         }
2709         return old->get_return_value();
2710 }
2711
2712 /**
2713  * Takes the next step in the execution, if possible.
2714  * @param curr The current step to take
2715  * @return Returns true (success) if a step was taken and false otherwise.
2716  */
2717 bool ModelChecker::take_step(ModelAction *curr)
2718 {
2719         if (has_asserted())
2720                 return false;
2721
2722         Thread *curr_thrd = get_thread(curr);
2723         ASSERT(curr_thrd->get_state() == THREAD_READY);
2724
2725         Thread *next_thrd = check_current_action(curr);
2726
2727         if (curr_thrd->is_blocked() || curr_thrd->is_complete())
2728                 scheduler->remove_thread(curr_thrd);
2729
2730         next_thrd = scheduler->next_thread(next_thrd);
2731
2732         /* Infeasible -> don't take any more steps */
2733         if (is_infeasible())
2734                 return false;
2735         else if (isfeasibleprefix() && have_bug_reports()) {
2736                 set_assert();
2737                 return false;
2738         }
2739
2740         if (params.bound != 0) {
2741                 if (priv->used_sequence_numbers > params.bound) {
2742                         return false;
2743                 }
2744         }
2745
2746         DEBUG("(%d, %d)\n", curr_thrd ? id_to_int(curr_thrd->get_id()) : -1,
2747                         next_thrd ? id_to_int(next_thrd->get_id()) : -1);
2748
2749         /*
2750          * Launch end-of-execution release sequence fixups only when there are:
2751          *
2752          * (1) no more user threads to run (or when execution replay chooses
2753          *     the 'model_thread')
2754          * (2) pending release sequences
2755          * (3) pending assertions (i.e., data races)
2756          * (4) no pending promises
2757          */
2758         if (!pending_rel_seqs->empty() && (!next_thrd || next_thrd->is_model_thread()) &&
2759                         is_feasible_prefix_ignore_relseq() && !unrealizedraces.empty()) {
2760                 model_print("*** WARNING: release sequence fixup action (%zu pending release seuqences) ***\n",
2761                                 pending_rel_seqs->size());
2762                 ModelAction *fixup = new ModelAction(MODEL_FIXUP_RELSEQ,
2763                                 std::memory_order_seq_cst, NULL, VALUE_NONE,
2764                                 model_thread);
2765                 set_current_action(fixup);
2766                 return true;
2767         }
2768
2769         /* next_thrd == NULL -> don't take any more steps */
2770         if (!next_thrd)
2771                 return false;
2772
2773         next_thrd->set_state(THREAD_RUNNING);
2774
2775         if (next_thrd->get_pending() != NULL) {
2776                 /* restart a pending action */
2777                 set_current_action(next_thrd->get_pending());
2778                 next_thrd->set_pending(NULL);
2779                 next_thrd->set_state(THREAD_READY);
2780                 return true;
2781         }
2782
2783         /* Return false only if swap fails with an error */
2784         return (Thread::swap(&system_context, next_thrd) == 0);
2785 }
2786
2787 /** Wrapper to run the user's main function, with appropriate arguments */
2788 void user_main_wrapper(void *)
2789 {
2790         user_main(model->params.argc, model->params.argv);
2791 }
2792
2793 /** @brief Run ModelChecker for the user program */
2794 void ModelChecker::run()
2795 {
2796         do {
2797                 thrd_t user_thread;
2798                 Thread *t = new Thread(&user_thread, &user_main_wrapper, NULL);
2799
2800                 add_thread(t);
2801
2802                 /* Run user thread up to its first action */
2803                 scheduler->next_thread(t);
2804                 Thread::swap(&system_context, t);
2805
2806                 /* Wait for all threads to complete */
2807                 while (take_step(priv->current_action));
2808         } while (next_execution());
2809
2810         print_stats();
2811 }