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