+bool Node::increment_read_from_past()
+{
+ DBG();
+ if (read_from_past_idx < read_from_past.size()) {
+ read_from_past_idx++;
+ return read_from_past_idx < read_from_past.size();
+ }
+ return false;
+}
+
+/************************** end read from past ********************************/
+
+/***************************** read_from_promises *****************************/
+
+/**
+ * Add an action to the read_from_promises set.
+ * @param reader The read which generated the Promise; we use the ModelAction
+ * instead of the Promise because the Promise does not last across executions
+ */
+void Node::add_read_from_promise(const ModelAction *reader)
+{
+ read_from_promises.push_back(reader);
+}
+
+/**
+ * Gets the next 'read-from-promise' from this Node. Only valid for a node
+ * where this->action is a 'read'.
+ * @return The current element in read_from_promises
+ */
+Promise * Node::get_read_from_promise() const
+{
+ ASSERT(read_from_promise_idx >= 0 && read_from_promise_idx < ((int)read_from_promises.size()));
+ return read_from_promises[read_from_promise_idx]->get_reads_from_promise();
+}
+
+/**
+ * Gets a particular 'read-from-promise' form this Node. Only vlaid for a node
+ * where this->action is a 'read'.
+ * @param i The index of the Promise to get
+ * @return The Promise at index i, if the Promise is still available; NULL
+ * otherwise
+ */
+Promise * Node::get_read_from_promise(int i) const
+{
+ return read_from_promises[i]->get_reads_from_promise();
+}
+
+/** @return The size of the read-from-promise set */
+int Node::get_read_from_promise_size() const
+{
+ return read_from_promises.size();
+}
+
+/**
+ * Checks whether the read_from_promises set for this node is empty.
+ * @return true if the read_from_promises set is empty.
+ */
+bool Node::read_from_promise_empty() const
+{
+ return ((read_from_promise_idx + 1) >= ((int)read_from_promises.size()));
+}
+
+/**
+ * Increments the index into the read_from_promises set to explore the next item.
+ * @return Returns false if we have explored all promises.
+ */
+bool Node::increment_read_from_promise()
+{
+ DBG();
+ if (read_from_promise_idx < ((int)read_from_promises.size())) {
+ read_from_promise_idx++;
+ return (read_from_promise_idx < ((int)read_from_promises.size()));
+ }
+ return false;
+}
+
+/************************* end read_from_promises *****************************/
+
+/****************************** future values *********************************/
+
+/**
+ * Adds a value from a weakly ordered future write to backtrack to. This
+ * operation may "fail" if the future value has already been run (within some
+ * sloppiness window of this expiration), or if the futurevalues set has
+ * reached its maximum.
+ * @see model_params.maxfuturevalues
+ *
+ * @param value is the value to backtrack to.
+ * @return True if the future value was successully added; false otherwise
+ */
+bool Node::add_future_value(struct future_value fv)
+{
+ uint64_t value = fv.value;
+ modelclock_t expiration = fv.expiration;
+ thread_id_t tid = fv.tid;
+ int idx = -1; /* Highest index where value is found */
+ for (unsigned int i = 0; i < future_values.size(); i++) {
+ if (future_values[i].value == value && future_values[i].tid == tid) {
+ if (expiration <= future_values[i].expiration)
+ return false;
+ idx = i;
+ }
+ }
+ if (idx > future_index) {
+ /* Future value hasn't been explored; update expiration */
+ future_values[idx].expiration = expiration;
+ return true;
+ } else if (idx >= 0 && expiration <= future_values[idx].expiration + get_params()->expireslop) {
+ /* Future value has been explored and is within the "sloppy" window */
+ return false;
+ }
+
+ /* Limit the size of the future-values set */
+ if (get_params()->maxfuturevalues > 0 &&
+ (int)future_values.size() >= get_params()->maxfuturevalues)
+ return false;
+
+ future_values.push_back(fv);
+ return true;
+}
+
+/**
+ * Gets the next 'future_value' from this Node. Only valid for a node where
+ * this->action is a 'read'.
+ * @return The first element in future_values
+ */
+struct future_value Node::get_future_value() const
+{
+ ASSERT(future_index >= 0 && future_index < ((int)future_values.size()));
+ return future_values[future_index];
+}
+
+/**
+ * Checks whether the future_values set for this node is empty.
+ * @return true if the future_values set is empty.
+ */
+bool Node::future_value_empty() const
+{
+ return ((future_index + 1) >= ((int)future_values.size()));