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