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