* @return true if we have explored all promise combinations.
*/
bool Node::promise_empty() {
- unsigned int rmw_count=0;
- for (unsigned int i = 0; i < promises.size(); i++) {
- if (promises[i]==(PROMISE_RMW|PROMISE_FULFILLED))
- rmw_count++;
- }
-
- for (unsigned int i = 0; i < promises.size();i++) {
- if ((promises[i]& PROMISE_MASK) == PROMISE_UNFULFILLED) {
- //if this isn't a feasible option, keep going
- if ((rmw_count > 0)&&(promises[i] & PROMISE_RMW))
- continue;
+ bool fulfilledrmw=false;
+ for (int i = promises.size()-1 ; i>=0; i--) {
+ if (promises[i]==PROMISE_UNFULFILLED)
return false;
- } else if (promises[i] == (PROMISE_RMW|PROMISE_FULFILLED)) {
- rmw_count--;
- }
+ if (!fulfilledrmw && ((promises[i]&PROMISE_MASK)==PROMISE_UNFULFILLED))
+ return false;
+ if (promises[i]==(PROMISE_FULFILLED|PROMISE_RMW))
+ fulfilledrmw=true;
}
return true;
}
/**
- * Adds a value from a weakly ordered future write to backtrack to.
+ * Adds a value from a weakly ordered future write to backtrack to. This
+ * operation may "fail" if the future value is already set (with a later
+ * 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(uint64_t value, modelclock_t expiration) {
int suitableindex=-1;
future_values[suitableindex].expiration=expiration;
return true;
}
- struct future_value newfv={value, expiration};
+
+ if (model->params.maxfuturevalues > 0 &&
+ (int)future_values.size() >= model->params.maxfuturevalues)
+ return false;
+
+ struct future_value newfv = {value, expiration};
future_values.push_back(newfv);
return true;
}