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