model: remove public check_promises() interface
[cdsspec-compiler.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 < *first) {
1450                 set_bad_synchronization();
1451                 return false;
1452         }
1453         check_promises(first->get_tid(), second->get_cv(), first->get_cv());
1454         return second->synchronize_with(first);
1455 }
1456
1457 /**
1458  * Check promises and eliminate potentially-satisfying threads when a thread is
1459  * blocked (e.g., join, lock). A thread which is waiting on another thread can
1460  * no longer satisfy a promise generated from that thread.
1461  *
1462  * @param blocker The thread on which a thread is waiting
1463  * @param waiting The waiting thread
1464  */
1465 void ModelChecker::thread_blocking_check_promises(Thread *blocker, Thread *waiting)
1466 {
1467         for (unsigned int i = 0; i < promises->size(); i++) {
1468                 Promise *promise = (*promises)[i];
1469                 if (!promise->thread_is_available(waiting->get_id()))
1470                         continue;
1471                 for (unsigned int j = 0; j < promise->get_num_readers(); j++) {
1472                         ModelAction *reader = promise->get_reader(j);
1473                         if (reader->get_tid() != blocker->get_id())
1474                                 continue;
1475                         if (promise->eliminate_thread(waiting->get_id())) {
1476                                 /* Promise has failed */
1477                                 priv->failed_promise = true;
1478                         } else {
1479                                 /* Only eliminate the 'waiting' thread once */
1480                                 return;
1481                         }
1482                 }
1483         }
1484 }
1485
1486 /**
1487  * @brief Check whether a model action is enabled.
1488  *
1489  * Checks whether a lock or join operation would be successful (i.e., is the
1490  * lock already locked, or is the joined thread already complete). If not, put
1491  * the action in a waiter list.
1492  *
1493  * @param curr is the ModelAction to check whether it is enabled.
1494  * @return a bool that indicates whether the action is enabled.
1495  */
1496 bool ModelChecker::check_action_enabled(ModelAction *curr) {
1497         if (curr->is_lock()) {
1498                 std::mutex *lock = curr->get_mutex();
1499                 struct std::mutex_state *state = lock->get_state();
1500                 if (state->locked)
1501                         return false;
1502         } else if (curr->is_thread_join()) {
1503                 Thread *blocking = curr->get_thread_operand();
1504                 if (!blocking->is_complete()) {
1505                         thread_blocking_check_promises(blocking, get_thread(curr));
1506                         return false;
1507                 }
1508         }
1509
1510         return true;
1511 }
1512
1513 /**
1514  * This is the heart of the model checker routine. It performs model-checking
1515  * actions corresponding to a given "current action." Among other processes, it
1516  * calculates reads-from relationships, updates synchronization clock vectors,
1517  * forms a memory_order constraints graph, and handles replay/backtrack
1518  * execution when running permutations of previously-observed executions.
1519  *
1520  * @param curr The current action to process
1521  * @return The ModelAction that is actually executed; may be different than
1522  * curr; may be NULL, if the current action is not enabled to run
1523  */
1524 ModelAction * ModelChecker::check_current_action(ModelAction *curr)
1525 {
1526         ASSERT(curr);
1527         bool second_part_of_rmw = curr->is_rmwc() || curr->is_rmw();
1528         bool newly_explored = initialize_curr_action(&curr);
1529
1530         DBG();
1531
1532         wake_up_sleeping_actions(curr);
1533
1534         /* Compute fairness information for CHESS yield algorithm */
1535         if (model->params.yieldon) {
1536                 curr->get_node()->update_yield(scheduler);
1537         }
1538
1539         /* Add the action to lists before any other model-checking tasks */
1540         if (!second_part_of_rmw)
1541                 add_action_to_lists(curr);
1542
1543         /* Build may_read_from set for newly-created actions */
1544         if (newly_explored && curr->is_read())
1545                 build_may_read_from(curr);
1546
1547         /* Initialize work_queue with the "current action" work */
1548         work_queue_t work_queue(1, CheckCurrWorkEntry(curr));
1549         while (!work_queue.empty() && !has_asserted()) {
1550                 WorkQueueEntry work = work_queue.front();
1551                 work_queue.pop_front();
1552
1553                 switch (work.type) {
1554                 case WORK_CHECK_CURR_ACTION: {
1555                         ModelAction *act = work.action;
1556                         bool update = false; /* update this location's release seq's */
1557                         bool update_all = false; /* update all release seq's */
1558
1559                         if (process_thread_action(curr))
1560                                 update_all = true;
1561
1562                         if (act->is_read() && !second_part_of_rmw && process_read(act))
1563                                 update = true;
1564
1565                         if (act->is_write() && process_write(act))
1566                                 update = true;
1567
1568                         if (act->is_fence() && process_fence(act))
1569                                 update_all = true;
1570
1571                         if (act->is_mutex_op() && process_mutex(act))
1572                                 update_all = true;
1573
1574                         if (act->is_relseq_fixup())
1575                                 process_relseq_fixup(curr, &work_queue);
1576
1577                         if (update_all)
1578                                 work_queue.push_back(CheckRelSeqWorkEntry(NULL));
1579                         else if (update)
1580                                 work_queue.push_back(CheckRelSeqWorkEntry(act->get_location()));
1581                         break;
1582                 }
1583                 case WORK_CHECK_RELEASE_SEQ:
1584                         resolve_release_sequences(work.location, &work_queue);
1585                         break;
1586                 case WORK_CHECK_MO_EDGES: {
1587                         /** @todo Complete verification of work_queue */
1588                         ModelAction *act = work.action;
1589                         bool updated = false;
1590
1591                         if (act->is_read()) {
1592                                 const ModelAction *rf = act->get_reads_from();
1593                                 const Promise *promise = act->get_reads_from_promise();
1594                                 if (rf) {
1595                                         if (r_modification_order(act, rf))
1596                                                 updated = true;
1597                                 } else if (promise) {
1598                                         if (r_modification_order(act, promise))
1599                                                 updated = true;
1600                                 }
1601                         }
1602                         if (act->is_write()) {
1603                                 if (w_modification_order(act, NULL))
1604                                         updated = true;
1605                         }
1606                         mo_graph->commitChanges();
1607
1608                         if (updated)
1609                                 work_queue.push_back(CheckRelSeqWorkEntry(act->get_location()));
1610                         break;
1611                 }
1612                 default:
1613                         ASSERT(false);
1614                         break;
1615                 }
1616         }
1617
1618         check_curr_backtracking(curr);
1619         set_backtracking(curr);
1620         return curr;
1621 }
1622
1623 void ModelChecker::check_curr_backtracking(ModelAction *curr)
1624 {
1625         Node *currnode = curr->get_node();
1626         Node *parnode = currnode->get_parent();
1627
1628         if ((parnode && !parnode->backtrack_empty()) ||
1629                          !currnode->misc_empty() ||
1630                          !currnode->read_from_empty() ||
1631                          !currnode->promise_empty() ||
1632                          !currnode->relseq_break_empty()) {
1633                 set_latest_backtrack(curr);
1634         }
1635 }
1636
1637 bool ModelChecker::promises_expired() const
1638 {
1639         for (unsigned int i = 0; i < promises->size(); i++) {
1640                 Promise *promise = (*promises)[i];
1641                 if (promise->get_expiration() < priv->used_sequence_numbers)
1642                         return true;
1643         }
1644         return false;
1645 }
1646
1647 /**
1648  * This is the strongest feasibility check available.
1649  * @return whether the current trace (partial or complete) must be a prefix of
1650  * a feasible trace.
1651  */
1652 bool ModelChecker::isfeasibleprefix() const
1653 {
1654         return pending_rel_seqs->size() == 0 && is_feasible_prefix_ignore_relseq();
1655 }
1656
1657 /**
1658  * Print disagnostic information about an infeasible execution
1659  * @param prefix A string to prefix the output with; if NULL, then a default
1660  * message prefix will be provided
1661  */
1662 void ModelChecker::print_infeasibility(const char *prefix) const
1663 {
1664         char buf[100];
1665         char *ptr = buf;
1666         if (mo_graph->checkForCycles())
1667                 ptr += sprintf(ptr, "[mo cycle]");
1668         if (priv->failed_promise)
1669                 ptr += sprintf(ptr, "[failed promise]");
1670         if (priv->too_many_reads)
1671                 ptr += sprintf(ptr, "[too many reads]");
1672         if (priv->no_valid_reads)
1673                 ptr += sprintf(ptr, "[no valid reads-from]");
1674         if (priv->bad_synchronization)
1675                 ptr += sprintf(ptr, "[bad sw ordering]");
1676         if (promises_expired())
1677                 ptr += sprintf(ptr, "[promise expired]");
1678         if (promises->size() != 0)
1679                 ptr += sprintf(ptr, "[unresolved promise]");
1680         if (ptr != buf)
1681                 model_print("%s: %s\n", prefix ? prefix : "Infeasible", buf);
1682 }
1683
1684 /**
1685  * Returns whether the current completed trace is feasible, except for pending
1686  * release sequences.
1687  */
1688 bool ModelChecker::is_feasible_prefix_ignore_relseq() const
1689 {
1690         return !is_infeasible() && promises->size() == 0;
1691 }
1692
1693 /**
1694  * Check if the current partial trace is infeasible. Does not check any
1695  * end-of-execution flags, which might rule out the execution. Thus, this is
1696  * useful only for ruling an execution as infeasible.
1697  * @return whether the current partial trace is infeasible.
1698  */
1699 bool ModelChecker::is_infeasible() const
1700 {
1701         return mo_graph->checkForCycles() ||
1702                 priv->no_valid_reads ||
1703                 priv->failed_promise ||
1704                 priv->too_many_reads ||
1705                 priv->bad_synchronization ||
1706                 promises_expired();
1707 }
1708
1709 /** Close out a RMWR by converting previous RMWR into a RMW or READ. */
1710 ModelAction * ModelChecker::process_rmw(ModelAction *act) {
1711         ModelAction *lastread = get_last_action(act->get_tid());
1712         lastread->process_rmw(act);
1713         if (act->is_rmw()) {
1714                 if (lastread->get_reads_from())
1715                         mo_graph->addRMWEdge(lastread->get_reads_from(), lastread);
1716                 else
1717                         mo_graph->addRMWEdge(lastread->get_reads_from_promise(), lastread);
1718                 mo_graph->commitChanges();
1719         }
1720         return lastread;
1721 }
1722
1723 /**
1724  * A helper function for ModelChecker::check_recency, to check if the current
1725  * thread is able to read from a different write/promise for 'params.maxreads'
1726  * number of steps and if that write/promise should become visible (i.e., is
1727  * ordered later in the modification order). This helps model memory liveness.
1728  *
1729  * @param curr The current action. Must be a read.
1730  * @param rf The write/promise from which we plan to read
1731  * @param other_rf The write/promise from which we may read
1732  * @return True if we were able to read from other_rf for params.maxreads steps
1733  */
1734 template <typename T, typename U>
1735 bool ModelChecker::should_read_instead(const ModelAction *curr, const T *rf, const U *other_rf) const
1736 {
1737         /* Need a different write/promise */
1738         if (other_rf->equals(rf))
1739                 return false;
1740
1741         /* Only look for "newer" writes/promises */
1742         if (!mo_graph->checkReachable(rf, other_rf))
1743                 return false;
1744
1745         SnapVector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
1746         action_list_t *list = &(*thrd_lists)[id_to_int(curr->get_tid())];
1747         action_list_t::reverse_iterator rit = list->rbegin();
1748         ASSERT((*rit) == curr);
1749         /* Skip past curr */
1750         rit++;
1751
1752         /* Does this write/promise work for everyone? */
1753         for (int i = 0; i < params.maxreads; i++, rit++) {
1754                 ModelAction *act = *rit;
1755                 if (!act->may_read_from(other_rf))
1756                         return false;
1757         }
1758         return true;
1759 }
1760
1761 /**
1762  * Checks whether a thread has read from the same write or Promise for too many
1763  * times without seeing the effects of a later write/Promise.
1764  *
1765  * Basic idea:
1766  * 1) there must a different write/promise that we could read from,
1767  * 2) we must have read from the same write/promise in excess of maxreads times,
1768  * 3) that other write/promise must have been in the reads_from set for maxreads times, and
1769  * 4) that other write/promise must be mod-ordered after the write/promise we are reading.
1770  *
1771  * If so, we decide that the execution is no longer feasible.
1772  *
1773  * @param curr The current action. Must be a read.
1774  * @param rf The ModelAction/Promise from which we might read.
1775  * @return True if the read should succeed; false otherwise
1776  */
1777 template <typename T>
1778 bool ModelChecker::check_recency(ModelAction *curr, const T *rf) const
1779 {
1780         if (!params.maxreads)
1781                 return true;
1782
1783         //NOTE: Next check is just optimization, not really necessary....
1784         if (curr->get_node()->get_read_from_past_size() +
1785                         curr->get_node()->get_read_from_promise_size() <= 1)
1786                 return true;
1787
1788         SnapVector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
1789         int tid = id_to_int(curr->get_tid());
1790         ASSERT(tid < (int)thrd_lists->size());
1791         action_list_t *list = &(*thrd_lists)[tid];
1792         action_list_t::reverse_iterator rit = list->rbegin();
1793         ASSERT((*rit) == curr);
1794         /* Skip past curr */
1795         rit++;
1796
1797         action_list_t::reverse_iterator ritcopy = rit;
1798         /* See if we have enough reads from the same value */
1799         for (int count = 0; count < params.maxreads; ritcopy++, count++) {
1800                 if (ritcopy == list->rend())
1801                         return true;
1802                 ModelAction *act = *ritcopy;
1803                 if (!act->is_read())
1804                         return true;
1805                 if (act->get_reads_from_promise() && !act->get_reads_from_promise()->equals(rf))
1806                         return true;
1807                 if (act->get_reads_from() && !act->get_reads_from()->equals(rf))
1808                         return true;
1809                 if (act->get_node()->get_read_from_past_size() +
1810                                 act->get_node()->get_read_from_promise_size() <= 1)
1811                         return true;
1812         }
1813         for (int i = 0; i < curr->get_node()->get_read_from_past_size(); i++) {
1814                 const ModelAction *write = curr->get_node()->get_read_from_past(i);
1815                 if (should_read_instead(curr, rf, write))
1816                         return false; /* liveness failure */
1817         }
1818         for (int i = 0; i < curr->get_node()->get_read_from_promise_size(); i++) {
1819                 const Promise *promise = curr->get_node()->get_read_from_promise(i);
1820                 if (should_read_instead(curr, rf, promise))
1821                         return false; /* liveness failure */
1822         }
1823         return true;
1824 }
1825
1826 /**
1827  * @brief Updates the mo_graph with the constraints imposed from the current
1828  * read.
1829  *
1830  * Basic idea is the following: Go through each other thread and find
1831  * the last action that happened before our read.  Two cases:
1832  *
1833  * -# The action is a write: that write must either occur before
1834  * the write we read from or be the write we read from.
1835  * -# The action is a read: the write that that action read from
1836  * must occur before the write we read from or be the same write.
1837  *
1838  * @param curr The current action. Must be a read.
1839  * @param rf The ModelAction or Promise that curr reads from. Must be a write.
1840  * @return True if modification order edges were added; false otherwise
1841  */
1842 template <typename rf_type>
1843 bool ModelChecker::r_modification_order(ModelAction *curr, const rf_type *rf)
1844 {
1845         SnapVector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
1846         unsigned int i;
1847         bool added = false;
1848         ASSERT(curr->is_read());
1849
1850         /* Last SC fence in the current thread */
1851         ModelAction *last_sc_fence_local = get_last_seq_cst_fence(curr->get_tid(), NULL);
1852         ModelAction *last_sc_write = NULL;
1853         if (curr->is_seqcst())
1854                 last_sc_write = get_last_seq_cst_write(curr);
1855
1856         /* Iterate over all threads */
1857         for (i = 0; i < thrd_lists->size(); i++) {
1858                 /* Last SC fence in thread i */
1859                 ModelAction *last_sc_fence_thread_local = NULL;
1860                 if (int_to_id((int)i) != curr->get_tid())
1861                         last_sc_fence_thread_local = get_last_seq_cst_fence(int_to_id(i), NULL);
1862
1863                 /* Last SC fence in thread i, before last SC fence in current thread */
1864                 ModelAction *last_sc_fence_thread_before = NULL;
1865                 if (last_sc_fence_local)
1866                         last_sc_fence_thread_before = get_last_seq_cst_fence(int_to_id(i), last_sc_fence_local);
1867
1868                 /* Iterate over actions in thread, starting from most recent */
1869                 action_list_t *list = &(*thrd_lists)[i];
1870                 action_list_t::reverse_iterator rit;
1871                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
1872                         ModelAction *act = *rit;
1873
1874                         /* Skip curr */
1875                         if (act == curr)
1876                                 continue;
1877                         /* Don't want to add reflexive edges on 'rf' */
1878                         if (act->equals(rf)) {
1879                                 if (act->happens_before(curr))
1880                                         break;
1881                                 else
1882                                         continue;
1883                         }
1884
1885                         if (act->is_write()) {
1886                                 /* C++, Section 29.3 statement 5 */
1887                                 if (curr->is_seqcst() && last_sc_fence_thread_local &&
1888                                                 *act < *last_sc_fence_thread_local) {
1889                                         added = mo_graph->addEdge(act, rf) || added;
1890                                         break;
1891                                 }
1892                                 /* C++, Section 29.3 statement 4 */
1893                                 else if (act->is_seqcst() && last_sc_fence_local &&
1894                                                 *act < *last_sc_fence_local) {
1895                                         added = mo_graph->addEdge(act, rf) || added;
1896                                         break;
1897                                 }
1898                                 /* C++, Section 29.3 statement 6 */
1899                                 else if (last_sc_fence_thread_before &&
1900                                                 *act < *last_sc_fence_thread_before) {
1901                                         added = mo_graph->addEdge(act, rf) || added;
1902                                         break;
1903                                 }
1904                         }
1905
1906                         /* C++, Section 29.3 statement 3 (second subpoint) */
1907                         if (curr->is_seqcst() && last_sc_write && act == last_sc_write) {
1908                                 added = mo_graph->addEdge(act, rf) || added;
1909                                 break;
1910                         }
1911
1912                         /*
1913                          * Include at most one act per-thread that "happens
1914                          * before" curr
1915                          */
1916                         if (act->happens_before(curr)) {
1917                                 if (act->is_write()) {
1918                                         added = mo_graph->addEdge(act, rf) || added;
1919                                 } else {
1920                                         const ModelAction *prevrf = act->get_reads_from();
1921                                         const Promise *prevrf_promise = act->get_reads_from_promise();
1922                                         if (prevrf) {
1923                                                 if (!prevrf->equals(rf))
1924                                                         added = mo_graph->addEdge(prevrf, rf) || added;
1925                                         } else if (!prevrf_promise->equals(rf)) {
1926                                                 added = mo_graph->addEdge(prevrf_promise, rf) || added;
1927                                         }
1928                                 }
1929                                 break;
1930                         }
1931                 }
1932         }
1933
1934         /*
1935          * All compatible, thread-exclusive promises must be ordered after any
1936          * concrete loads from the same thread
1937          */
1938         for (unsigned int i = 0; i < promises->size(); i++)
1939                 if ((*promises)[i]->is_compatible_exclusive(curr))
1940                         added = mo_graph->addEdge(rf, (*promises)[i]) || added;
1941
1942         return added;
1943 }
1944
1945 /**
1946  * Updates the mo_graph with the constraints imposed from the current write.
1947  *
1948  * Basic idea is the following: Go through each other thread and find
1949  * the lastest action that happened before our write.  Two cases:
1950  *
1951  * (1) The action is a write => that write must occur before
1952  * the current write
1953  *
1954  * (2) The action is a read => the write that that action read from
1955  * must occur before the current write.
1956  *
1957  * This method also handles two other issues:
1958  *
1959  * (I) Sequential Consistency: Making sure that if the current write is
1960  * seq_cst, that it occurs after the previous seq_cst write.
1961  *
1962  * (II) Sending the write back to non-synchronizing reads.
1963  *
1964  * @param curr The current action. Must be a write.
1965  * @param send_fv A vector for stashing reads to which we may pass our future
1966  * value. If NULL, then don't record any future values.
1967  * @return True if modification order edges were added; false otherwise
1968  */
1969 bool ModelChecker::w_modification_order(ModelAction *curr, ModelVector<ModelAction *> *send_fv)
1970 {
1971         SnapVector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
1972         unsigned int i;
1973         bool added = false;
1974         ASSERT(curr->is_write());
1975
1976         if (curr->is_seqcst()) {
1977                 /* We have to at least see the last sequentially consistent write,
1978                          so we are initialized. */
1979                 ModelAction *last_seq_cst = get_last_seq_cst_write(curr);
1980                 if (last_seq_cst != NULL) {
1981                         added = mo_graph->addEdge(last_seq_cst, curr) || added;
1982                 }
1983         }
1984
1985         /* Last SC fence in the current thread */
1986         ModelAction *last_sc_fence_local = get_last_seq_cst_fence(curr->get_tid(), NULL);
1987
1988         /* Iterate over all threads */
1989         for (i = 0; i < thrd_lists->size(); i++) {
1990                 /* Last SC fence in thread i, before last SC fence in current thread */
1991                 ModelAction *last_sc_fence_thread_before = NULL;
1992                 if (last_sc_fence_local && int_to_id((int)i) != curr->get_tid())
1993                         last_sc_fence_thread_before = get_last_seq_cst_fence(int_to_id(i), last_sc_fence_local);
1994
1995                 /* Iterate over actions in thread, starting from most recent */
1996                 action_list_t *list = &(*thrd_lists)[i];
1997                 action_list_t::reverse_iterator rit;
1998                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
1999                         ModelAction *act = *rit;
2000                         if (act == curr) {
2001                                 /*
2002                                  * 1) If RMW and it actually read from something, then we
2003                                  * already have all relevant edges, so just skip to next
2004                                  * thread.
2005                                  *
2006                                  * 2) If RMW and it didn't read from anything, we should
2007                                  * whatever edge we can get to speed up convergence.
2008                                  *
2009                                  * 3) If normal write, we need to look at earlier actions, so
2010                                  * continue processing list.
2011                                  */
2012                                 if (curr->is_rmw()) {
2013                                         if (curr->get_reads_from() != NULL)
2014                                                 break;
2015                                         else
2016                                                 continue;
2017                                 } else
2018                                         continue;
2019                         }
2020
2021                         /* C++, Section 29.3 statement 7 */
2022                         if (last_sc_fence_thread_before && act->is_write() &&
2023                                         *act < *last_sc_fence_thread_before) {
2024                                 added = mo_graph->addEdge(act, curr) || added;
2025                                 break;
2026                         }
2027
2028                         /*
2029                          * Include at most one act per-thread that "happens
2030                          * before" curr
2031                          */
2032                         if (act->happens_before(curr)) {
2033                                 /*
2034                                  * Note: if act is RMW, just add edge:
2035                                  *   act --mo--> curr
2036                                  * The following edge should be handled elsewhere:
2037                                  *   readfrom(act) --mo--> act
2038                                  */
2039                                 if (act->is_write())
2040                                         added = mo_graph->addEdge(act, curr) || added;
2041                                 else if (act->is_read()) {
2042                                         //if previous read accessed a null, just keep going
2043                                         if (act->get_reads_from() == NULL)
2044                                                 continue;
2045                                         added = mo_graph->addEdge(act->get_reads_from(), curr) || added;
2046                                 }
2047                                 break;
2048                         } else if (act->is_read() && !act->could_synchronize_with(curr) &&
2049                                                      !act->same_thread(curr)) {
2050                                 /* We have an action that:
2051                                    (1) did not happen before us
2052                                    (2) is a read and we are a write
2053                                    (3) cannot synchronize with us
2054                                    (4) is in a different thread
2055                                    =>
2056                                    that read could potentially read from our write.  Note that
2057                                    these checks are overly conservative at this point, we'll
2058                                    do more checks before actually removing the
2059                                    pendingfuturevalue.
2060
2061                                  */
2062                                 if (send_fv && thin_air_constraint_may_allow(curr, act)) {
2063                                         if (!is_infeasible())
2064                                                 send_fv->push_back(act);
2065                                         else if (curr->is_rmw() && act->is_rmw() && curr->get_reads_from() && curr->get_reads_from() == act->get_reads_from())
2066                                                 add_future_value(curr, act);
2067                                 }
2068                         }
2069                 }
2070         }
2071
2072         /*
2073          * All compatible, thread-exclusive promises must be ordered after any
2074          * concrete stores to the same thread, or else they can be merged with
2075          * this store later
2076          */
2077         for (unsigned int i = 0; i < promises->size(); i++)
2078                 if ((*promises)[i]->is_compatible_exclusive(curr))
2079                         added = mo_graph->addEdge(curr, (*promises)[i]) || added;
2080
2081         return added;
2082 }
2083
2084 /** Arbitrary reads from the future are not allowed.  Section 29.3
2085  * part 9 places some constraints.  This method checks one result of constraint
2086  * constraint.  Others require compiler support. */
2087 bool ModelChecker::thin_air_constraint_may_allow(const ModelAction *writer, const ModelAction *reader) const
2088 {
2089         if (!writer->is_rmw())
2090                 return true;
2091
2092         if (!reader->is_rmw())
2093                 return true;
2094
2095         for (const ModelAction *search = writer->get_reads_from(); search != NULL; search = search->get_reads_from()) {
2096                 if (search == reader)
2097                         return false;
2098                 if (search->get_tid() == reader->get_tid() &&
2099                                 search->happens_before(reader))
2100                         break;
2101         }
2102
2103         return true;
2104 }
2105
2106 /**
2107  * Arbitrary reads from the future are not allowed. Section 29.3 part 9 places
2108  * some constraints. This method checks one the following constraint (others
2109  * require compiler support):
2110  *
2111  *   If X --hb-> Y --mo-> Z, then X should not read from Z.
2112  */
2113 bool ModelChecker::mo_may_allow(const ModelAction *writer, const ModelAction *reader)
2114 {
2115         SnapVector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, reader->get_location());
2116         unsigned int i;
2117         /* Iterate over all threads */
2118         for (i = 0; i < thrd_lists->size(); i++) {
2119                 const ModelAction *write_after_read = NULL;
2120
2121                 /* Iterate over actions in thread, starting from most recent */
2122                 action_list_t *list = &(*thrd_lists)[i];
2123                 action_list_t::reverse_iterator rit;
2124                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
2125                         ModelAction *act = *rit;
2126
2127                         /* Don't disallow due to act == reader */
2128                         if (!reader->happens_before(act) || reader == act)
2129                                 break;
2130                         else if (act->is_write())
2131                                 write_after_read = act;
2132                         else if (act->is_read() && act->get_reads_from() != NULL)
2133                                 write_after_read = act->get_reads_from();
2134                 }
2135
2136                 if (write_after_read && write_after_read != writer && mo_graph->checkReachable(write_after_read, writer))
2137                         return false;
2138         }
2139         return true;
2140 }
2141
2142 /**
2143  * Finds the head(s) of the release sequence(s) containing a given ModelAction.
2144  * The ModelAction under consideration is expected to be taking part in
2145  * release/acquire synchronization as an object of the "reads from" relation.
2146  * Note that this can only provide release sequence support for RMW chains
2147  * which do not read from the future, as those actions cannot be traced until
2148  * their "promise" is fulfilled. Similarly, we may not even establish the
2149  * presence of a release sequence with certainty, as some modification order
2150  * constraints may be decided further in the future. Thus, this function
2151  * "returns" two pieces of data: a pass-by-reference vector of @a release_heads
2152  * and a boolean representing certainty.
2153  *
2154  * @param rf The action that might be part of a release sequence. Must be a
2155  * write.
2156  * @param release_heads A pass-by-reference style return parameter. After
2157  * execution of this function, release_heads will contain the heads of all the
2158  * relevant release sequences, if any exists with certainty
2159  * @param pending A pass-by-reference style return parameter which is only used
2160  * when returning false (i.e., uncertain). Returns most information regarding
2161  * an uncertain release sequence, including any write operations that might
2162  * break the sequence.
2163  * @return true, if the ModelChecker is certain that release_heads is complete;
2164  * false otherwise
2165  */
2166 bool ModelChecker::release_seq_heads(const ModelAction *rf,
2167                 rel_heads_list_t *release_heads,
2168                 struct release_seq *pending) const
2169 {
2170         /* Only check for release sequences if there are no cycles */
2171         if (mo_graph->checkForCycles())
2172                 return false;
2173
2174         for ( ; rf != NULL; rf = rf->get_reads_from()) {
2175                 ASSERT(rf->is_write());
2176
2177                 if (rf->is_release())
2178                         release_heads->push_back(rf);
2179                 else if (rf->get_last_fence_release())
2180                         release_heads->push_back(rf->get_last_fence_release());
2181                 if (!rf->is_rmw())
2182                         break; /* End of RMW chain */
2183
2184                 /** @todo Need to be smarter here...  In the linux lock
2185                  * example, this will run to the beginning of the program for
2186                  * every acquire. */
2187                 /** @todo The way to be smarter here is to keep going until 1
2188                  * thread has a release preceded by an acquire and you've seen
2189                  *       both. */
2190
2191                 /* acq_rel RMW is a sufficient stopping condition */
2192                 if (rf->is_acquire() && rf->is_release())
2193                         return true; /* complete */
2194         };
2195         if (!rf) {
2196                 /* read from future: need to settle this later */
2197                 pending->rf = NULL;
2198                 return false; /* incomplete */
2199         }
2200
2201         if (rf->is_release())
2202                 return true; /* complete */
2203
2204         /* else relaxed write
2205          * - check for fence-release in the same thread (29.8, stmt. 3)
2206          * - check modification order for contiguous subsequence
2207          *   -> rf must be same thread as release */
2208
2209         const ModelAction *fence_release = rf->get_last_fence_release();
2210         /* Synchronize with a fence-release unconditionally; we don't need to
2211          * find any more "contiguous subsequence..." for it */
2212         if (fence_release)
2213                 release_heads->push_back(fence_release);
2214
2215         int tid = id_to_int(rf->get_tid());
2216         SnapVector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, rf->get_location());
2217         action_list_t *list = &(*thrd_lists)[tid];
2218         action_list_t::const_reverse_iterator rit;
2219
2220         /* Find rf in the thread list */
2221         rit = std::find(list->rbegin(), list->rend(), rf);
2222         ASSERT(rit != list->rend());
2223
2224         /* Find the last {write,fence}-release */
2225         for (; rit != list->rend(); rit++) {
2226                 if (fence_release && *(*rit) < *fence_release)
2227                         break;
2228                 if ((*rit)->is_release())
2229                         break;
2230         }
2231         if (rit == list->rend()) {
2232                 /* No write-release in this thread */
2233                 return true; /* complete */
2234         } else if (fence_release && *(*rit) < *fence_release) {
2235                 /* The fence-release is more recent (and so, "stronger") than
2236                  * the most recent write-release */
2237                 return true; /* complete */
2238         } /* else, need to establish contiguous release sequence */
2239         ModelAction *release = *rit;
2240
2241         ASSERT(rf->same_thread(release));
2242
2243         pending->writes.clear();
2244
2245         bool certain = true;
2246         for (unsigned int i = 0; i < thrd_lists->size(); i++) {
2247                 if (id_to_int(rf->get_tid()) == (int)i)
2248                         continue;
2249                 list = &(*thrd_lists)[i];
2250
2251                 /* Can we ensure no future writes from this thread may break
2252                  * the release seq? */
2253                 bool future_ordered = false;
2254
2255                 ModelAction *last = get_last_action(int_to_id(i));
2256                 Thread *th = get_thread(int_to_id(i));
2257                 if ((last && rf->happens_before(last)) ||
2258                                 !is_enabled(th) ||
2259                                 th->is_complete())
2260                         future_ordered = true;
2261
2262                 ASSERT(!th->is_model_thread() || future_ordered);
2263
2264                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
2265                         const ModelAction *act = *rit;
2266                         /* Reach synchronization -> this thread is complete */
2267                         if (act->happens_before(release))
2268                                 break;
2269                         if (rf->happens_before(act)) {
2270                                 future_ordered = true;
2271                                 continue;
2272                         }
2273
2274                         /* Only non-RMW writes can break release sequences */
2275                         if (!act->is_write() || act->is_rmw())
2276                                 continue;
2277
2278                         /* Check modification order */
2279                         if (mo_graph->checkReachable(rf, act)) {
2280                                 /* rf --mo--> act */
2281                                 future_ordered = true;
2282                                 continue;
2283                         }
2284                         if (mo_graph->checkReachable(act, release))
2285                                 /* act --mo--> release */
2286                                 break;
2287                         if (mo_graph->checkReachable(release, act) &&
2288                                       mo_graph->checkReachable(act, rf)) {
2289                                 /* release --mo-> act --mo--> rf */
2290                                 return true; /* complete */
2291                         }
2292                         /* act may break release sequence */
2293                         pending->writes.push_back(act);
2294                         certain = false;
2295                 }
2296                 if (!future_ordered)
2297                         certain = false; /* This thread is uncertain */
2298         }
2299
2300         if (certain) {
2301                 release_heads->push_back(release);
2302                 pending->writes.clear();
2303         } else {
2304                 pending->release = release;
2305                 pending->rf = rf;
2306         }
2307         return certain;
2308 }
2309
2310 /**
2311  * An interface for getting the release sequence head(s) with which a
2312  * given ModelAction must synchronize. This function only returns a non-empty
2313  * result when it can locate a release sequence head with certainty. Otherwise,
2314  * it may mark the internal state of the ModelChecker so that it will handle
2315  * the release sequence at a later time, causing @a acquire to update its
2316  * synchronization at some later point in execution.
2317  *
2318  * @param acquire The 'acquire' action that may synchronize with a release
2319  * sequence
2320  * @param read The read action that may read from a release sequence; this may
2321  * be the same as acquire, or else an earlier action in the same thread (i.e.,
2322  * when 'acquire' is a fence-acquire)
2323  * @param release_heads A pass-by-reference return parameter. Will be filled
2324  * with the head(s) of the release sequence(s), if they exists with certainty.
2325  * @see ModelChecker::release_seq_heads
2326  */
2327 void ModelChecker::get_release_seq_heads(ModelAction *acquire,
2328                 ModelAction *read, rel_heads_list_t *release_heads)
2329 {
2330         const ModelAction *rf = read->get_reads_from();
2331         struct release_seq *sequence = (struct release_seq *)snapshot_calloc(1, sizeof(struct release_seq));
2332         sequence->acquire = acquire;
2333         sequence->read = read;
2334
2335         if (!release_seq_heads(rf, release_heads, sequence)) {
2336                 /* add act to 'lazy checking' list */
2337                 pending_rel_seqs->push_back(sequence);
2338         } else {
2339                 snapshot_free(sequence);
2340         }
2341 }
2342
2343 /**
2344  * Attempt to resolve all stashed operations that might synchronize with a
2345  * release sequence for a given location. This implements the "lazy" portion of
2346  * determining whether or not a release sequence was contiguous, since not all
2347  * modification order information is present at the time an action occurs.
2348  *
2349  * @param location The location/object that should be checked for release
2350  * sequence resolutions. A NULL value means to check all locations.
2351  * @param work_queue The work queue to which to add work items as they are
2352  * generated
2353  * @return True if any updates occurred (new synchronization, new mo_graph
2354  * edges)
2355  */
2356 bool ModelChecker::resolve_release_sequences(void *location, work_queue_t *work_queue)
2357 {
2358         bool updated = false;
2359         SnapVector<struct release_seq *>::iterator it = pending_rel_seqs->begin();
2360         while (it != pending_rel_seqs->end()) {
2361                 struct release_seq *pending = *it;
2362                 ModelAction *acquire = pending->acquire;
2363                 const ModelAction *read = pending->read;
2364
2365                 /* Only resolve sequences on the given location, if provided */
2366                 if (location && read->get_location() != location) {
2367                         it++;
2368                         continue;
2369                 }
2370
2371                 const ModelAction *rf = read->get_reads_from();
2372                 rel_heads_list_t release_heads;
2373                 bool complete;
2374                 complete = release_seq_heads(rf, &release_heads, pending);
2375                 for (unsigned int i = 0; i < release_heads.size(); i++)
2376                         if (!acquire->has_synchronized_with(release_heads[i]))
2377                                 if (synchronize(release_heads[i], acquire))
2378                                         updated = true;
2379
2380                 if (updated) {
2381                         /* Re-check all pending release sequences */
2382                         work_queue->push_back(CheckRelSeqWorkEntry(NULL));
2383                         /* Re-check read-acquire for mo_graph edges */
2384                         if (acquire->is_read())
2385                                 work_queue->push_back(MOEdgeWorkEntry(acquire));
2386
2387                         /* propagate synchronization to later actions */
2388                         action_list_t::reverse_iterator rit = action_trace->rbegin();
2389                         for (; (*rit) != acquire; rit++) {
2390                                 ModelAction *propagate = *rit;
2391                                 if (acquire->happens_before(propagate)) {
2392                                         synchronize(acquire, propagate);
2393                                         /* Re-check 'propagate' for mo_graph edges */
2394                                         work_queue->push_back(MOEdgeWorkEntry(propagate));
2395                                 }
2396                         }
2397                 }
2398                 if (complete) {
2399                         it = pending_rel_seqs->erase(it);
2400                         snapshot_free(pending);
2401                 } else {
2402                         it++;
2403                 }
2404         }
2405
2406         // If we resolved promises or data races, see if we have realized a data race.
2407         checkDataRaces();
2408
2409         return updated;
2410 }
2411
2412 /**
2413  * Performs various bookkeeping operations for the current ModelAction. For
2414  * instance, adds action to the per-object, per-thread action vector and to the
2415  * action trace list of all thread actions.
2416  *
2417  * @param act is the ModelAction to add.
2418  */
2419 void ModelChecker::add_action_to_lists(ModelAction *act)
2420 {
2421         int tid = id_to_int(act->get_tid());
2422         ModelAction *uninit = NULL;
2423         int uninit_id = -1;
2424         action_list_t *list = get_safe_ptr_action(obj_map, act->get_location());
2425         if (list->empty() && act->is_atomic_var()) {
2426                 uninit = get_uninitialized_action(act);
2427                 uninit_id = id_to_int(uninit->get_tid());
2428                 list->push_front(uninit);
2429         }
2430         list->push_back(act);
2431
2432         action_trace->push_back(act);
2433         if (uninit)
2434                 action_trace->push_front(uninit);
2435
2436         SnapVector<action_list_t> *vec = get_safe_ptr_vect_action(obj_thrd_map, act->get_location());
2437         if (tid >= (int)vec->size())
2438                 vec->resize(priv->next_thread_id);
2439         (*vec)[tid].push_back(act);
2440         if (uninit)
2441                 (*vec)[uninit_id].push_front(uninit);
2442
2443         if ((int)thrd_last_action->size() <= tid)
2444                 thrd_last_action->resize(get_num_threads());
2445         (*thrd_last_action)[tid] = act;
2446         if (uninit)
2447                 (*thrd_last_action)[uninit_id] = uninit;
2448
2449         if (act->is_fence() && act->is_release()) {
2450                 if ((int)thrd_last_fence_release->size() <= tid)
2451                         thrd_last_fence_release->resize(get_num_threads());
2452                 (*thrd_last_fence_release)[tid] = act;
2453         }
2454
2455         if (act->is_wait()) {
2456                 void *mutex_loc = (void *) act->get_value();
2457                 get_safe_ptr_action(obj_map, mutex_loc)->push_back(act);
2458
2459                 SnapVector<action_list_t> *vec = get_safe_ptr_vect_action(obj_thrd_map, mutex_loc);
2460                 if (tid >= (int)vec->size())
2461                         vec->resize(priv->next_thread_id);
2462                 (*vec)[tid].push_back(act);
2463         }
2464 }
2465
2466 /**
2467  * @brief Get the last action performed by a particular Thread
2468  * @param tid The thread ID of the Thread in question
2469  * @return The last action in the thread
2470  */
2471 ModelAction * ModelChecker::get_last_action(thread_id_t tid) const
2472 {
2473         int threadid = id_to_int(tid);
2474         if (threadid < (int)thrd_last_action->size())
2475                 return (*thrd_last_action)[id_to_int(tid)];
2476         else
2477                 return NULL;
2478 }
2479
2480 /**
2481  * @brief Get the last fence release performed by a particular Thread
2482  * @param tid The thread ID of the Thread in question
2483  * @return The last fence release in the thread, if one exists; NULL otherwise
2484  */
2485 ModelAction * ModelChecker::get_last_fence_release(thread_id_t tid) const
2486 {
2487         int threadid = id_to_int(tid);
2488         if (threadid < (int)thrd_last_fence_release->size())
2489                 return (*thrd_last_fence_release)[id_to_int(tid)];
2490         else
2491                 return NULL;
2492 }
2493
2494 /**
2495  * Gets the last memory_order_seq_cst write (in the total global sequence)
2496  * performed on a particular object (i.e., memory location), not including the
2497  * current action.
2498  * @param curr The current ModelAction; also denotes the object location to
2499  * check
2500  * @return The last seq_cst write
2501  */
2502 ModelAction * ModelChecker::get_last_seq_cst_write(ModelAction *curr) const
2503 {
2504         void *location = curr->get_location();
2505         action_list_t *list = get_safe_ptr_action(obj_map, location);
2506         /* Find: max({i in dom(S) | seq_cst(t_i) && isWrite(t_i) && samevar(t_i, t)}) */
2507         action_list_t::reverse_iterator rit;
2508         for (rit = list->rbegin(); (*rit) != curr; rit++)
2509                 ;
2510         rit++; /* Skip past curr */
2511         for ( ; rit != list->rend(); rit++)
2512                 if ((*rit)->is_write() && (*rit)->is_seqcst())
2513                         return *rit;
2514         return NULL;
2515 }
2516
2517 /**
2518  * Gets the last memory_order_seq_cst fence (in the total global sequence)
2519  * performed in a particular thread, prior to a particular fence.
2520  * @param tid The ID of the thread to check
2521  * @param before_fence The fence from which to begin the search; if NULL, then
2522  * search for the most recent fence in the thread.
2523  * @return The last prior seq_cst fence in the thread, if exists; otherwise, NULL
2524  */
2525 ModelAction * ModelChecker::get_last_seq_cst_fence(thread_id_t tid, const ModelAction *before_fence) const
2526 {
2527         /* All fences should have NULL location */
2528         action_list_t *list = get_safe_ptr_action(obj_map, NULL);
2529         action_list_t::reverse_iterator rit = list->rbegin();
2530
2531         if (before_fence) {
2532                 for (; rit != list->rend(); rit++)
2533                         if (*rit == before_fence)
2534                                 break;
2535
2536                 ASSERT(*rit == before_fence);
2537                 rit++;
2538         }
2539
2540         for (; rit != list->rend(); rit++)
2541                 if ((*rit)->is_fence() && (tid == (*rit)->get_tid()) && (*rit)->is_seqcst())
2542                         return *rit;
2543         return NULL;
2544 }
2545
2546 /**
2547  * Gets the last unlock operation performed on a particular mutex (i.e., memory
2548  * location). This function identifies the mutex according to the current
2549  * action, which is presumed to perform on the same mutex.
2550  * @param curr The current ModelAction; also denotes the object location to
2551  * check
2552  * @return The last unlock operation
2553  */
2554 ModelAction * ModelChecker::get_last_unlock(ModelAction *curr) const
2555 {
2556         void *location = curr->get_location();
2557         action_list_t *list = get_safe_ptr_action(obj_map, location);
2558         /* Find: max({i in dom(S) | isUnlock(t_i) && samevar(t_i, t)}) */
2559         action_list_t::reverse_iterator rit;
2560         for (rit = list->rbegin(); rit != list->rend(); rit++)
2561                 if ((*rit)->is_unlock() || (*rit)->is_wait())
2562                         return *rit;
2563         return NULL;
2564 }
2565
2566 ModelAction * ModelChecker::get_parent_action(thread_id_t tid) const
2567 {
2568         ModelAction *parent = get_last_action(tid);
2569         if (!parent)
2570                 parent = get_thread(tid)->get_creation();
2571         return parent;
2572 }
2573
2574 /**
2575  * Returns the clock vector for a given thread.
2576  * @param tid The thread whose clock vector we want
2577  * @return Desired clock vector
2578  */
2579 ClockVector * ModelChecker::get_cv(thread_id_t tid) const
2580 {
2581         return get_parent_action(tid)->get_cv();
2582 }
2583
2584 /**
2585  * @brief Find the promise (if any) to resolve for the current action and
2586  * remove it from the pending promise vector
2587  * @param curr The current ModelAction. Should be a write.
2588  * @return The Promise to resolve, if any; otherwise NULL
2589  */
2590 Promise * ModelChecker::pop_promise_to_resolve(const ModelAction *curr)
2591 {
2592         for (unsigned int i = 0; i < promises->size(); i++)
2593                 if (curr->get_node()->get_promise(i)) {
2594                         Promise *ret = (*promises)[i];
2595                         promises->erase(promises->begin() + i);
2596                         return ret;
2597                 }
2598         return NULL;
2599 }
2600
2601 /**
2602  * Resolve a Promise with a current write.
2603  * @param write The ModelAction that is fulfilling Promises
2604  * @param promise The Promise to resolve
2605  * @return True if the Promise was successfully resolved; false otherwise
2606  */
2607 bool ModelChecker::resolve_promise(ModelAction *write, Promise *promise)
2608 {
2609         ModelVector<ModelAction *> actions_to_check;
2610
2611         for (unsigned int i = 0; i < promise->get_num_readers(); i++) {
2612                 ModelAction *read = promise->get_reader(i);
2613                 read_from(read, write);
2614                 actions_to_check.push_back(read);
2615         }
2616         /* Make sure the promise's value matches the write's value */
2617         ASSERT(promise->is_compatible(write) && promise->same_value(write));
2618         if (!mo_graph->resolvePromise(promise, write))
2619                 priv->failed_promise = true;
2620
2621         /**
2622          * @todo  It is possible to end up in an inconsistent state, where a
2623          * "resolved" promise may still be referenced if
2624          * CycleGraph::resolvePromise() failed, so don't delete 'promise'.
2625          *
2626          * Note that the inconsistency only matters when dumping mo_graph to
2627          * file.
2628          *
2629          * delete promise;
2630          */
2631
2632         //Check whether reading these writes has made threads unable to
2633         //resolve promises
2634         for (unsigned int i = 0; i < actions_to_check.size(); i++) {
2635                 ModelAction *read = actions_to_check[i];
2636                 mo_check_promises(read, true);
2637         }
2638
2639         return true;
2640 }
2641
2642 /**
2643  * Compute the set of promises that could potentially be satisfied by this
2644  * action. Note that the set computation actually appears in the Node, not in
2645  * ModelChecker.
2646  * @param curr The ModelAction that may satisfy promises
2647  */
2648 void ModelChecker::compute_promises(ModelAction *curr)
2649 {
2650         for (unsigned int i = 0; i < promises->size(); i++) {
2651                 Promise *promise = (*promises)[i];
2652                 if (!promise->is_compatible(curr) || !promise->same_value(curr))
2653                         continue;
2654
2655                 bool satisfy = true;
2656                 for (unsigned int j = 0; j < promise->get_num_readers(); j++) {
2657                         const ModelAction *act = promise->get_reader(j);
2658                         if (act->happens_before(curr) ||
2659                                         act->could_synchronize_with(curr)) {
2660                                 satisfy = false;
2661                                 break;
2662                         }
2663                 }
2664                 if (satisfy)
2665                         curr->get_node()->set_promise(i);
2666         }
2667 }
2668
2669 /** Checks promises in response to change in ClockVector Threads. */
2670 void ModelChecker::check_promises(thread_id_t tid, ClockVector *old_cv, ClockVector *merge_cv)
2671 {
2672         for (unsigned int i = 0; i < promises->size(); i++) {
2673                 Promise *promise = (*promises)[i];
2674                 if (!promise->thread_is_available(tid))
2675                         continue;
2676                 for (unsigned int j = 0; j < promise->get_num_readers(); j++) {
2677                         const ModelAction *act = promise->get_reader(j);
2678                         if ((!old_cv || !old_cv->synchronized_since(act)) &&
2679                                         merge_cv->synchronized_since(act)) {
2680                                 if (promise->eliminate_thread(tid)) {
2681                                         /* Promise has failed */
2682                                         priv->failed_promise = true;
2683                                         return;
2684                                 }
2685                         }
2686                 }
2687         }
2688 }
2689
2690 void ModelChecker::check_promises_thread_disabled()
2691 {
2692         for (unsigned int i = 0; i < promises->size(); i++) {
2693                 Promise *promise = (*promises)[i];
2694                 if (promise->has_failed()) {
2695                         priv->failed_promise = true;
2696                         return;
2697                 }
2698         }
2699 }
2700
2701 /**
2702  * @brief Checks promises in response to addition to modification order for
2703  * threads.
2704  *
2705  * We test whether threads are still available for satisfying promises after an
2706  * addition to our modification order constraints. Those that are unavailable
2707  * are "eliminated". Once all threads are eliminated from satisfying a promise,
2708  * that promise has failed.
2709  *
2710  * @param act The ModelAction which updated the modification order
2711  * @param is_read_check Should be true if act is a read and we must check for
2712  * updates to the store from which it read (there is a distinction here for
2713  * RMW's, which are both a load and a store)
2714  */
2715 void ModelChecker::mo_check_promises(const ModelAction *act, bool is_read_check)
2716 {
2717         const ModelAction *write = is_read_check ? act->get_reads_from() : act;
2718
2719         for (unsigned int i = 0; i < promises->size(); i++) {
2720                 Promise *promise = (*promises)[i];
2721
2722                 // Is this promise on the same location?
2723                 if (!promise->same_location(write))
2724                         continue;
2725
2726                 for (unsigned int j = 0; j < promise->get_num_readers(); j++) {
2727                         const ModelAction *pread = promise->get_reader(j);
2728                         if (!pread->happens_before(act))
2729                                continue;
2730                         if (mo_graph->checkPromise(write, promise)) {
2731                                 priv->failed_promise = true;
2732                                 return;
2733                         }
2734                         break;
2735                 }
2736
2737                 // Don't do any lookups twice for the same thread
2738                 if (!promise->thread_is_available(act->get_tid()))
2739                         continue;
2740
2741                 if (mo_graph->checkReachable(promise, write)) {
2742                         if (mo_graph->checkPromise(write, promise)) {
2743                                 priv->failed_promise = true;
2744                                 return;
2745                         }
2746                 }
2747         }
2748 }
2749
2750 /**
2751  * Compute the set of writes that may break the current pending release
2752  * sequence. This information is extracted from previou release sequence
2753  * calculations.
2754  *
2755  * @param curr The current ModelAction. Must be a release sequence fixup
2756  * action.
2757  */
2758 void ModelChecker::compute_relseq_breakwrites(ModelAction *curr)
2759 {
2760         if (pending_rel_seqs->empty())
2761                 return;
2762
2763         struct release_seq *pending = pending_rel_seqs->back();
2764         for (unsigned int i = 0; i < pending->writes.size(); i++) {
2765                 const ModelAction *write = pending->writes[i];
2766                 curr->get_node()->add_relseq_break(write);
2767         }
2768
2769         /* NULL means don't break the sequence; just synchronize */
2770         curr->get_node()->add_relseq_break(NULL);
2771 }
2772
2773 /**
2774  * Build up an initial set of all past writes that this 'read' action may read
2775  * from, as well as any previously-observed future values that must still be valid.
2776  *
2777  * @param curr is the current ModelAction that we are exploring; it must be a
2778  * 'read' operation.
2779  */
2780 void ModelChecker::build_may_read_from(ModelAction *curr)
2781 {
2782         SnapVector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
2783         unsigned int i;
2784         ASSERT(curr->is_read());
2785
2786         ModelAction *last_sc_write = NULL;
2787
2788         if (curr->is_seqcst())
2789                 last_sc_write = get_last_seq_cst_write(curr);
2790
2791         /* Iterate over all threads */
2792         for (i = 0; i < thrd_lists->size(); i++) {
2793                 /* Iterate over actions in thread, starting from most recent */
2794                 action_list_t *list = &(*thrd_lists)[i];
2795                 action_list_t::reverse_iterator rit;
2796                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
2797                         ModelAction *act = *rit;
2798
2799                         /* Only consider 'write' actions */
2800                         if (!act->is_write() || act == curr)
2801                                 continue;
2802
2803                         /* Don't consider more than one seq_cst write if we are a seq_cst read. */
2804                         bool allow_read = true;
2805
2806                         if (curr->is_seqcst() && (act->is_seqcst() || (last_sc_write != NULL && act->happens_before(last_sc_write))) && act != last_sc_write)
2807                                 allow_read = false;
2808                         else if (curr->get_sleep_flag() && !curr->is_seqcst() && !sleep_can_read_from(curr, act))
2809                                 allow_read = false;
2810
2811                         if (allow_read) {
2812                                 /* Only add feasible reads */
2813                                 mo_graph->startChanges();
2814                                 r_modification_order(curr, act);
2815                                 if (!is_infeasible())
2816                                         curr->get_node()->add_read_from_past(act);
2817                                 mo_graph->rollbackChanges();
2818                         }
2819
2820                         /* Include at most one act per-thread that "happens before" curr */
2821                         if (act->happens_before(curr))
2822                                 break;
2823                 }
2824         }
2825
2826         /* Inherit existing, promised future values */
2827         for (i = 0; i < promises->size(); i++) {
2828                 const Promise *promise = (*promises)[i];
2829                 const ModelAction *promise_read = promise->get_reader(0);
2830                 if (promise_read->same_var(curr)) {
2831                         /* Only add feasible future-values */
2832                         mo_graph->startChanges();
2833                         r_modification_order(curr, promise);
2834                         if (!is_infeasible())
2835                                 curr->get_node()->add_read_from_promise(promise_read);
2836                         mo_graph->rollbackChanges();
2837                 }
2838         }
2839
2840         /* We may find no valid may-read-from only if the execution is doomed */
2841         if (!curr->get_node()->read_from_size()) {
2842                 priv->no_valid_reads = true;
2843                 set_assert();
2844         }
2845
2846         if (DBG_ENABLED()) {
2847                 model_print("Reached read action:\n");
2848                 curr->print();
2849                 model_print("Printing read_from_past\n");
2850                 curr->get_node()->print_read_from_past();
2851                 model_print("End printing read_from_past\n");
2852         }
2853 }
2854
2855 bool ModelChecker::sleep_can_read_from(ModelAction *curr, const ModelAction *write)
2856 {
2857         for ( ; write != NULL; write = write->get_reads_from()) {
2858                 /* UNINIT actions don't have a Node, and they never sleep */
2859                 if (write->is_uninitialized())
2860                         return true;
2861                 Node *prevnode = write->get_node()->get_parent();
2862
2863                 bool thread_sleep = prevnode->enabled_status(curr->get_tid()) == THREAD_SLEEP_SET;
2864                 if (write->is_release() && thread_sleep)
2865                         return true;
2866                 if (!write->is_rmw())
2867                         return false;
2868         }
2869         return true;
2870 }
2871
2872 /**
2873  * @brief Get an action representing an uninitialized atomic
2874  *
2875  * This function may create a new one or try to retrieve one from the NodeStack
2876  *
2877  * @param curr The current action, which prompts the creation of an UNINIT action
2878  * @return A pointer to the UNINIT ModelAction
2879  */
2880 ModelAction * ModelChecker::get_uninitialized_action(const ModelAction *curr) const
2881 {
2882         Node *node = curr->get_node();
2883         ModelAction *act = node->get_uninit_action();
2884         if (!act) {
2885                 act = new ModelAction(ATOMIC_UNINIT, std::memory_order_relaxed, curr->get_location(), model->params.uninitvalue, model_thread);
2886                 node->set_uninit_action(act);
2887         }
2888         act->create_cv(NULL);
2889         return act;
2890 }
2891
2892 static void print_list(action_list_t *list)
2893 {
2894         action_list_t::iterator it;
2895
2896         model_print("---------------------------------------------------------------------\n");
2897
2898         unsigned int hash = 0;
2899
2900         for (it = list->begin(); it != list->end(); it++) {
2901                 const ModelAction *act = *it;
2902                 if (act->get_seq_number() > 0)
2903                         act->print();
2904                 hash = hash^(hash<<3)^((*it)->hash());
2905         }
2906         model_print("HASH %u\n", hash);
2907         model_print("---------------------------------------------------------------------\n");
2908 }
2909
2910 #if SUPPORT_MOD_ORDER_DUMP
2911 void ModelChecker::dumpGraph(char *filename) const
2912 {
2913         char buffer[200];
2914         sprintf(buffer, "%s.dot", filename);
2915         FILE *file = fopen(buffer, "w");
2916         fprintf(file, "digraph %s {\n", filename);
2917         mo_graph->dumpNodes(file);
2918         ModelAction **thread_array = (ModelAction **)model_calloc(1, sizeof(ModelAction *) * get_num_threads());
2919
2920         for (action_list_t::iterator it = action_trace->begin(); it != action_trace->end(); it++) {
2921                 ModelAction *act = *it;
2922                 if (act->is_read()) {
2923                         mo_graph->dot_print_node(file, act);
2924                         if (act->get_reads_from())
2925                                 mo_graph->dot_print_edge(file,
2926                                                 act->get_reads_from(),
2927                                                 act,
2928                                                 "label=\"rf\", color=red, weight=2");
2929                         else
2930                                 mo_graph->dot_print_edge(file,
2931                                                 act->get_reads_from_promise(),
2932                                                 act,
2933                                                 "label=\"rf\", color=red");
2934                 }
2935                 if (thread_array[act->get_tid()]) {
2936                         mo_graph->dot_print_edge(file,
2937                                         thread_array[id_to_int(act->get_tid())],
2938                                         act,
2939                                         "label=\"sb\", color=blue, weight=400");
2940                 }
2941
2942                 thread_array[act->get_tid()] = act;
2943         }
2944         fprintf(file, "}\n");
2945         model_free(thread_array);
2946         fclose(file);
2947 }
2948 #endif
2949
2950 /** @brief Prints an execution trace summary. */
2951 void ModelChecker::print_summary() const
2952 {
2953 #if SUPPORT_MOD_ORDER_DUMP
2954         char buffername[100];
2955         sprintf(buffername, "exec%04u", stats.num_total);
2956         mo_graph->dumpGraphToFile(buffername);
2957         sprintf(buffername, "graph%04u", stats.num_total);
2958         dumpGraph(buffername);
2959 #endif
2960
2961         model_print("Execution %d:", stats.num_total);
2962         if (isfeasibleprefix()) {
2963                 if (scheduler->all_threads_sleeping())
2964                         model_print(" SLEEP-SET REDUNDANT");
2965                 model_print("\n");
2966         } else
2967                 print_infeasibility(" INFEASIBLE");
2968         print_list(action_trace);
2969         model_print("\n");
2970         if (!promises->empty()) {
2971                 model_print("Pending promises:\n");
2972                 for (unsigned int i = 0; i < promises->size(); i++) {
2973                         model_print(" [P%u] ", i);
2974                         (*promises)[i]->print();
2975                 }
2976                 model_print("\n");
2977         }
2978 }
2979
2980 /**
2981  * Add a Thread to the system for the first time. Should only be called once
2982  * per thread.
2983  * @param t The Thread to add
2984  */
2985 void ModelChecker::add_thread(Thread *t)
2986 {
2987         thread_map->put(id_to_int(t->get_id()), t);
2988         scheduler->add_thread(t);
2989 }
2990
2991 /**
2992  * @brief Get a Thread reference by its ID
2993  * @param tid The Thread's ID
2994  * @return A Thread reference
2995  */
2996 Thread * ModelChecker::get_thread(thread_id_t tid) const
2997 {
2998         return thread_map->get(id_to_int(tid));
2999 }
3000
3001 /**
3002  * @brief Get a reference to the Thread in which a ModelAction was executed
3003  * @param act The ModelAction
3004  * @return A Thread reference
3005  */
3006 Thread * ModelChecker::get_thread(const ModelAction *act) const
3007 {
3008         return get_thread(act->get_tid());
3009 }
3010
3011 /**
3012  * @brief Get a Promise's "promise number"
3013  *
3014  * A "promise number" is an index number that is unique to a promise, valid
3015  * only for a specific snapshot of an execution trace. Promises may come and go
3016  * as they are generated an resolved, so an index only retains meaning for the
3017  * current snapshot.
3018  *
3019  * @param promise The Promise to check
3020  * @return The promise index, if the promise still is valid; otherwise -1
3021  */
3022 int ModelChecker::get_promise_number(const Promise *promise) const
3023 {
3024         for (unsigned int i = 0; i < promises->size(); i++)
3025                 if ((*promises)[i] == promise)
3026                         return i;
3027         /* Not found */
3028         return -1;
3029 }
3030
3031 /**
3032  * @brief Check if a Thread is currently enabled
3033  * @param t The Thread to check
3034  * @return True if the Thread is currently enabled
3035  */
3036 bool ModelChecker::is_enabled(Thread *t) const
3037 {
3038         return scheduler->is_enabled(t);
3039 }
3040
3041 /**
3042  * @brief Check if a Thread is currently enabled
3043  * @param tid The ID of the Thread to check
3044  * @return True if the Thread is currently enabled
3045  */
3046 bool ModelChecker::is_enabled(thread_id_t tid) const
3047 {
3048         return scheduler->is_enabled(tid);
3049 }
3050
3051 /**
3052  * Switch from a model-checker context to a user-thread context. This is the
3053  * complement of ModelChecker::switch_to_master and must be called from the
3054  * model-checker context
3055  *
3056  * @param thread The user-thread to switch to
3057  */
3058 void ModelChecker::switch_from_master(Thread *thread)
3059 {
3060         scheduler->set_current_thread(thread);
3061         Thread::swap(&system_context, thread);
3062 }
3063
3064 /**
3065  * Switch from a user-context to the "master thread" context (a.k.a. system
3066  * context). This switch is made with the intention of exploring a particular
3067  * model-checking action (described by a ModelAction object). Must be called
3068  * from a user-thread context.
3069  *
3070  * @param act The current action that will be explored. May be NULL only if
3071  * trace is exiting via an assertion (see ModelChecker::set_assert and
3072  * ModelChecker::has_asserted).
3073  * @return Return the value returned by the current action
3074  */
3075 uint64_t ModelChecker::switch_to_master(ModelAction *act)
3076 {
3077         DBG();
3078         Thread *old = thread_current();
3079         scheduler->set_current_thread(NULL);
3080         ASSERT(!old->get_pending());
3081         old->set_pending(act);
3082         if (Thread::swap(old, &system_context) < 0) {
3083                 perror("swap threads");
3084                 exit(EXIT_FAILURE);
3085         }
3086         return old->get_return_value();
3087 }
3088
3089 /**
3090  * Takes the next step in the execution, if possible.
3091  * @param curr The current step to take
3092  * @return Returns the next Thread to run, if any; NULL if this execution
3093  * should terminate
3094  */
3095 Thread * ModelChecker::take_step(ModelAction *curr)
3096 {
3097         Thread *curr_thrd = get_thread(curr);
3098         ASSERT(curr_thrd->get_state() == THREAD_READY);
3099
3100         ASSERT(check_action_enabled(curr)); /* May have side effects? */
3101         curr = check_current_action(curr);
3102         ASSERT(curr);
3103
3104         if (curr_thrd->is_blocked() || curr_thrd->is_complete())
3105                 scheduler->remove_thread(curr_thrd);
3106
3107         return action_select_next_thread(curr);
3108 }
3109
3110 /** Wrapper to run the user's main function, with appropriate arguments */
3111 void user_main_wrapper(void *)
3112 {
3113         user_main(model->params.argc, model->params.argv);
3114 }
3115
3116 /** @return True if the execution has taken too many steps */
3117 bool ModelChecker::too_many_steps() const
3118 {
3119         return params.bound != 0 && priv->used_sequence_numbers > params.bound;
3120 }
3121
3122 bool ModelChecker::should_terminate_execution()
3123 {
3124         /* Infeasible -> don't take any more steps */
3125         if (is_infeasible())
3126                 return true;
3127         else if (isfeasibleprefix() && have_bug_reports()) {
3128                 set_assert();
3129                 return true;
3130         }
3131
3132         if (too_many_steps())
3133                 return true;
3134         return false;
3135 }
3136
3137 /** @brief Run ModelChecker for the user program */
3138 void ModelChecker::run()
3139 {
3140         do {
3141                 thrd_t user_thread;
3142                 Thread *t = new Thread(&user_thread, &user_main_wrapper, NULL, NULL);
3143                 add_thread(t);
3144
3145                 do {
3146                         /*
3147                          * Stash next pending action(s) for thread(s). There
3148                          * should only need to stash one thread's action--the
3149                          * thread which just took a step--plus the first step
3150                          * for any newly-created thread
3151                          */
3152                         for (unsigned int i = 0; i < get_num_threads(); i++) {
3153                                 thread_id_t tid = int_to_id(i);
3154                                 Thread *thr = get_thread(tid);
3155                                 if (!thr->is_model_thread() && !thr->is_complete() && !thr->get_pending()) {
3156                                         switch_from_master(thr);
3157                                         if (thr->is_waiting_on(thr))
3158                                                 assert_bug("Deadlock detected (thread %u)", i);
3159                                 }
3160                         }
3161
3162                         /* Don't schedule threads which should be disabled */
3163                         for (unsigned int i = 0; i < get_num_threads(); i++) {
3164                                 Thread *th = get_thread(int_to_id(i));
3165                                 ModelAction *act = th->get_pending();
3166                                 if (act && is_enabled(th) && !check_action_enabled(act)) {
3167                                         scheduler->sleep(th);
3168                                 }
3169                         }
3170
3171                         /* Catch assertions from prior take_step or from
3172                          * between-ModelAction bugs (e.g., data races) */
3173                         if (has_asserted())
3174                                 break;
3175
3176                         if (!t)
3177                                 t = get_next_thread();
3178                         if (!t || t->is_model_thread())
3179                                 break;
3180
3181                         /* Consume the next action for a Thread */
3182                         ModelAction *curr = t->get_pending();
3183                         t->set_pending(NULL);
3184                         t = take_step(curr);
3185                 } while (!should_terminate_execution());
3186
3187                 /*
3188                  * Launch end-of-execution release sequence fixups only when
3189                  * the execution is otherwise feasible AND there are:
3190                  *
3191                  * (1) pending release sequences
3192                  * (2) pending assertions that could be invalidated by a change
3193                  * in clock vectors (i.e., data races)
3194                  * (3) no pending promises
3195                  */
3196                 while (!pending_rel_seqs->empty() &&
3197                                 is_feasible_prefix_ignore_relseq() &&
3198                                 !unrealizedraces.empty()) {
3199                         model_print("*** WARNING: release sequence fixup action "
3200                                         "(%zu pending release seuqence(s)) ***\n",
3201                                         pending_rel_seqs->size());
3202                         ModelAction *fixup = new ModelAction(MODEL_FIXUP_RELSEQ,
3203                                         std::memory_order_seq_cst, NULL, VALUE_NONE,
3204                                         model_thread);
3205                         take_step(fixup);
3206                 };
3207         } while (next_execution());
3208
3209         model_print("******* Model-checking complete: *******\n");
3210         print_stats();
3211 }