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