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