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