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