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