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