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