clean out includes, etc.
[cdsspec-compiler.git] / nodestack.cc
1 #define __STDC_FORMAT_MACROS
2 #include <inttypes.h>
3
4 #include <string.h>
5
6 #include "nodestack.h"
7 #include "action.h"
8 #include "common.h"
9 #include "model.h"
10 #include "threads-model.h"
11 #include "modeltypes.h"
12
13 /**
14  * @brief Node constructor
15  *
16  * Constructs a single Node for use in a NodeStack. Each Node is associated
17  * with exactly one ModelAction (exception: the first Node should be created
18  * as an empty stub, to represent the first thread "choice") and up to one
19  * parent.
20  *
21  * @param act The ModelAction to associate with this Node. May be NULL.
22  * @param par The parent Node in the NodeStack. May be NULL if there is no
23  * parent.
24  * @param nthreads The number of threads which exist at this point in the
25  * execution trace.
26  */
27 Node::Node(ModelAction *act, Node *par, int nthreads, Node *prevfairness) :
28         read_from_status(READ_FROM_PAST),
29         action(act),
30         uninit_action(NULL),
31         parent(par),
32         num_threads(nthreads),
33         explored_children(num_threads),
34         backtrack(num_threads),
35         fairness(num_threads),
36         numBacktracks(0),
37         enabled_array(NULL),
38         read_from_past(),
39         read_from_past_idx(0),
40         read_from_promises(),
41         read_from_promise_idx(-1),
42         future_values(),
43         future_index(-1),
44         resolve_promise(),
45         resolve_promise_idx(-1),
46         relseq_break_writes(),
47         relseq_break_index(0),
48         misc_index(0),
49         misc_max(0),
50         yield_data(NULL)
51 {
52         ASSERT(act);
53         act->set_node(this);
54         int currtid = id_to_int(act->get_tid());
55         int prevtid = prevfairness ? id_to_int(prevfairness->action->get_tid()) : 0;
56
57         if (model->params.fairwindow != 0) {
58                 for (int i = 0; i < num_threads; i++) {
59                         ASSERT(i < ((int)fairness.size()));
60                         struct fairness_info *fi = &fairness[i];
61                         struct fairness_info *prevfi = (parent && i < parent->get_num_threads()) ? &parent->fairness[i] : NULL;
62                         if (prevfi) {
63                                 *fi = *prevfi;
64                         }
65                         if (parent && parent->is_enabled(int_to_id(i))) {
66                                 fi->enabled_count++;
67                         }
68                         if (i == currtid) {
69                                 fi->turns++;
70                                 fi->priority = false;
71                         }
72                         /* Do window processing */
73                         if (prevfairness != NULL) {
74                                 if (prevfairness->parent->is_enabled(int_to_id(i)))
75                                         fi->enabled_count--;
76                                 if (i == prevtid) {
77                                         fi->turns--;
78                                 }
79                                 /* Need full window to start evaluating
80                                  * conditions
81                                  * If we meet the enabled count and have no
82                                  * turns, give us priority */
83                                 if ((fi->enabled_count >= model->params.enabledcount) &&
84                                                 (fi->turns == 0))
85                                         fi->priority = true;
86                         }
87                 }
88         }
89 }
90
91 int Node::get_yield_data(int tid1, int tid2) const {
92         if (tid1<num_threads && tid2 < num_threads)
93                 return yield_data[YIELD_INDEX(tid1,tid2,num_threads)];
94         else
95                 return YIELD_S | YIELD_D;
96 }
97
98 void Node::update_yield(Scheduler * scheduler) {
99         if (yield_data==NULL)
100                 yield_data=(int *) model_calloc(1, sizeof(int)*num_threads*num_threads);
101         //handle base case
102         if (parent == NULL) {
103                 for(int i = 0; i < num_threads*num_threads; i++) {
104                         yield_data[i] = YIELD_S | YIELD_D;
105                 }
106                 return;
107         }
108         int curr_tid=id_to_int(action->get_tid());
109
110         for(int u = 0; u < num_threads; u++) {
111                 for(int v = 0; v < num_threads; v++) {
112                         int yield_state=parent->get_yield_data(u, v);
113                         bool next_enabled=scheduler->is_enabled(int_to_id(v));
114                         bool curr_enabled=parent->is_enabled(int_to_id(v));
115                         if (!next_enabled) {
116                                 //Compute intersection of ES and E
117                                 yield_state&=~YIELD_E;
118                                 //Check to see if we disabled the thread
119                                 if (u==curr_tid && curr_enabled)
120                                         yield_state|=YIELD_D;
121                         }
122                         yield_data[YIELD_INDEX(u, v, num_threads)]=yield_state;
123                 }
124                 yield_data[YIELD_INDEX(u, curr_tid, num_threads)]=(yield_data[YIELD_INDEX(u, curr_tid, num_threads)]&~YIELD_P)|YIELD_S;
125         }
126         //handle curr.yield(t) part of computation
127         if (action->is_yield()) {
128                 for(int v = 0; v < num_threads; v++) {
129                         int yield_state=yield_data[YIELD_INDEX(curr_tid, v, num_threads)];
130                         if ((yield_state & (YIELD_E | YIELD_D)) && (!(yield_state & YIELD_S)))
131                                 yield_state |= YIELD_P;
132                         yield_state &= YIELD_P;
133                         if (scheduler->is_enabled(int_to_id(v))) {
134                                 yield_state|=YIELD_E;
135                         }
136                         yield_data[YIELD_INDEX(curr_tid, v, num_threads)]=yield_state;
137                 }
138         }
139 }
140
141 /** @brief Node desctructor */
142 Node::~Node()
143 {
144         delete action;
145         if (uninit_action)
146                 delete uninit_action;
147         if (enabled_array)
148                 model_free(enabled_array);
149         if (yield_data)
150                 model_free(yield_data);
151 }
152
153 /** Prints debugging info for the ModelAction associated with this Node */
154 void Node::print() const
155 {
156         action->print();
157         model_print("          thread status: ");
158         if (enabled_array) {
159                 for (int i = 0; i < num_threads; i++) {
160                         char str[20];
161                         enabled_type_to_string(enabled_array[i], str);
162                         model_print("[%d: %s]", i, str);
163                 }
164                 model_print("\n");
165         } else
166                 model_print("(info not available)\n");
167         model_print("          backtrack: %s", backtrack_empty() ? "empty" : "non-empty ");
168         for (int i = 0; i < (int)backtrack.size(); i++)
169                 if (backtrack[i] == true)
170                         model_print("[%d]", i);
171         model_print("\n");
172
173         model_print("          read from past: %s", read_from_past_empty() ? "empty" : "non-empty ");
174         for (int i = read_from_past_idx + 1; i < (int)read_from_past.size(); i++)
175                 model_print("[%d]", read_from_past[i]->get_seq_number());
176         model_print("\n");
177
178         model_print("          read-from promises: %s", read_from_promise_empty() ? "empty" : "non-empty ");
179         for (int i = read_from_promise_idx + 1; i < (int)read_from_promises.size(); i++)
180                 model_print("[%d]", read_from_promises[i]->get_seq_number());
181         model_print("\n");
182
183         model_print("          future values: %s", future_value_empty() ? "empty" : "non-empty ");
184         for (int i = future_index + 1; i < (int)future_values.size(); i++)
185                 model_print("[%#" PRIx64 "]", future_values[i].value);
186         model_print("\n");
187
188         model_print("          promises: %s\n", promise_empty() ? "empty" : "non-empty");
189         model_print("          misc: %s\n", misc_empty() ? "empty" : "non-empty");
190         model_print("          rel seq break: %s\n", relseq_break_empty() ? "empty" : "non-empty");
191 }
192
193 /****************************** threads backtracking **************************/
194
195 /**
196  * Checks if the Thread associated with this thread ID has been explored from
197  * this Node already.
198  * @param tid is the thread ID to check
199  * @return true if this thread choice has been explored already, false
200  * otherwise
201  */
202 bool Node::has_been_explored(thread_id_t tid) const
203 {
204         int id = id_to_int(tid);
205         return explored_children[id];
206 }
207
208 /**
209  * Checks if the backtracking set is empty.
210  * @return true if the backtracking set is empty
211  */
212 bool Node::backtrack_empty() const
213 {
214         return (numBacktracks == 0);
215 }
216
217 void Node::explore(thread_id_t tid)
218 {
219         int i = id_to_int(tid);
220         ASSERT(i < ((int)backtrack.size()));
221         if (backtrack[i]) {
222                 backtrack[i] = false;
223                 numBacktracks--;
224         }
225         explored_children[i] = true;
226 }
227
228 /**
229  * Mark the appropriate backtracking information for exploring a thread choice.
230  * @param act The ModelAction to explore
231  */
232 void Node::explore_child(ModelAction *act, enabled_type_t *is_enabled)
233 {
234         if (!enabled_array)
235                 enabled_array = (enabled_type_t *)model_malloc(sizeof(enabled_type_t) * num_threads);
236         if (is_enabled != NULL)
237                 memcpy(enabled_array, is_enabled, sizeof(enabled_type_t) * num_threads);
238         else {
239                 for (int i = 0; i < num_threads; i++)
240                         enabled_array[i] = THREAD_DISABLED;
241         }
242
243         explore(act->get_tid());
244 }
245
246 /**
247  * Records a backtracking reference for a thread choice within this Node.
248  * Provides feedback as to whether this thread choice is already set for
249  * backtracking.
250  * @return false if the thread was already set to be backtracked, true
251  * otherwise
252  */
253 bool Node::set_backtrack(thread_id_t id)
254 {
255         int i = id_to_int(id);
256         ASSERT(i < ((int)backtrack.size()));
257         if (backtrack[i])
258                 return false;
259         backtrack[i] = true;
260         numBacktracks++;
261         return true;
262 }
263
264 thread_id_t Node::get_next_backtrack()
265 {
266         /** @todo Find next backtrack */
267         unsigned int i;
268         for (i = 0; i < backtrack.size(); i++)
269                 if (backtrack[i] == true)
270                         break;
271         /* Backtrack set was empty? */
272         ASSERT(i != backtrack.size());
273
274         backtrack[i] = false;
275         numBacktracks--;
276         return int_to_id(i);
277 }
278
279 void Node::clear_backtracking()
280 {
281         for (unsigned int i = 0; i < backtrack.size(); i++)
282                 backtrack[i] = false;
283         for (unsigned int i = 0; i < explored_children.size(); i++)
284                 explored_children[i] = false;
285         numBacktracks = 0;
286 }
287
288 /************************** end threads backtracking **************************/
289
290 /*********************************** promise **********************************/
291
292 /**
293  * Sets a promise to explore meeting with the given node.
294  * @param i is the promise index.
295  */
296 void Node::set_promise(unsigned int i)
297 {
298         if (i >= resolve_promise.size())
299                 resolve_promise.resize(i + 1, false);
300         resolve_promise[i] = true;
301 }
302
303 /**
304  * Looks up whether a given promise should be satisfied by this node.
305  * @param i The promise index.
306  * @return true if the promise should be satisfied by the given ModelAction.
307  */
308 bool Node::get_promise(unsigned int i) const
309 {
310         return (i < resolve_promise.size()) && (int)i == resolve_promise_idx;
311 }
312
313 /**
314  * Increments to the next promise to resolve.
315  * @return true if we have a valid combination.
316  */
317 bool Node::increment_promise()
318 {
319         DBG();
320         if (resolve_promise.empty())
321                 return false;
322         int prev_idx = resolve_promise_idx;
323         resolve_promise_idx++;
324         for ( ; resolve_promise_idx < (int)resolve_promise.size(); resolve_promise_idx++)
325                 if (resolve_promise[resolve_promise_idx])
326                         return true;
327         resolve_promise_idx = prev_idx;
328         return false;
329 }
330
331 /**
332  * Returns whether the promise set is empty.
333  * @return true if we have explored all promise combinations.
334  */
335 bool Node::promise_empty() const
336 {
337         for (int i = resolve_promise_idx + 1; i < (int)resolve_promise.size(); i++)
338                 if (i >= 0 && resolve_promise[i])
339                         return false;
340         return true;
341 }
342
343 /** @brief Clear any promise-resolution information for this Node */
344 void Node::clear_promise_resolutions()
345 {
346         resolve_promise.clear();
347         resolve_promise_idx = -1;
348 }
349
350 /******************************* end promise **********************************/
351
352 void Node::set_misc_max(int i)
353 {
354         misc_max = i;
355 }
356
357 int Node::get_misc() const
358 {
359         return misc_index;
360 }
361
362 bool Node::increment_misc()
363 {
364         return (misc_index < misc_max) && ((++misc_index) < misc_max);
365 }
366
367 bool Node::misc_empty() const
368 {
369         return (misc_index + 1) >= misc_max;
370 }
371
372 bool Node::is_enabled(Thread *t) const
373 {
374         int thread_id = id_to_int(t->get_id());
375         return thread_id < num_threads && (enabled_array[thread_id] != THREAD_DISABLED);
376 }
377
378 enabled_type_t Node::enabled_status(thread_id_t tid) const
379 {
380         int thread_id = id_to_int(tid);
381         if (thread_id < num_threads)
382                 return enabled_array[thread_id];
383         else
384                 return THREAD_DISABLED;
385 }
386
387 bool Node::is_enabled(thread_id_t tid) const
388 {
389         int thread_id = id_to_int(tid);
390         return thread_id < num_threads && (enabled_array[thread_id] != THREAD_DISABLED);
391 }
392
393 bool Node::has_priority(thread_id_t tid) const
394 {
395         return fairness[id_to_int(tid)].priority;
396 }
397
398 bool Node::has_priority_over(thread_id_t tid1, thread_id_t tid2) const
399 {
400         return get_yield_data(id_to_int(tid1), id_to_int(tid2)) & YIELD_P;
401 }
402
403 /*********************************** read from ********************************/
404
405 /**
406  * Get the current state of the may-read-from set iteration
407  * @return The read-from type we should currently be checking (past or future)
408  */
409 read_from_type_t Node::get_read_from_status()
410 {
411         if (read_from_status == READ_FROM_PAST && read_from_past.empty())
412                 increment_read_from();
413         return read_from_status;
414 }
415
416 /**
417  * Iterate one step in the may-read-from iteration. This includes a step in
418  * reading from the either the past or the future.
419  * @return True if there is a new read-from to explore; false otherwise
420  */
421 bool Node::increment_read_from()
422 {
423         clear_promise_resolutions();
424         if (increment_read_from_past()) {
425                read_from_status = READ_FROM_PAST;
426                return true;
427         } else if (increment_read_from_promise()) {
428                 read_from_status = READ_FROM_PROMISE;
429                 return true;
430         } else if (increment_future_value()) {
431                 read_from_status = READ_FROM_FUTURE;
432                 return true;
433         }
434         read_from_status = READ_FROM_NONE;
435         return false;
436 }
437
438 /**
439  * @return True if there are any new read-froms to explore
440  */
441 bool Node::read_from_empty() const
442 {
443         return read_from_past_empty() &&
444                 read_from_promise_empty() &&
445                 future_value_empty();
446 }
447
448 /**
449  * Get the total size of the may-read-from set, including both past and future
450  * values
451  * @return The size of may-read-from
452  */
453 unsigned int Node::read_from_size() const
454 {
455         return read_from_past.size() +
456                 read_from_promises.size() +
457                 future_values.size();
458 }
459
460 /******************************* end read from ********************************/
461
462 /****************************** read from past ********************************/
463
464 /** @brief Prints info about read_from_past set */
465 void Node::print_read_from_past()
466 {
467         for (unsigned int i = 0; i < read_from_past.size(); i++)
468                 read_from_past[i]->print();
469 }
470
471 /**
472  * Add an action to the read_from_past set.
473  * @param act is the action to add
474  */
475 void Node::add_read_from_past(const ModelAction *act)
476 {
477         read_from_past.push_back(act);
478 }
479
480 /**
481  * Gets the next 'read_from_past' action from this Node. Only valid for a node
482  * where this->action is a 'read'.
483  * @return The first element in read_from_past
484  */
485 const ModelAction * Node::get_read_from_past() const
486 {
487         if (read_from_past_idx < read_from_past.size())
488                 return read_from_past[read_from_past_idx];
489         else
490                 return NULL;
491 }
492
493 const ModelAction * Node::get_read_from_past(int i) const
494 {
495         return read_from_past[i];
496 }
497
498 int Node::get_read_from_past_size() const
499 {
500         return read_from_past.size();
501 }
502
503 /**
504  * Checks whether the readsfrom set for this node is empty.
505  * @return true if the readsfrom set is empty.
506  */
507 bool Node::read_from_past_empty() const
508 {
509         return ((read_from_past_idx + 1) >= read_from_past.size());
510 }
511
512 /**
513  * Increments the index into the readsfrom set to explore the next item.
514  * @return Returns false if we have explored all items.
515  */
516 bool Node::increment_read_from_past()
517 {
518         DBG();
519         if (read_from_past_idx < read_from_past.size()) {
520                 read_from_past_idx++;
521                 return read_from_past_idx < read_from_past.size();
522         }
523         return false;
524 }
525
526 /************************** end read from past ********************************/
527
528 /***************************** read_from_promises *****************************/
529
530 /**
531  * Add an action to the read_from_promises set.
532  * @param reader The read which generated the Promise; we use the ModelAction
533  * instead of the Promise because the Promise does not last across executions
534  */
535 void Node::add_read_from_promise(const ModelAction *reader)
536 {
537         read_from_promises.push_back(reader);
538 }
539
540 /**
541  * Gets the next 'read-from-promise' from this Node. Only valid for a node
542  * where this->action is a 'read'.
543  * @return The current element in read_from_promises
544  */
545 Promise * Node::get_read_from_promise() const
546 {
547         ASSERT(read_from_promise_idx >= 0 && read_from_promise_idx < ((int)read_from_promises.size()));
548         return read_from_promises[read_from_promise_idx]->get_reads_from_promise();
549 }
550
551 /**
552  * Gets a particular 'read-from-promise' form this Node. Only vlaid for a node
553  * where this->action is a 'read'.
554  * @param i The index of the Promise to get
555  * @return The Promise at index i, if the Promise is still available; NULL
556  * otherwise
557  */
558 Promise * Node::get_read_from_promise(int i) const
559 {
560         return read_from_promises[i]->get_reads_from_promise();
561 }
562
563 /** @return The size of the read-from-promise set */
564 int Node::get_read_from_promise_size() const
565 {
566         return read_from_promises.size();
567 }
568
569 /**
570  * Checks whether the read_from_promises set for this node is empty.
571  * @return true if the read_from_promises set is empty.
572  */
573 bool Node::read_from_promise_empty() const
574 {
575         return ((read_from_promise_idx + 1) >= ((int)read_from_promises.size()));
576 }
577
578 /**
579  * Increments the index into the read_from_promises set to explore the next item.
580  * @return Returns false if we have explored all promises.
581  */
582 bool Node::increment_read_from_promise()
583 {
584         DBG();
585         if (read_from_promise_idx < ((int)read_from_promises.size())) {
586                 read_from_promise_idx++;
587                 return (read_from_promise_idx < ((int)read_from_promises.size()));
588         }
589         return false;
590 }
591
592 /************************* end read_from_promises *****************************/
593
594 /****************************** future values *********************************/
595
596 /**
597  * Adds a value from a weakly ordered future write to backtrack to. This
598  * operation may "fail" if the future value has already been run (within some
599  * sloppiness window of this expiration), or if the futurevalues set has
600  * reached its maximum.
601  * @see model_params.maxfuturevalues
602  *
603  * @param value is the value to backtrack to.
604  * @return True if the future value was successully added; false otherwise
605  */
606 bool Node::add_future_value(struct future_value fv)
607 {
608         uint64_t value = fv.value;
609         modelclock_t expiration = fv.expiration;
610         thread_id_t tid = fv.tid;
611         int idx = -1; /* Highest index where value is found */
612         for (unsigned int i = 0; i < future_values.size(); i++) {
613                 if (future_values[i].value == value && future_values[i].tid == tid) {
614                         if (expiration <= future_values[i].expiration)
615                                 return false;
616                         idx = i;
617                 }
618         }
619         if (idx > future_index) {
620                 /* Future value hasn't been explored; update expiration */
621                 future_values[idx].expiration = expiration;
622                 return true;
623         } else if (idx >= 0 && expiration <= future_values[idx].expiration + model->params.expireslop) {
624                 /* Future value has been explored and is within the "sloppy" window */
625                 return false;
626         }
627
628         /* Limit the size of the future-values set */
629         if (model->params.maxfuturevalues > 0 &&
630                         (int)future_values.size() >= model->params.maxfuturevalues)
631                 return false;
632
633         future_values.push_back(fv);
634         return true;
635 }
636
637 /**
638  * Gets the next 'future_value' from this Node. Only valid for a node where
639  * this->action is a 'read'.
640  * @return The first element in future_values
641  */
642 struct future_value Node::get_future_value() const
643 {
644         ASSERT(future_index >= 0 && future_index < ((int)future_values.size()));
645         return future_values[future_index];
646 }
647
648 /**
649  * Checks whether the future_values set for this node is empty.
650  * @return true if the future_values set is empty.
651  */
652 bool Node::future_value_empty() const
653 {
654         return ((future_index + 1) >= ((int)future_values.size()));
655 }
656
657 /**
658  * Increments the index into the future_values set to explore the next item.
659  * @return Returns false if we have explored all values.
660  */
661 bool Node::increment_future_value()
662 {
663         DBG();
664         if (future_index < ((int)future_values.size())) {
665                 future_index++;
666                 return (future_index < ((int)future_values.size()));
667         }
668         return false;
669 }
670
671 /************************** end future values *********************************/
672
673 /*********************** breaking release sequences ***************************/
674
675 /**
676  * Add a write ModelAction to the set of writes that may break the release
677  * sequence. This is used during replay exploration of pending release
678  * sequences. This Node must correspond to a release sequence fixup action.
679  *
680  * @param write The write that may break the release sequence. NULL means we
681  * allow the release sequence to synchronize.
682  */
683 void Node::add_relseq_break(const ModelAction *write)
684 {
685         relseq_break_writes.push_back(write);
686 }
687
688 /**
689  * Get the write that may break the current pending release sequence,
690  * according to the replay / divergence pattern.
691  *
692  * @return A write that may break the release sequence. If NULL, that means
693  * the release sequence should not be broken.
694  */
695 const ModelAction * Node::get_relseq_break() const
696 {
697         if (relseq_break_index < (int)relseq_break_writes.size())
698                 return relseq_break_writes[relseq_break_index];
699         else
700                 return NULL;
701 }
702
703 /**
704  * Increments the index into the relseq_break_writes set to explore the next
705  * item.
706  * @return Returns false if we have explored all values.
707  */
708 bool Node::increment_relseq_break()
709 {
710         DBG();
711         if (relseq_break_index < ((int)relseq_break_writes.size())) {
712                 relseq_break_index++;
713                 return (relseq_break_index < ((int)relseq_break_writes.size()));
714         }
715         return false;
716 }
717
718 /**
719  * @return True if all writes that may break the release sequence have been
720  * explored
721  */
722 bool Node::relseq_break_empty() const
723 {
724         return ((relseq_break_index + 1) >= ((int)relseq_break_writes.size()));
725 }
726
727 /******************* end breaking release sequences ***************************/
728
729 /**
730  * Increments some behavior's index, if a new behavior is available
731  * @return True if there is a new behavior available; otherwise false
732  */
733 bool Node::increment_behaviors()
734 {
735         /* satisfy a different misc_index values */
736         if (increment_misc())
737                 return true;
738         /* satisfy a different set of promises */
739         if (increment_promise())
740                 return true;
741         /* read from a different value */
742         if (increment_read_from())
743                 return true;
744         /* resolve a release sequence differently */
745         if (increment_relseq_break())
746                 return true;
747         return false;
748 }
749
750 NodeStack::NodeStack() :
751         node_list(),
752         head_idx(-1),
753         total_nodes(0)
754 {
755         total_nodes++;
756 }
757
758 NodeStack::~NodeStack()
759 {
760         for (unsigned int i = 0; i < node_list.size(); i++)
761                 delete node_list[i];
762 }
763
764 void NodeStack::print() const
765 {
766         model_print("............................................\n");
767         model_print("NodeStack printing node_list:\n");
768         for (unsigned int it = 0; it < node_list.size(); it++) {
769                 if ((int)it == this->head_idx)
770                         model_print("vvv following action is the current iterator vvv\n");
771                 node_list[it]->print();
772         }
773         model_print("............................................\n");
774 }
775
776 /** Note: The is_enabled set contains what actions were enabled when
777  *  act was chosen. */
778 ModelAction * NodeStack::explore_action(ModelAction *act, enabled_type_t *is_enabled)
779 {
780         DBG();
781
782         if ((head_idx + 1) < (int)node_list.size()) {
783                 head_idx++;
784                 return node_list[head_idx]->get_action();
785         }
786
787         /* Record action */
788         Node *head = get_head();
789         Node *prevfairness = NULL;
790         if (head) {
791                 head->explore_child(act, is_enabled);
792                 if (model->params.fairwindow != 0 && head_idx > (int)model->params.fairwindow)
793                         prevfairness = node_list[head_idx - model->params.fairwindow];
794         }
795
796         int next_threads = model->get_num_threads();
797         if (act->get_type() == THREAD_CREATE)
798                 next_threads++;
799         node_list.push_back(new Node(act, head, next_threads, prevfairness));
800         total_nodes++;
801         head_idx++;
802         return NULL;
803 }
804
805 /**
806  * Empties the stack of all trailing nodes after a given position and calls the
807  * destructor for each. This function is provided an offset which determines
808  * how many nodes (relative to the current replay state) to save before popping
809  * the stack.
810  * @param numAhead gives the number of Nodes (including this Node) to skip over
811  * before removing nodes.
812  */
813 void NodeStack::pop_restofstack(int numAhead)
814 {
815         /* Diverging from previous execution; clear out remainder of list */
816         unsigned int it = head_idx + numAhead;
817         for (unsigned int i = it; i < node_list.size(); i++)
818                 delete node_list[i];
819         node_list.resize(it);
820         node_list.back()->clear_backtracking();
821 }
822
823 Node * NodeStack::get_head() const
824 {
825         if (node_list.empty() || head_idx < 0)
826                 return NULL;
827         return node_list[head_idx];
828 }
829
830 Node * NodeStack::get_next() const
831 {
832         if (node_list.empty()) {
833                 DEBUG("Empty\n");
834                 return NULL;
835         }
836         unsigned int it = head_idx + 1;
837         if (it == node_list.size()) {
838                 DEBUG("At end\n");
839                 return NULL;
840         }
841         return node_list[it];
842 }
843
844 void NodeStack::reset_execution()
845 {
846         head_idx = -1;
847 }