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