model: clear a ModelAction's reads-from properly
[model-checker.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->is_sleep_set(thr) && thr->get_pending() == NULL) {
290                         thr->set_state(THREAD_RUNNING);
291                         scheduler->next_thread(thr);
292                         Thread::swap(&system_context, thr);
293                         priv->current_action->set_sleep_flag();
294                         thr->set_pending(priv->current_action);
295                 }
296         }
297         priv->current_action = NULL;
298 }
299
300 void ModelChecker::wake_up_sleeping_actions(ModelAction *curr)
301 {
302         for (unsigned int i = 0; i < get_num_threads(); i++) {
303                 Thread *thr = get_thread(int_to_id(i));
304                 if (scheduler->is_sleep_set(thr)) {
305                         ModelAction *pending_act = thr->get_pending();
306                         if ((!curr->is_rmwr()) && pending_act->could_synchronize_with(curr))
307                                 //Remove this thread from sleep set
308                                 scheduler->remove_sleep(thr);
309                 }
310         }
311 }
312
313 /** @brief Alert the model-checker that an incorrectly-ordered
314  * synchronization was made */
315 void ModelChecker::set_bad_synchronization()
316 {
317         priv->bad_synchronization = true;
318 }
319
320 bool ModelChecker::has_asserted() const
321 {
322         return priv->asserted;
323 }
324
325 void ModelChecker::set_assert()
326 {
327         priv->asserted = true;
328 }
329
330 /**
331  * Check if we are in a deadlock. Should only be called at the end of an
332  * execution, although it should not give false positives in the middle of an
333  * execution (there should be some ENABLED thread).
334  *
335  * @return True if program is in a deadlock; false otherwise
336  */
337 bool ModelChecker::is_deadlocked() const
338 {
339         bool blocking_threads = false;
340         for (unsigned int i = 0; i < get_num_threads(); i++) {
341                 thread_id_t tid = int_to_id(i);
342                 if (is_enabled(tid))
343                         return false;
344                 Thread *t = get_thread(tid);
345                 if (!t->is_model_thread() && t->get_pending())
346                         blocking_threads = true;
347         }
348         return blocking_threads;
349 }
350
351 /**
352  * Check if this is a complete execution. That is, have all thread completed
353  * execution (rather than exiting because sleep sets have forced a redundant
354  * execution).
355  *
356  * @return True if the execution is complete.
357  */
358 bool ModelChecker::is_complete_execution() const
359 {
360         for (unsigned int i = 0; i < get_num_threads(); i++)
361                 if (is_enabled(int_to_id(i)))
362                         return false;
363         return true;
364 }
365
366 /**
367  * @brief Assert a bug in the executing program.
368  *
369  * Use this function to assert any sort of bug in the user program. If the
370  * current trace is feasible (actually, a prefix of some feasible execution),
371  * then this execution will be aborted, printing the appropriate message. If
372  * the current trace is not yet feasible, the error message will be stashed and
373  * printed if the execution ever becomes feasible.
374  *
375  * @param msg Descriptive message for the bug (do not include newline char)
376  * @return True if bug is immediately-feasible
377  */
378 bool ModelChecker::assert_bug(const char *msg)
379 {
380         priv->bugs.push_back(new bug_message(msg));
381
382         if (isfeasibleprefix()) {
383                 set_assert();
384                 return true;
385         }
386         return false;
387 }
388
389 /**
390  * @brief Assert a bug in the executing program, asserted by a user thread
391  * @see ModelChecker::assert_bug
392  * @param msg Descriptive message for the bug (do not include newline char)
393  */
394 void ModelChecker::assert_user_bug(const char *msg)
395 {
396         /* If feasible bug, bail out now */
397         if (assert_bug(msg))
398                 switch_to_master(NULL);
399 }
400
401 /** @return True, if any bugs have been reported for this execution */
402 bool ModelChecker::have_bug_reports() const
403 {
404         return priv->bugs.size() != 0;
405 }
406
407 /** @brief Print bug report listing for this execution (if any bugs exist) */
408 void ModelChecker::print_bugs() const
409 {
410         if (have_bug_reports()) {
411                 model_print("Bug report: %zu bug%s detected\n",
412                                 priv->bugs.size(),
413                                 priv->bugs.size() > 1 ? "s" : "");
414                 for (unsigned int i = 0; i < priv->bugs.size(); i++)
415                         priv->bugs[i]->print();
416         }
417 }
418
419 /**
420  * @brief Record end-of-execution stats
421  *
422  * Must be run when exiting an execution. Records various stats.
423  * @see struct execution_stats
424  */
425 void ModelChecker::record_stats()
426 {
427         stats.num_total++;
428         if (!isfeasibleprefix())
429                 stats.num_infeasible++;
430         else if (have_bug_reports())
431                 stats.num_buggy_executions++;
432         else if (is_complete_execution())
433                 stats.num_complete++;
434         else
435                 stats.num_redundant++;
436 }
437
438 /** @brief Print execution stats */
439 void ModelChecker::print_stats() const
440 {
441         model_print("Number of complete, bug-free executions: %d\n", stats.num_complete);
442         model_print("Number of redundant executions: %d\n", stats.num_redundant);
443         model_print("Number of buggy executions: %d\n", stats.num_buggy_executions);
444         model_print("Number of infeasible executions: %d\n", stats.num_infeasible);
445         model_print("Total executions: %d\n", stats.num_total);
446         model_print("Total nodes created: %d\n", node_stack->get_total_nodes());
447 }
448
449 /**
450  * @brief End-of-exeuction print
451  * @param printbugs Should any existing bugs be printed?
452  */
453 void ModelChecker::print_execution(bool printbugs) const
454 {
455         print_program_output();
456
457         if (DBG_ENABLED() || params.verbose) {
458                 model_print("Earliest divergence point since last feasible execution:\n");
459                 if (earliest_diverge)
460                         earliest_diverge->print();
461                 else
462                         model_print("(Not set)\n");
463
464                 model_print("\n");
465                 print_stats();
466         }
467
468         /* Don't print invalid bugs */
469         if (printbugs)
470                 print_bugs();
471
472         model_print("\n");
473         print_summary();
474 }
475
476 /**
477  * Queries the model-checker for more executions to explore and, if one
478  * exists, resets the model-checker state to execute a new execution.
479  *
480  * @return If there are more executions to explore, return true. Otherwise,
481  * return false.
482  */
483 bool ModelChecker::next_execution()
484 {
485         DBG();
486         /* Is this execution a feasible execution that's worth bug-checking? */
487         bool complete = isfeasibleprefix() && (is_complete_execution() ||
488                         have_bug_reports());
489
490         /* End-of-execution bug checks */
491         if (complete) {
492                 if (is_deadlocked())
493                         assert_bug("Deadlock detected");
494
495                 checkDataRaces();
496         }
497
498         record_stats();
499
500         /* Output */
501         if (DBG_ENABLED() || params.verbose || have_bug_reports())
502                 print_execution(complete);
503         else
504                 clear_program_output();
505
506         if (complete)
507                 earliest_diverge = NULL;
508
509         if ((diverge = get_next_backtrack()) == NULL)
510                 return false;
511
512         if (DBG_ENABLED()) {
513                 model_print("Next execution will diverge at:\n");
514                 diverge->print();
515         }
516
517         reset_to_initial_state();
518         return true;
519 }
520
521 ModelAction * ModelChecker::get_last_conflict(ModelAction *act)
522 {
523         switch (act->get_type()) {
524         case ATOMIC_FENCE:
525         case ATOMIC_READ:
526         case ATOMIC_WRITE:
527         case ATOMIC_RMW: {
528                 /* Optimization: relaxed operations don't need backtracking */
529                 if (act->is_relaxed())
530                         return NULL;
531                 /* linear search: from most recent to oldest */
532                 action_list_t *list = get_safe_ptr_action(obj_map, act->get_location());
533                 action_list_t::reverse_iterator rit;
534                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
535                         ModelAction *prev = *rit;
536                         if (prev->could_synchronize_with(act))
537                                 return prev;
538                 }
539                 break;
540         }
541         case ATOMIC_LOCK:
542         case ATOMIC_TRYLOCK: {
543                 /* linear search: from most recent to oldest */
544                 action_list_t *list = get_safe_ptr_action(obj_map, act->get_location());
545                 action_list_t::reverse_iterator rit;
546                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
547                         ModelAction *prev = *rit;
548                         if (act->is_conflicting_lock(prev))
549                                 return prev;
550                 }
551                 break;
552         }
553         case ATOMIC_UNLOCK: {
554                 /* linear search: from most recent to oldest */
555                 action_list_t *list = get_safe_ptr_action(obj_map, act->get_location());
556                 action_list_t::reverse_iterator rit;
557                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
558                         ModelAction *prev = *rit;
559                         if (!act->same_thread(prev)&&prev->is_failed_trylock())
560                                 return prev;
561                 }
562                 break;
563         }
564         case ATOMIC_WAIT: {
565                 /* linear search: from most recent to oldest */
566                 action_list_t *list = get_safe_ptr_action(obj_map, act->get_location());
567                 action_list_t::reverse_iterator rit;
568                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
569                         ModelAction *prev = *rit;
570                         if (!act->same_thread(prev)&&prev->is_failed_trylock())
571                                 return prev;
572                         if (!act->same_thread(prev)&&prev->is_notify())
573                                 return prev;
574                 }
575                 break;
576         }
577
578         case ATOMIC_NOTIFY_ALL:
579         case ATOMIC_NOTIFY_ONE: {
580                 /* linear search: from most recent to oldest */
581                 action_list_t *list = get_safe_ptr_action(obj_map, act->get_location());
582                 action_list_t::reverse_iterator rit;
583                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
584                         ModelAction *prev = *rit;
585                         if (!act->same_thread(prev)&&prev->is_wait())
586                                 return prev;
587                 }
588                 break;
589         }
590         default:
591                 break;
592         }
593         return NULL;
594 }
595
596 /** This method finds backtracking points where we should try to
597  * reorder the parameter ModelAction against.
598  *
599  * @param the ModelAction to find backtracking points for.
600  */
601 void ModelChecker::set_backtracking(ModelAction *act)
602 {
603         Thread *t = get_thread(act);
604         ModelAction * prev = get_last_conflict(act);
605         if (prev == NULL)
606                 return;
607
608         Node * node = prev->get_node()->get_parent();
609
610         int low_tid, high_tid;
611         if (node->is_enabled(t)) {
612                 low_tid = id_to_int(act->get_tid());
613                 high_tid = low_tid+1;
614         } else {
615                 low_tid = 0;
616                 high_tid = get_num_threads();
617         }
618
619         for(int i = low_tid; i < high_tid; i++) {
620                 thread_id_t tid = int_to_id(i);
621
622                 /* Make sure this thread can be enabled here. */
623                 if (i >= node->get_num_threads())
624                         break;
625
626                 /* Don't backtrack into a point where the thread is disabled or sleeping. */
627                 if (node->enabled_status(tid)!=THREAD_ENABLED)
628                         continue;
629
630                 /* Check if this has been explored already */
631                 if (node->has_been_explored(tid))
632                         continue;
633
634                 /* See if fairness allows */
635                 if (model->params.fairwindow != 0 && !node->has_priority(tid)) {
636                         bool unfair=false;
637                         for(int t=0;t<node->get_num_threads();t++) {
638                                 thread_id_t tother=int_to_id(t);
639                                 if (node->is_enabled(tother) && node->has_priority(tother)) {
640                                         unfair=true;
641                                         break;
642                                 }
643                         }
644                         if (unfair)
645                                 continue;
646                 }
647                 /* Cache the latest backtracking point */
648                 if (!priv->next_backtrack || *prev > *priv->next_backtrack)
649                         priv->next_backtrack = prev;
650
651                 /* If this is a new backtracking point, mark the tree */
652                 if (!node->set_backtrack(tid))
653                         continue;
654                 DEBUG("Setting backtrack: conflict = %d, instead tid = %d\n",
655                                         id_to_int(prev->get_tid()),
656                                         id_to_int(t->get_id()));
657                 if (DBG_ENABLED()) {
658                         prev->print();
659                         act->print();
660                 }
661         }
662 }
663
664 /**
665  * Returns last backtracking point. The model checker will explore a different
666  * path for this point in the next execution.
667  * @return The ModelAction at which the next execution should diverge.
668  */
669 ModelAction * ModelChecker::get_next_backtrack()
670 {
671         ModelAction *next = priv->next_backtrack;
672         priv->next_backtrack = NULL;
673         return next;
674 }
675
676 /**
677  * Processes a read or rmw model action.
678  * @param curr is the read model action to process.
679  * @param second_part_of_rmw is boolean that is true is this is the second action of a rmw.
680  * @return True if processing this read updates the mo_graph.
681  */
682 bool ModelChecker::process_read(ModelAction *curr, bool second_part_of_rmw)
683 {
684         uint64_t value = VALUE_NONE;
685         bool updated = false;
686         while (true) {
687                 const ModelAction *reads_from = curr->get_node()->get_read_from();
688                 if (reads_from != NULL) {
689                         mo_graph->startChanges();
690
691                         value = reads_from->get_value();
692                         bool r_status = false;
693
694                         if (!second_part_of_rmw) {
695                                 check_recency(curr, reads_from);
696                                 r_status = r_modification_order(curr, reads_from);
697                         }
698
699
700                         if (!second_part_of_rmw&&is_infeasible()&&(curr->get_node()->increment_read_from()||curr->get_node()->increment_future_value())) {
701                                 mo_graph->rollbackChanges();
702                                 priv->too_many_reads = false;
703                                 continue;
704                         }
705
706                         read_from(curr, reads_from);
707                         mo_graph->commitChanges();
708                         mo_check_promises(curr->get_tid(), reads_from);
709
710                         updated |= r_status;
711                 } else if (!second_part_of_rmw) {
712                         /* Read from future value */
713                         value = curr->get_node()->get_future_value();
714                         modelclock_t expiration = curr->get_node()->get_future_value_expiration();
715                         curr->set_read_from(NULL);
716                         Promise *valuepromise = new Promise(curr, value, expiration);
717                         promises->push_back(valuepromise);
718                 }
719                 get_thread(curr)->set_return_value(value);
720                 return updated;
721         }
722 }
723
724 /**
725  * Processes a lock, trylock, or unlock model action.  @param curr is
726  * the read model action to process.
727  *
728  * The try lock operation checks whether the lock is taken.  If not,
729  * it falls to the normal lock operation case.  If so, it returns
730  * fail.
731  *
732  * The lock operation has already been checked that it is enabled, so
733  * it just grabs the lock and synchronizes with the previous unlock.
734  *
735  * The unlock operation has to re-enable all of the threads that are
736  * waiting on the lock.
737  *
738  * @return True if synchronization was updated; false otherwise
739  */
740 bool ModelChecker::process_mutex(ModelAction *curr) {
741         std::mutex *mutex=NULL;
742         struct std::mutex_state *state=NULL;
743
744         if (curr->is_trylock() || curr->is_lock() || curr->is_unlock()) {
745                 mutex = (std::mutex *)curr->get_location();
746                 state = mutex->get_state();
747         } else if(curr->is_wait()) {
748                 mutex = (std::mutex *)curr->get_value();
749                 state = mutex->get_state();
750         }
751
752         switch (curr->get_type()) {
753         case ATOMIC_TRYLOCK: {
754                 bool success = !state->islocked;
755                 curr->set_try_lock(success);
756                 if (!success) {
757                         get_thread(curr)->set_return_value(0);
758                         break;
759                 }
760                 get_thread(curr)->set_return_value(1);
761         }
762                 //otherwise fall into the lock case
763         case ATOMIC_LOCK: {
764                 if (curr->get_cv()->getClock(state->alloc_tid) <= state->alloc_clock)
765                         assert_bug("Lock access before initialization");
766                 state->islocked = true;
767                 ModelAction *unlock = get_last_unlock(curr);
768                 //synchronize with the previous unlock statement
769                 if (unlock != NULL) {
770                         curr->synchronize_with(unlock);
771                         return true;
772                 }
773                 break;
774         }
775         case ATOMIC_UNLOCK: {
776                 //unlock the lock
777                 state->islocked = false;
778                 //wake up the other threads
779                 action_list_t *waiters = get_safe_ptr_action(lock_waiters_map, curr->get_location());
780                 //activate all the waiting threads
781                 for (action_list_t::iterator rit = waiters->begin(); rit != waiters->end(); rit++) {
782                         scheduler->wake(get_thread(*rit));
783                 }
784                 waiters->clear();
785                 break;
786         }
787         case ATOMIC_WAIT: {
788                 //unlock the lock
789                 state->islocked = false;
790                 //wake up the other threads
791                 action_list_t *waiters = get_safe_ptr_action(lock_waiters_map, (void *) curr->get_value());
792                 //activate all the waiting threads
793                 for (action_list_t::iterator rit = waiters->begin(); rit != waiters->end(); rit++) {
794                         scheduler->wake(get_thread(*rit));
795                 }
796                 waiters->clear();
797                 //check whether we should go to sleep or not...simulate spurious failures
798                 if (curr->get_node()->get_misc()==0) {
799                         get_safe_ptr_action(condvar_waiters_map, curr->get_location())->push_back(curr);
800                         //disable us
801                         scheduler->sleep(get_current_thread());
802                 }
803                 break;
804         }
805         case ATOMIC_NOTIFY_ALL: {
806                 action_list_t *waiters = get_safe_ptr_action(condvar_waiters_map, curr->get_location());
807                 //activate all the waiting threads
808                 for (action_list_t::iterator rit = waiters->begin(); rit != waiters->end(); rit++) {
809                         scheduler->wake(get_thread(*rit));
810                 }
811                 waiters->clear();
812                 break;
813         }
814         case ATOMIC_NOTIFY_ONE: {
815                 action_list_t *waiters = get_safe_ptr_action(condvar_waiters_map, curr->get_location());
816                 int wakeupthread=curr->get_node()->get_misc();
817                 action_list_t::iterator it = waiters->begin();
818                 advance(it, wakeupthread);
819                 scheduler->wake(get_thread(*it));
820                 waiters->erase(it);
821                 break;
822         }
823
824         default:
825                 ASSERT(0);
826         }
827         return false;
828 }
829
830 /**
831  * Process a write ModelAction
832  * @param curr The ModelAction to process
833  * @return True if the mo_graph was updated or promises were resolved
834  */
835 bool ModelChecker::process_write(ModelAction *curr)
836 {
837         bool updated_mod_order = w_modification_order(curr);
838         bool updated_promises = resolve_promises(curr);
839
840         if (promises->size() == 0) {
841                 for (unsigned int i = 0; i < futurevalues->size(); i++) {
842                         struct PendingFutureValue pfv = (*futurevalues)[i];
843                         //Do more ambitious checks now that mo is more complete
844                         if (mo_may_allow(pfv.writer, pfv.act)&&
845                                         pfv.act->get_node()->add_future_value(pfv.writer->get_value(), pfv.writer->get_seq_number()+params.maxfuturedelay) &&
846                                         (!priv->next_backtrack || *pfv.act > *priv->next_backtrack))
847                                 priv->next_backtrack = pfv.act;
848                 }
849                 futurevalues->resize(0);
850         }
851
852         mo_graph->commitChanges();
853         mo_check_promises(curr->get_tid(), curr);
854
855         get_thread(curr)->set_return_value(VALUE_NONE);
856         return updated_mod_order || updated_promises;
857 }
858
859 /**
860  * Process a fence ModelAction
861  * @param curr The ModelAction to process
862  * @return True if synchronization was updated
863  */
864 bool ModelChecker::process_fence(ModelAction *curr)
865 {
866         /*
867          * fence-relaxed: no-op
868          * fence-release: only log the occurence (not in this function), for
869          *   use in later synchronization
870          * fence-acquire (this function): search for hypothetical release
871          *   sequences
872          */
873         bool updated = false;
874         if (curr->is_acquire()) {
875                 action_list_t *list = action_trace;
876                 action_list_t::reverse_iterator rit;
877                 /* Find X : is_read(X) && X --sb-> curr */
878                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
879                         ModelAction *act = *rit;
880                         if (act == curr)
881                                 continue;
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 (!curr->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                                         break;
1519                                 }
1520                                 /* C++, Section 29.3 statement 4 */
1521                                 else if (act->is_seqcst() && last_sc_fence_local &&
1522                                                 *act < *last_sc_fence_local) {
1523                                         mo_graph->addEdge(act, rf);
1524                                         added = true;
1525                                         break;
1526                                 }
1527                                 /* C++, Section 29.3 statement 6 */
1528                                 else if (last_sc_fence_thread_before &&
1529                                                 *act < *last_sc_fence_thread_before) {
1530                                         mo_graph->addEdge(act, rf);
1531                                         added = true;
1532                                         break;
1533                                 }
1534                         }
1535
1536                         /*
1537                          * Include at most one act per-thread that "happens
1538                          * before" curr. Don't consider reflexively.
1539                          */
1540                         if (act->happens_before(curr) && act != curr) {
1541                                 if (act->is_write()) {
1542                                         if (rf != act) {
1543                                                 mo_graph->addEdge(act, rf);
1544                                                 added = true;
1545                                         }
1546                                 } else {
1547                                         const ModelAction *prevreadfrom = act->get_reads_from();
1548                                         //if the previous read is unresolved, keep going...
1549                                         if (prevreadfrom == NULL)
1550                                                 continue;
1551
1552                                         if (rf != prevreadfrom) {
1553                                                 mo_graph->addEdge(prevreadfrom, rf);
1554                                                 added = true;
1555                                         }
1556                                 }
1557                                 break;
1558                         }
1559                 }
1560         }
1561
1562         return added;
1563 }
1564
1565 /** This method fixes up the modification order when we resolve a
1566  *  promises.  The basic problem is that actions that occur after the
1567  *  read curr could not property add items to the modification order
1568  *  for our read.
1569  *
1570  *  So for each thread, we find the earliest item that happens after
1571  *  the read curr.  This is the item we have to fix up with additional
1572  *  constraints.  If that action is write, we add a MO edge between
1573  *  the Action rf and that action.  If the action is a read, we add a
1574  *  MO edge between the Action rf, and whatever the read accessed.
1575  *
1576  * @param curr is the read ModelAction that we are fixing up MO edges for.
1577  * @param rf is the write ModelAction that curr reads from.
1578  *
1579  */
1580 void ModelChecker::post_r_modification_order(ModelAction *curr, const ModelAction *rf)
1581 {
1582         std::vector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
1583         unsigned int i;
1584         ASSERT(curr->is_read());
1585
1586         /* Iterate over all threads */
1587         for (i = 0; i < thrd_lists->size(); i++) {
1588                 /* Iterate over actions in thread, starting from most recent */
1589                 action_list_t *list = &(*thrd_lists)[i];
1590                 action_list_t::reverse_iterator rit;
1591                 ModelAction *lastact = NULL;
1592
1593                 /* Find last action that happens after curr that is either not curr or a rmw */
1594                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
1595                         ModelAction *act = *rit;
1596                         if (curr->happens_before(act) && (curr != act || curr->is_rmw())) {
1597                                 lastact = act;
1598                         } else
1599                                 break;
1600                 }
1601
1602                         /* Include at most one act per-thread that "happens before" curr */
1603                 if (lastact != NULL) {
1604                         if (lastact==curr) {
1605                                 //Case 1: The resolved read is a RMW, and we need to make sure
1606                                 //that the write portion of the RMW mod order after rf
1607
1608                                 mo_graph->addEdge(rf, lastact);
1609                         } else if (lastact->is_read()) {
1610                                 //Case 2: The resolved read is a normal read and the next
1611                                 //operation is a read, and we need to make sure the value read
1612                                 //is mod ordered after rf
1613
1614                                 const ModelAction *postreadfrom = lastact->get_reads_from();
1615                                 if (postreadfrom != NULL&&rf != postreadfrom)
1616                                         mo_graph->addEdge(rf, postreadfrom);
1617                         } else {
1618                                 //Case 3: The resolved read is a normal read and the next
1619                                 //operation is a write, and we need to make sure that the
1620                                 //write is mod ordered after rf
1621                                 if (lastact!=rf)
1622                                         mo_graph->addEdge(rf, lastact);
1623                         }
1624                         break;
1625                 }
1626         }
1627 }
1628
1629 /**
1630  * Updates the mo_graph with the constraints imposed from the current write.
1631  *
1632  * Basic idea is the following: Go through each other thread and find
1633  * the lastest action that happened before our write.  Two cases:
1634  *
1635  * (1) The action is a write => that write must occur before
1636  * the current write
1637  *
1638  * (2) The action is a read => the write that that action read from
1639  * must occur before the current write.
1640  *
1641  * This method also handles two other issues:
1642  *
1643  * (I) Sequential Consistency: Making sure that if the current write is
1644  * seq_cst, that it occurs after the previous seq_cst write.
1645  *
1646  * (II) Sending the write back to non-synchronizing reads.
1647  *
1648  * @param curr The current action. Must be a write.
1649  * @return True if modification order edges were added; false otherwise
1650  */
1651 bool ModelChecker::w_modification_order(ModelAction *curr)
1652 {
1653         std::vector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
1654         unsigned int i;
1655         bool added = false;
1656         ASSERT(curr->is_write());
1657
1658         if (curr->is_seqcst()) {
1659                 /* We have to at least see the last sequentially consistent write,
1660                          so we are initialized. */
1661                 ModelAction *last_seq_cst = get_last_seq_cst_write(curr);
1662                 if (last_seq_cst != NULL) {
1663                         mo_graph->addEdge(last_seq_cst, curr);
1664                         added = true;
1665                 }
1666         }
1667
1668         /* Last SC fence in the current thread */
1669         ModelAction *last_sc_fence_local = get_last_seq_cst_fence(curr->get_tid(), NULL);
1670
1671         /* Iterate over all threads */
1672         for (i = 0; i < thrd_lists->size(); i++) {
1673                 /* Last SC fence in thread i, before last SC fence in current thread */
1674                 ModelAction *last_sc_fence_thread_before = NULL;
1675                 if (last_sc_fence_local && int_to_id((int)i) != curr->get_tid())
1676                         last_sc_fence_thread_before = get_last_seq_cst_fence(int_to_id(i), last_sc_fence_local);
1677
1678                 /* Iterate over actions in thread, starting from most recent */
1679                 action_list_t *list = &(*thrd_lists)[i];
1680                 action_list_t::reverse_iterator rit;
1681                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
1682                         ModelAction *act = *rit;
1683                         if (act == curr) {
1684                                 /*
1685                                  * 1) If RMW and it actually read from something, then we
1686                                  * already have all relevant edges, so just skip to next
1687                                  * thread.
1688                                  *
1689                                  * 2) If RMW and it didn't read from anything, we should
1690                                  * whatever edge we can get to speed up convergence.
1691                                  *
1692                                  * 3) If normal write, we need to look at earlier actions, so
1693                                  * continue processing list.
1694                                  */
1695                                 if (curr->is_rmw()) {
1696                                         if (curr->get_reads_from()!=NULL)
1697                                                 break;
1698                                         else
1699                                                 continue;
1700                                 } else
1701                                         continue;
1702                         }
1703
1704                         /* C++, Section 29.3 statement 7 */
1705                         if (last_sc_fence_thread_before && act->is_write() &&
1706                                         *act < *last_sc_fence_thread_before) {
1707                                 mo_graph->addEdge(act, curr);
1708                                 added = true;
1709                                 break;
1710                         }
1711
1712                         /*
1713                          * Include at most one act per-thread that "happens
1714                          * before" curr
1715                          */
1716                         if (act->happens_before(curr)) {
1717                                 /*
1718                                  * Note: if act is RMW, just add edge:
1719                                  *   act --mo--> curr
1720                                  * The following edge should be handled elsewhere:
1721                                  *   readfrom(act) --mo--> act
1722                                  */
1723                                 if (act->is_write())
1724                                         mo_graph->addEdge(act, curr);
1725                                 else if (act->is_read()) {
1726                                         //if previous read accessed a null, just keep going
1727                                         if (act->get_reads_from() == NULL)
1728                                                 continue;
1729                                         mo_graph->addEdge(act->get_reads_from(), curr);
1730                                 }
1731                                 added = true;
1732                                 break;
1733                         } else if (act->is_read() && !act->could_synchronize_with(curr) &&
1734                                                      !act->same_thread(curr)) {
1735                                 /* We have an action that:
1736                                    (1) did not happen before us
1737                                    (2) is a read and we are a write
1738                                    (3) cannot synchronize with us
1739                                    (4) is in a different thread
1740                                    =>
1741                                    that read could potentially read from our write.  Note that
1742                                    these checks are overly conservative at this point, we'll
1743                                    do more checks before actually removing the
1744                                    pendingfuturevalue.
1745
1746                                  */
1747                                 if (thin_air_constraint_may_allow(curr, act)) {
1748                                         if (!is_infeasible() ||
1749                                                         (curr->is_rmw() && act->is_rmw() && curr->get_reads_from() == act->get_reads_from() && !is_infeasible_ignoreRMW())) {
1750                                                 struct PendingFutureValue pfv = {curr,act};
1751                                                 futurevalues->push_back(pfv);
1752                                         }
1753                                 }
1754                         }
1755                 }
1756         }
1757
1758         return added;
1759 }
1760
1761 /** Arbitrary reads from the future are not allowed.  Section 29.3
1762  * part 9 places some constraints.  This method checks one result of constraint
1763  * constraint.  Others require compiler support. */
1764 bool ModelChecker::thin_air_constraint_may_allow(const ModelAction * writer, const ModelAction *reader) {
1765         if (!writer->is_rmw())
1766                 return true;
1767
1768         if (!reader->is_rmw())
1769                 return true;
1770
1771         for (const ModelAction *search = writer->get_reads_from(); search != NULL; search = search->get_reads_from()) {
1772                 if (search == reader)
1773                         return false;
1774                 if (search->get_tid() == reader->get_tid() &&
1775                                 search->happens_before(reader))
1776                         break;
1777         }
1778
1779         return true;
1780 }
1781
1782 /**
1783  * Arbitrary reads from the future are not allowed. Section 29.3 part 9 places
1784  * some constraints. This method checks one the following constraint (others
1785  * require compiler support):
1786  *
1787  *   If X --hb-> Y --mo-> Z, then X should not read from Z.
1788  */
1789 bool ModelChecker::mo_may_allow(const ModelAction *writer, const ModelAction *reader)
1790 {
1791         std::vector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, reader->get_location());
1792         unsigned int i;
1793         /* Iterate over all threads */
1794         for (i = 0; i < thrd_lists->size(); i++) {
1795                 const ModelAction *write_after_read = NULL;
1796
1797                 /* Iterate over actions in thread, starting from most recent */
1798                 action_list_t *list = &(*thrd_lists)[i];
1799                 action_list_t::reverse_iterator rit;
1800                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
1801                         ModelAction *act = *rit;
1802
1803                         if (!reader->happens_before(act))
1804                                 break;
1805                         else if (act->is_write())
1806                                 write_after_read = act;
1807                         else if (act->is_read() && act->get_reads_from() != NULL && act != reader) {
1808                                 write_after_read = act->get_reads_from();
1809                         }
1810                 }
1811
1812                 if (write_after_read && write_after_read!=writer && mo_graph->checkReachable(write_after_read, writer))
1813                         return false;
1814         }
1815         return true;
1816 }
1817
1818 /**
1819  * Finds the head(s) of the release sequence(s) containing a given ModelAction.
1820  * The ModelAction under consideration is expected to be taking part in
1821  * release/acquire synchronization as an object of the "reads from" relation.
1822  * Note that this can only provide release sequence support for RMW chains
1823  * which do not read from the future, as those actions cannot be traced until
1824  * their "promise" is fulfilled. Similarly, we may not even establish the
1825  * presence of a release sequence with certainty, as some modification order
1826  * constraints may be decided further in the future. Thus, this function
1827  * "returns" two pieces of data: a pass-by-reference vector of @a release_heads
1828  * and a boolean representing certainty.
1829  *
1830  * @param rf The action that might be part of a release sequence. Must be a
1831  * write.
1832  * @param release_heads A pass-by-reference style return parameter. After
1833  * execution of this function, release_heads will contain the heads of all the
1834  * relevant release sequences, if any exists with certainty
1835  * @param pending A pass-by-reference style return parameter which is only used
1836  * when returning false (i.e., uncertain). Returns most information regarding
1837  * an uncertain release sequence, including any write operations that might
1838  * break the sequence.
1839  * @return true, if the ModelChecker is certain that release_heads is complete;
1840  * false otherwise
1841  */
1842 bool ModelChecker::release_seq_heads(const ModelAction *rf,
1843                 rel_heads_list_t *release_heads,
1844                 struct release_seq *pending) const
1845 {
1846         /* Only check for release sequences if there are no cycles */
1847         if (mo_graph->checkForCycles())
1848                 return false;
1849
1850         while (rf) {
1851                 ASSERT(rf->is_write());
1852
1853                 if (rf->is_release())
1854                         release_heads->push_back(rf);
1855                 else if (rf->get_last_fence_release())
1856                         release_heads->push_back(rf->get_last_fence_release());
1857                 if (!rf->is_rmw())
1858                         break; /* End of RMW chain */
1859
1860                 /** @todo Need to be smarter here...  In the linux lock
1861                  * example, this will run to the beginning of the program for
1862                  * every acquire. */
1863                 /** @todo The way to be smarter here is to keep going until 1
1864                  * thread has a release preceded by an acquire and you've seen
1865                  *       both. */
1866
1867                 /* acq_rel RMW is a sufficient stopping condition */
1868                 if (rf->is_acquire() && rf->is_release())
1869                         return true; /* complete */
1870
1871                 rf = rf->get_reads_from();
1872         };
1873         if (!rf) {
1874                 /* read from future: need to settle this later */
1875                 pending->rf = NULL;
1876                 return false; /* incomplete */
1877         }
1878
1879         if (rf->is_release())
1880                 return true; /* complete */
1881
1882         /* else relaxed write
1883          * - check for fence-release in the same thread (29.8, stmt. 3)
1884          * - check modification order for contiguous subsequence
1885          *   -> rf must be same thread as release */
1886
1887         const ModelAction *fence_release = rf->get_last_fence_release();
1888         /* Synchronize with a fence-release unconditionally; we don't need to
1889          * find any more "contiguous subsequence..." for it */
1890         if (fence_release)
1891                 release_heads->push_back(fence_release);
1892
1893         int tid = id_to_int(rf->get_tid());
1894         std::vector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, rf->get_location());
1895         action_list_t *list = &(*thrd_lists)[tid];
1896         action_list_t::const_reverse_iterator rit;
1897
1898         /* Find rf in the thread list */
1899         rit = std::find(list->rbegin(), list->rend(), rf);
1900         ASSERT(rit != list->rend());
1901
1902         /* Find the last {write,fence}-release */
1903         for (; rit != list->rend(); rit++) {
1904                 if (fence_release && *(*rit) < *fence_release)
1905                         break;
1906                 if ((*rit)->is_release())
1907                         break;
1908         }
1909         if (rit == list->rend()) {
1910                 /* No write-release in this thread */
1911                 return true; /* complete */
1912         } else if (fence_release && *(*rit) < *fence_release) {
1913                 /* The fence-release is more recent (and so, "stronger") than
1914                  * the most recent write-release */
1915                 return true; /* complete */
1916         } /* else, need to establish contiguous release sequence */
1917         ModelAction *release = *rit;
1918
1919         ASSERT(rf->same_thread(release));
1920
1921         pending->writes.clear();
1922
1923         bool certain = true;
1924         for (unsigned int i = 0; i < thrd_lists->size(); i++) {
1925                 if (id_to_int(rf->get_tid()) == (int)i)
1926                         continue;
1927                 list = &(*thrd_lists)[i];
1928
1929                 /* Can we ensure no future writes from this thread may break
1930                  * the release seq? */
1931                 bool future_ordered = false;
1932
1933                 ModelAction *last = get_last_action(int_to_id(i));
1934                 Thread *th = get_thread(int_to_id(i));
1935                 if ((last && rf->happens_before(last)) ||
1936                                 !is_enabled(th) ||
1937                                 th->is_complete())
1938                         future_ordered = true;
1939
1940                 ASSERT(!th->is_model_thread() || future_ordered);
1941
1942                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
1943                         const ModelAction *act = *rit;
1944                         /* Reach synchronization -> this thread is complete */
1945                         if (act->happens_before(release))
1946                                 break;
1947                         if (rf->happens_before(act)) {
1948                                 future_ordered = true;
1949                                 continue;
1950                         }
1951
1952                         /* Only non-RMW writes can break release sequences */
1953                         if (!act->is_write() || act->is_rmw())
1954                                 continue;
1955
1956                         /* Check modification order */
1957                         if (mo_graph->checkReachable(rf, act)) {
1958                                 /* rf --mo--> act */
1959                                 future_ordered = true;
1960                                 continue;
1961                         }
1962                         if (mo_graph->checkReachable(act, release))
1963                                 /* act --mo--> release */
1964                                 break;
1965                         if (mo_graph->checkReachable(release, act) &&
1966                                       mo_graph->checkReachable(act, rf)) {
1967                                 /* release --mo-> act --mo--> rf */
1968                                 return true; /* complete */
1969                         }
1970                         /* act may break release sequence */
1971                         pending->writes.push_back(act);
1972                         certain = false;
1973                 }
1974                 if (!future_ordered)
1975                         certain = false; /* This thread is uncertain */
1976         }
1977
1978         if (certain) {
1979                 release_heads->push_back(release);
1980                 pending->writes.clear();
1981         } else {
1982                 pending->release = release;
1983                 pending->rf = rf;
1984         }
1985         return certain;
1986 }
1987
1988 /**
1989  * An interface for getting the release sequence head(s) with which a
1990  * given ModelAction must synchronize. This function only returns a non-empty
1991  * result when it can locate a release sequence head with certainty. Otherwise,
1992  * it may mark the internal state of the ModelChecker so that it will handle
1993  * the release sequence at a later time, causing @a acquire to update its
1994  * synchronization at some later point in execution.
1995  *
1996  * @param acquire The 'acquire' action that may synchronize with a release
1997  * sequence
1998  * @param read The read action that may read from a release sequence; this may
1999  * be the same as acquire, or else an earlier action in the same thread (i.e.,
2000  * when 'acquire' is a fence-acquire)
2001  * @param release_heads A pass-by-reference return parameter. Will be filled
2002  * with the head(s) of the release sequence(s), if they exists with certainty.
2003  * @see ModelChecker::release_seq_heads
2004  */
2005 void ModelChecker::get_release_seq_heads(ModelAction *acquire,
2006                 ModelAction *read, rel_heads_list_t *release_heads)
2007 {
2008         const ModelAction *rf = read->get_reads_from();
2009         struct release_seq *sequence = (struct release_seq *)snapshot_calloc(1, sizeof(struct release_seq));
2010         sequence->acquire = acquire;
2011         sequence->read = read;
2012
2013         if (!release_seq_heads(rf, release_heads, sequence)) {
2014                 /* add act to 'lazy checking' list */
2015                 pending_rel_seqs->push_back(sequence);
2016         } else {
2017                 snapshot_free(sequence);
2018         }
2019 }
2020
2021 /**
2022  * Attempt to resolve all stashed operations that might synchronize with a
2023  * release sequence for a given location. This implements the "lazy" portion of
2024  * determining whether or not a release sequence was contiguous, since not all
2025  * modification order information is present at the time an action occurs.
2026  *
2027  * @param location The location/object that should be checked for release
2028  * sequence resolutions. A NULL value means to check all locations.
2029  * @param work_queue The work queue to which to add work items as they are
2030  * generated
2031  * @return True if any updates occurred (new synchronization, new mo_graph
2032  * edges)
2033  */
2034 bool ModelChecker::resolve_release_sequences(void *location, work_queue_t *work_queue)
2035 {
2036         bool updated = false;
2037         std::vector< struct release_seq *, SnapshotAlloc<struct release_seq *> >::iterator it = pending_rel_seqs->begin();
2038         while (it != pending_rel_seqs->end()) {
2039                 struct release_seq *pending = *it;
2040                 ModelAction *acquire = pending->acquire;
2041                 const ModelAction *read = pending->read;
2042
2043                 /* Only resolve sequences on the given location, if provided */
2044                 if (location && read->get_location() != location) {
2045                         it++;
2046                         continue;
2047                 }
2048
2049                 const ModelAction *rf = read->get_reads_from();
2050                 rel_heads_list_t release_heads;
2051                 bool complete;
2052                 complete = release_seq_heads(rf, &release_heads, pending);
2053                 for (unsigned int i = 0; i < release_heads.size(); i++) {
2054                         if (!acquire->has_synchronized_with(release_heads[i])) {
2055                                 if (acquire->synchronize_with(release_heads[i]))
2056                                         updated = true;
2057                                 else
2058                                         set_bad_synchronization();
2059                         }
2060                 }
2061
2062                 if (updated) {
2063                         /* Re-check all pending release sequences */
2064                         work_queue->push_back(CheckRelSeqWorkEntry(NULL));
2065                         /* Re-check read-acquire for mo_graph edges */
2066                         if (acquire->is_read())
2067                                 work_queue->push_back(MOEdgeWorkEntry(acquire));
2068
2069                         /* propagate synchronization to later actions */
2070                         action_list_t::reverse_iterator rit = action_trace->rbegin();
2071                         for (; (*rit) != acquire; rit++) {
2072                                 ModelAction *propagate = *rit;
2073                                 if (acquire->happens_before(propagate)) {
2074                                         propagate->synchronize_with(acquire);
2075                                         /* Re-check 'propagate' for mo_graph edges */
2076                                         work_queue->push_back(MOEdgeWorkEntry(propagate));
2077                                 }
2078                         }
2079                 }
2080                 if (complete) {
2081                         it = pending_rel_seqs->erase(it);
2082                         snapshot_free(pending);
2083                 } else {
2084                         it++;
2085                 }
2086         }
2087
2088         // If we resolved promises or data races, see if we have realized a data race.
2089         checkDataRaces();
2090
2091         return updated;
2092 }
2093
2094 /**
2095  * Performs various bookkeeping operations for the current ModelAction. For
2096  * instance, adds action to the per-object, per-thread action vector and to the
2097  * action trace list of all thread actions.
2098  *
2099  * @param act is the ModelAction to add.
2100  */
2101 void ModelChecker::add_action_to_lists(ModelAction *act)
2102 {
2103         int tid = id_to_int(act->get_tid());
2104         action_trace->push_back(act);
2105
2106         get_safe_ptr_action(obj_map, act->get_location())->push_back(act);
2107
2108         std::vector<action_list_t> *vec = get_safe_ptr_vect_action(obj_thrd_map, act->get_location());
2109         if (tid >= (int)vec->size())
2110                 vec->resize(priv->next_thread_id);
2111         (*vec)[tid].push_back(act);
2112
2113         if ((int)thrd_last_action->size() <= tid)
2114                 thrd_last_action->resize(get_num_threads());
2115         (*thrd_last_action)[tid] = act;
2116
2117         if (act->is_fence() && act->is_release()) {
2118                 if ((int)thrd_last_fence_release->size() <= tid)
2119                         thrd_last_fence_release->resize(get_num_threads());
2120                 (*thrd_last_fence_release)[tid] = act;
2121         }
2122
2123         if (act->is_wait()) {
2124                 void *mutex_loc=(void *) act->get_value();
2125                 get_safe_ptr_action(obj_map, mutex_loc)->push_back(act);
2126
2127                 std::vector<action_list_t> *vec = get_safe_ptr_vect_action(obj_thrd_map, mutex_loc);
2128                 if (tid >= (int)vec->size())
2129                         vec->resize(priv->next_thread_id);
2130                 (*vec)[tid].push_back(act);
2131         }
2132 }
2133
2134 /**
2135  * @brief Get the last action performed by a particular Thread
2136  * @param tid The thread ID of the Thread in question
2137  * @return The last action in the thread
2138  */
2139 ModelAction * ModelChecker::get_last_action(thread_id_t tid) const
2140 {
2141         int threadid = id_to_int(tid);
2142         if (threadid < (int)thrd_last_action->size())
2143                 return (*thrd_last_action)[id_to_int(tid)];
2144         else
2145                 return NULL;
2146 }
2147
2148 /**
2149  * @brief Get the last fence release performed by a particular Thread
2150  * @param tid The thread ID of the Thread in question
2151  * @return The last fence release in the thread, if one exists; NULL otherwise
2152  */
2153 ModelAction * ModelChecker::get_last_fence_release(thread_id_t tid) const
2154 {
2155         int threadid = id_to_int(tid);
2156         if (threadid < (int)thrd_last_fence_release->size())
2157                 return (*thrd_last_fence_release)[id_to_int(tid)];
2158         else
2159                 return NULL;
2160 }
2161
2162 /**
2163  * Gets the last memory_order_seq_cst write (in the total global sequence)
2164  * performed on a particular object (i.e., memory location), not including the
2165  * current action.
2166  * @param curr The current ModelAction; also denotes the object location to
2167  * check
2168  * @return The last seq_cst write
2169  */
2170 ModelAction * ModelChecker::get_last_seq_cst_write(ModelAction *curr) const
2171 {
2172         void *location = curr->get_location();
2173         action_list_t *list = get_safe_ptr_action(obj_map, location);
2174         /* Find: max({i in dom(S) | seq_cst(t_i) && isWrite(t_i) && samevar(t_i, t)}) */
2175         action_list_t::reverse_iterator rit;
2176         for (rit = list->rbegin(); rit != list->rend(); rit++)
2177                 if ((*rit)->is_write() && (*rit)->is_seqcst() && (*rit) != curr)
2178                         return *rit;
2179         return NULL;
2180 }
2181
2182 /**
2183  * Gets the last memory_order_seq_cst fence (in the total global sequence)
2184  * performed in a particular thread, prior to a particular fence.
2185  * @param tid The ID of the thread to check
2186  * @param before_fence The fence from which to begin the search; if NULL, then
2187  * search for the most recent fence in the thread.
2188  * @return The last prior seq_cst fence in the thread, if exists; otherwise, NULL
2189  */
2190 ModelAction * ModelChecker::get_last_seq_cst_fence(thread_id_t tid, const ModelAction *before_fence) const
2191 {
2192         /* All fences should have NULL location */
2193         action_list_t *list = get_safe_ptr_action(obj_map, NULL);
2194         action_list_t::reverse_iterator rit = list->rbegin();
2195
2196         if (before_fence) {
2197                 for (; rit != list->rend(); rit++)
2198                         if (*rit == before_fence)
2199                                 break;
2200
2201                 ASSERT(*rit == before_fence);
2202                 rit++;
2203         }
2204
2205         for (; rit != list->rend(); rit++)
2206                 if ((*rit)->is_fence() && (tid == (*rit)->get_tid()) && (*rit)->is_seqcst())
2207                         return *rit;
2208         return NULL;
2209 }
2210
2211 /**
2212  * Gets the last unlock operation performed on a particular mutex (i.e., memory
2213  * location). This function identifies the mutex according to the current
2214  * action, which is presumed to perform on the same mutex.
2215  * @param curr The current ModelAction; also denotes the object location to
2216  * check
2217  * @return The last unlock operation
2218  */
2219 ModelAction * ModelChecker::get_last_unlock(ModelAction *curr) const
2220 {
2221         void *location = curr->get_location();
2222         action_list_t *list = get_safe_ptr_action(obj_map, location);
2223         /* Find: max({i in dom(S) | isUnlock(t_i) && samevar(t_i, t)}) */
2224         action_list_t::reverse_iterator rit;
2225         for (rit = list->rbegin(); rit != list->rend(); rit++)
2226                 if ((*rit)->is_unlock() || (*rit)->is_wait())
2227                         return *rit;
2228         return NULL;
2229 }
2230
2231 ModelAction * ModelChecker::get_parent_action(thread_id_t tid) const
2232 {
2233         ModelAction *parent = get_last_action(tid);
2234         if (!parent)
2235                 parent = get_thread(tid)->get_creation();
2236         return parent;
2237 }
2238
2239 /**
2240  * Returns the clock vector for a given thread.
2241  * @param tid The thread whose clock vector we want
2242  * @return Desired clock vector
2243  */
2244 ClockVector * ModelChecker::get_cv(thread_id_t tid) const
2245 {
2246         return get_parent_action(tid)->get_cv();
2247 }
2248
2249 /**
2250  * Resolve a set of Promises with a current write. The set is provided in the
2251  * Node corresponding to @a write.
2252  * @param write The ModelAction that is fulfilling Promises
2253  * @return True if promises were resolved; false otherwise
2254  */
2255 bool ModelChecker::resolve_promises(ModelAction *write)
2256 {
2257         bool resolved = false;
2258         std::vector< thread_id_t, ModelAlloc<thread_id_t> > threads_to_check;
2259
2260         for (unsigned int i = 0, promise_index = 0; promise_index < promises->size(); i++) {
2261                 Promise *promise = (*promises)[promise_index];
2262                 if (write->get_node()->get_promise(i)) {
2263                         ModelAction *read = promise->get_action();
2264                         if (read->is_rmw()) {
2265                                 mo_graph->addRMWEdge(write, read);
2266                         }
2267                         read_from(read, write);
2268                         //First fix up the modification order for actions that happened
2269                         //before the read
2270                         r_modification_order(read, write);
2271                         //Next fix up the modification order for actions that happened
2272                         //after the read.
2273                         post_r_modification_order(read, write);
2274                         //Make sure the promise's value matches the write's value
2275                         ASSERT(promise->get_value() == write->get_value());
2276                         delete(promise);
2277
2278                         promises->erase(promises->begin() + promise_index);
2279                         threads_to_check.push_back(read->get_tid());
2280
2281                         resolved = true;
2282                 } else
2283                         promise_index++;
2284         }
2285
2286         //Check whether reading these writes has made threads unable to
2287         //resolve promises
2288
2289         for(unsigned int i=0;i<threads_to_check.size();i++)
2290                 mo_check_promises(threads_to_check[i], write);
2291
2292         return resolved;
2293 }
2294
2295 /**
2296  * Compute the set of promises that could potentially be satisfied by this
2297  * action. Note that the set computation actually appears in the Node, not in
2298  * ModelChecker.
2299  * @param curr The ModelAction that may satisfy promises
2300  */
2301 void ModelChecker::compute_promises(ModelAction *curr)
2302 {
2303         for (unsigned int i = 0; i < promises->size(); i++) {
2304                 Promise *promise = (*promises)[i];
2305                 const ModelAction *act = promise->get_action();
2306                 if (!act->happens_before(curr) &&
2307                                 act->is_read() &&
2308                                 !act->could_synchronize_with(curr) &&
2309                                 !act->same_thread(curr) &&
2310                                 act->get_location() == curr->get_location() &&
2311                                 promise->get_value() == curr->get_value()) {
2312                         curr->get_node()->set_promise(i, act->is_rmw());
2313                 }
2314         }
2315 }
2316
2317 /** Checks promises in response to change in ClockVector Threads. */
2318 void ModelChecker::check_promises(thread_id_t tid, ClockVector *old_cv, ClockVector *merge_cv)
2319 {
2320         for (unsigned int i = 0; i < promises->size(); i++) {
2321                 Promise *promise = (*promises)[i];
2322                 const ModelAction *act = promise->get_action();
2323                 if ((old_cv == NULL || !old_cv->synchronized_since(act)) &&
2324                                 merge_cv->synchronized_since(act)) {
2325                         if (promise->increment_threads(tid)) {
2326                                 //Promise has failed
2327                                 priv->failed_promise = true;
2328                                 return;
2329                         }
2330                 }
2331         }
2332 }
2333
2334 void ModelChecker::check_promises_thread_disabled() {
2335         for (unsigned int i = 0; i < promises->size(); i++) {
2336                 Promise *promise = (*promises)[i];
2337                 if (promise->check_promise()) {
2338                         priv->failed_promise = true;
2339                         return;
2340                 }
2341         }
2342 }
2343
2344 /** Checks promises in response to addition to modification order for threads.
2345  * Definitions:
2346  * pthread is the thread that performed the read that created the promise
2347  *
2348  * pread is the read that created the promise
2349  *
2350  * pwrite is either the first write to same location as pread by
2351  * pthread that is sequenced after pread or the value read by the
2352  * first read to the same lcoation as pread by pthread that is
2353  * sequenced after pread..
2354  *
2355  *      1. If tid=pthread, then we check what other threads are reachable
2356  * through the mode order starting with pwrite.  Those threads cannot
2357  * perform a write that will resolve the promise due to modification
2358  * order constraints.
2359  *
2360  * 2. If the tid is not pthread, we check whether pwrite can reach the
2361  * action write through the modification order.  If so, that thread
2362  * cannot perform a future write that will resolve the promise due to
2363  * modificatin order constraints.
2364  *
2365  *      @parem tid The thread that either read from the model action
2366  *      write, or actually did the model action write.
2367  *
2368  *      @parem write The ModelAction representing the relevant write.
2369  */
2370
2371 void ModelChecker::mo_check_promises(thread_id_t tid, const ModelAction *write) {
2372         void * location = write->get_location();
2373         for (unsigned int i = 0; i < promises->size(); i++) {
2374                 Promise *promise = (*promises)[i];
2375                 const ModelAction *act = promise->get_action();
2376
2377                 //Is this promise on the same location?
2378                 if ( act->get_location() != location )
2379                         continue;
2380
2381                 //same thread as the promise
2382                 if ( act->get_tid()==tid ) {
2383
2384                         //do we have a pwrite for the promise, if not, set it
2385                         if (promise->get_write() == NULL ) {
2386                                 promise->set_write(write);
2387                                 //The pwrite cannot happen before the promise
2388                                 if (write->happens_before(act) && (write != act)) {
2389                                         priv->failed_promise = true;
2390                                         return;
2391                                 }
2392                         }
2393                         if (mo_graph->checkPromise(write, promise)) {
2394                                 priv->failed_promise = true;
2395                                 return;
2396                         }
2397                 }
2398
2399                 //Don't do any lookups twice for the same thread
2400                 if (promise->has_sync_thread(tid))
2401                         continue;
2402
2403                 if (promise->get_write()&&mo_graph->checkReachable(promise->get_write(), write)) {
2404                         if (promise->increment_threads(tid)) {
2405                                 priv->failed_promise = true;
2406                                 return;
2407                         }
2408                 }
2409         }
2410 }
2411
2412 /**
2413  * Compute the set of writes that may break the current pending release
2414  * sequence. This information is extracted from previou release sequence
2415  * calculations.
2416  *
2417  * @param curr The current ModelAction. Must be a release sequence fixup
2418  * action.
2419  */
2420 void ModelChecker::compute_relseq_breakwrites(ModelAction *curr)
2421 {
2422         if (pending_rel_seqs->empty())
2423                 return;
2424
2425         struct release_seq *pending = pending_rel_seqs->back();
2426         for (unsigned int i = 0; i < pending->writes.size(); i++) {
2427                 const ModelAction *write = pending->writes[i];
2428                 curr->get_node()->add_relseq_break(write);
2429         }
2430
2431         /* NULL means don't break the sequence; just synchronize */
2432         curr->get_node()->add_relseq_break(NULL);
2433 }
2434
2435 /**
2436  * Build up an initial set of all past writes that this 'read' action may read
2437  * from. This set is determined by the clock vector's "happens before"
2438  * relationship.
2439  * @param curr is the current ModelAction that we are exploring; it must be a
2440  * 'read' operation.
2441  */
2442 void ModelChecker::build_reads_from_past(ModelAction *curr)
2443 {
2444         std::vector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
2445         unsigned int i;
2446         ASSERT(curr->is_read());
2447
2448         ModelAction *last_sc_write = NULL;
2449
2450         /* Track whether this object has been initialized */
2451         bool initialized = false;
2452
2453         if (curr->is_seqcst()) {
2454                 last_sc_write = get_last_seq_cst_write(curr);
2455                 /* We have to at least see the last sequentially consistent write,
2456                          so we are initialized. */
2457                 if (last_sc_write != NULL)
2458                         initialized = true;
2459         }
2460
2461         /* Iterate over all threads */
2462         for (i = 0; i < thrd_lists->size(); i++) {
2463                 /* Iterate over actions in thread, starting from most recent */
2464                 action_list_t *list = &(*thrd_lists)[i];
2465                 action_list_t::reverse_iterator rit;
2466                 for (rit = list->rbegin(); rit != list->rend(); rit++) {
2467                         ModelAction *act = *rit;
2468
2469                         /* Only consider 'write' actions */
2470                         if (!act->is_write() || act == curr)
2471                                 continue;
2472
2473                         /* Don't consider more than one seq_cst write if we are a seq_cst read. */
2474                         bool allow_read = true;
2475
2476                         if (curr->is_seqcst() && (act->is_seqcst() || (last_sc_write != NULL && act->happens_before(last_sc_write))) && act != last_sc_write)
2477                                 allow_read = false;
2478                         else if (curr->get_sleep_flag() && !curr->is_seqcst() && !sleep_can_read_from(curr, act))
2479                                 allow_read = false;
2480
2481                         if (allow_read) {
2482                                 DEBUG("Adding action to may_read_from:\n");
2483                                 if (DBG_ENABLED()) {
2484                                         act->print();
2485                                         curr->print();
2486                                 }
2487                                 curr->get_node()->add_read_from(act);
2488                         }
2489
2490                         /* Include at most one act per-thread that "happens before" curr */
2491                         if (act->happens_before(curr)) {
2492                                 initialized = true;
2493                                 break;
2494                         }
2495                 }
2496         }
2497
2498         if (!initialized)
2499                 assert_bug("May read from uninitialized atomic");
2500
2501         if (DBG_ENABLED() || !initialized) {
2502                 model_print("Reached read action:\n");
2503                 curr->print();
2504                 model_print("Printing may_read_from\n");
2505                 curr->get_node()->print_may_read_from();
2506                 model_print("End printing may_read_from\n");
2507         }
2508 }
2509
2510 bool ModelChecker::sleep_can_read_from(ModelAction * curr, const ModelAction *write) {
2511         while(true) {
2512                 Node *prevnode=write->get_node()->get_parent();
2513
2514                 bool thread_sleep=prevnode->enabled_status(curr->get_tid())==THREAD_SLEEP_SET;
2515                 if (write->is_release()&&thread_sleep)
2516                         return true;
2517                 if (!write->is_rmw()) {
2518                         return false;
2519                 }
2520                 if (write->get_reads_from()==NULL)
2521                         return true;
2522                 write=write->get_reads_from();
2523         }
2524 }
2525
2526 static void print_list(action_list_t *list, int exec_num = -1)
2527 {
2528         action_list_t::iterator it;
2529
2530         model_print("---------------------------------------------------------------------\n");
2531         if (exec_num >= 0)
2532                 model_print("Execution %d:\n", exec_num);
2533
2534         unsigned int hash=0;
2535
2536         for (it = list->begin(); it != list->end(); it++) {
2537                 (*it)->print();
2538                 hash=hash^(hash<<3)^((*it)->hash());
2539         }
2540         model_print("HASH %u\n", hash);
2541         model_print("---------------------------------------------------------------------\n");
2542 }
2543
2544 #if SUPPORT_MOD_ORDER_DUMP
2545 void ModelChecker::dumpGraph(char *filename) {
2546         char buffer[200];
2547         sprintf(buffer, "%s.dot",filename);
2548         FILE *file=fopen(buffer, "w");
2549         fprintf(file, "digraph %s {\n",filename);
2550         mo_graph->dumpNodes(file);
2551         ModelAction ** thread_array=(ModelAction **)model_calloc(1, sizeof(ModelAction *)*get_num_threads());
2552
2553         for (action_list_t::iterator it = action_trace->begin(); it != action_trace->end(); it++) {
2554                 ModelAction *action=*it;
2555                 if (action->is_read()) {
2556                         fprintf(file, "N%u [label=\"%u, T%u\"];\n", action->get_seq_number(),action->get_seq_number(), action->get_tid());
2557                         if (action->get_reads_from()!=NULL)
2558                                 fprintf(file, "N%u -> N%u[label=\"rf\", color=red];\n", action->get_seq_number(), action->get_reads_from()->get_seq_number());
2559                 }
2560                 if (thread_array[action->get_tid()] != NULL) {
2561                         fprintf(file, "N%u -> N%u[label=\"sb\", color=blue];\n", thread_array[action->get_tid()]->get_seq_number(), action->get_seq_number());
2562                 }
2563
2564                 thread_array[action->get_tid()]=action;
2565         }
2566         fprintf(file,"}\n");
2567         model_free(thread_array);
2568         fclose(file);
2569 }
2570 #endif
2571
2572 /** @brief Prints an execution trace summary. */
2573 void ModelChecker::print_summary() const
2574 {
2575 #if SUPPORT_MOD_ORDER_DUMP
2576         scheduler->print();
2577         char buffername[100];
2578         sprintf(buffername, "exec%04u", stats.num_total);
2579         mo_graph->dumpGraphToFile(buffername);
2580         sprintf(buffername, "graph%04u", stats.num_total);
2581         dumpGraph(buffername);
2582 #endif
2583
2584         if (!isfeasibleprefix())
2585                 model_print("INFEASIBLE EXECUTION!\n");
2586         print_list(action_trace, stats.num_total);
2587         model_print("\n");
2588 }
2589
2590 /**
2591  * Add a Thread to the system for the first time. Should only be called once
2592  * per thread.
2593  * @param t The Thread to add
2594  */
2595 void ModelChecker::add_thread(Thread *t)
2596 {
2597         thread_map->put(id_to_int(t->get_id()), t);
2598         scheduler->add_thread(t);
2599 }
2600
2601 /**
2602  * Removes a thread from the scheduler.
2603  * @param the thread to remove.
2604  */
2605 void ModelChecker::remove_thread(Thread *t)
2606 {
2607         scheduler->remove_thread(t);
2608 }
2609
2610 /**
2611  * @brief Get a Thread reference by its ID
2612  * @param tid The Thread's ID
2613  * @return A Thread reference
2614  */
2615 Thread * ModelChecker::get_thread(thread_id_t tid) const
2616 {
2617         return thread_map->get(id_to_int(tid));
2618 }
2619
2620 /**
2621  * @brief Get a reference to the Thread in which a ModelAction was executed
2622  * @param act The ModelAction
2623  * @return A Thread reference
2624  */
2625 Thread * ModelChecker::get_thread(ModelAction *act) const
2626 {
2627         return get_thread(act->get_tid());
2628 }
2629
2630 /**
2631  * @brief Check if a Thread is currently enabled
2632  * @param t The Thread to check
2633  * @return True if the Thread is currently enabled
2634  */
2635 bool ModelChecker::is_enabled(Thread *t) const
2636 {
2637         return scheduler->is_enabled(t);
2638 }
2639
2640 /**
2641  * @brief Check if a Thread is currently enabled
2642  * @param tid The ID of the Thread to check
2643  * @return True if the Thread is currently enabled
2644  */
2645 bool ModelChecker::is_enabled(thread_id_t tid) const
2646 {
2647         return scheduler->is_enabled(tid);
2648 }
2649
2650 /**
2651  * Switch from a user-context to the "master thread" context (a.k.a. system
2652  * context). This switch is made with the intention of exploring a particular
2653  * model-checking action (described by a ModelAction object). Must be called
2654  * from a user-thread context.
2655  *
2656  * @param act The current action that will be explored. May be NULL only if
2657  * trace is exiting via an assertion (see ModelChecker::set_assert and
2658  * ModelChecker::has_asserted).
2659  * @return Return status from the 'swap' call (i.e., success/fail, 0/-1)
2660  */
2661 int ModelChecker::switch_to_master(ModelAction *act)
2662 {
2663         DBG();
2664         Thread *old = thread_current();
2665         set_current_action(act);
2666         old->set_state(THREAD_READY);
2667         return Thread::swap(old, &system_context);
2668 }
2669
2670 /**
2671  * Takes the next step in the execution, if possible.
2672  * @return Returns true (success) if a step was taken and false otherwise.
2673  */
2674 bool ModelChecker::take_step() {
2675         if (has_asserted())
2676                 return false;
2677
2678         Thread *curr = priv->current_action ? get_thread(priv->current_action) : NULL;
2679         if (curr) {
2680                 if (curr->get_state() == THREAD_READY) {
2681                         ASSERT(priv->current_action);
2682
2683                         priv->nextThread = check_current_action(priv->current_action);
2684                         priv->current_action = NULL;
2685
2686                         if (curr->is_blocked() || curr->is_complete())
2687                                 scheduler->remove_thread(curr);
2688                 } else {
2689                         ASSERT(false);
2690                 }
2691         }
2692         Thread *next = scheduler->next_thread(priv->nextThread);
2693
2694         /* Infeasible -> don't take any more steps */
2695         if (is_infeasible())
2696                 return false;
2697         else if (isfeasibleprefix() && have_bug_reports()) {
2698                 set_assert();
2699                 return false;
2700         }
2701
2702         if (params.bound != 0) {
2703                 if (priv->used_sequence_numbers > params.bound) {
2704                         return false;
2705                 }
2706         }
2707
2708         DEBUG("(%d, %d)\n", curr ? id_to_int(curr->get_id()) : -1,
2709                         next ? id_to_int(next->get_id()) : -1);
2710
2711         /*
2712          * Launch end-of-execution release sequence fixups only when there are:
2713          *
2714          * (1) no more user threads to run (or when execution replay chooses
2715          *     the 'model_thread')
2716          * (2) pending release sequences
2717          * (3) pending assertions (i.e., data races)
2718          * (4) no pending promises
2719          */
2720         if (!pending_rel_seqs->empty() && (!next || next->is_model_thread()) &&
2721                         is_feasible_prefix_ignore_relseq() && !unrealizedraces.empty()) {
2722                 model_print("*** WARNING: release sequence fixup action (%zu pending release seuqences) ***\n",
2723                                 pending_rel_seqs->size());
2724                 ModelAction *fixup = new ModelAction(MODEL_FIXUP_RELSEQ,
2725                                 std::memory_order_seq_cst, NULL, VALUE_NONE,
2726                                 model_thread);
2727                 set_current_action(fixup);
2728                 return true;
2729         }
2730
2731         /* next == NULL -> don't take any more steps */
2732         if (!next)
2733                 return false;
2734
2735         next->set_state(THREAD_RUNNING);
2736
2737         if (next->get_pending() != NULL) {
2738                 /* restart a pending action */
2739                 set_current_action(next->get_pending());
2740                 next->set_pending(NULL);
2741                 next->set_state(THREAD_READY);
2742                 return true;
2743         }
2744
2745         /* Return false only if swap fails with an error */
2746         return (Thread::swap(&system_context, next) == 0);
2747 }
2748
2749 /** Wrapper to run the user's main function, with appropriate arguments */
2750 void user_main_wrapper(void *)
2751 {
2752         user_main(model->params.argc, model->params.argv);
2753 }
2754
2755 /** @brief Run ModelChecker for the user program */
2756 void ModelChecker::run()
2757 {
2758         do {
2759                 thrd_t user_thread;
2760
2761                 /* Start user program */
2762                 add_thread(new Thread(&user_thread, &user_main_wrapper, NULL));
2763
2764                 /* Wait for all threads to complete */
2765                 while (take_step());
2766         } while (next_execution());
2767
2768         print_stats();
2769 }