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