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