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