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