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