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