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