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