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