/* The next node will try to read from a different future value. */
tid = next->get_tid();
node_stack->pop_restofstack(2);
+ } else if (nextnode->increment_relseq_break()) {
+ /* The next node will try to resolve a release sequence differently */
+ tid = next->get_tid();
+ node_stack->pop_restofstack(2);
} else {
/* Make a different thread execute for next step */
Node *node = nextnode->get_parent();
num_feasible_executions++;
}
- DEBUG("Number of acquires waiting on pending release sequences: %lu\n",
+ DEBUG("Number of acquires waiting on pending release sequences: %zu\n",
pending_rel_seqs->size());
if (isfinalfeasible() || DBG_ENABLED())
*/
if (newcurr->is_write())
compute_promises(newcurr);
+ else if (newcurr->is_relseq_fixup())
+ compute_relseq_breakwrites(newcurr);
}
return newcurr;
}
if ((!parnode->backtrack_empty() ||
!currnode->read_from_empty() ||
!currnode->future_value_empty() ||
- !currnode->promise_empty())
+ !currnode->promise_empty() ||
+ !currnode->relseq_break_empty())
&& (!priv->next_backtrack ||
*curr > *priv->next_backtrack)) {
priv->next_backtrack = curr;
bool future_ordered = false;
ModelAction *last = get_last_action(int_to_id(i));
- if (last && (rf->happens_before(last) ||
- get_thread(int_to_id(i))->is_complete()))
+ Thread *th = get_thread(int_to_id(i));
+ if ((last && rf->happens_before(last)) ||
+ !scheduler->is_enabled(th) ||
+ th->is_complete())
future_ordered = true;
for (rit = list->rbegin(); rit != list->rend(); rit++) {
}
}
+/**
+ * Compute the set of writes that may break the current pending release
+ * sequence. This information is extracted from previou release sequence
+ * calculations.
+ *
+ * @param curr The current ModelAction. Must be a release sequence fixup
+ * action.
+ */
+void ModelChecker::compute_relseq_breakwrites(ModelAction *curr)
+{
+ if (pending_rel_seqs->empty())
+ return;
+
+ struct release_seq *pending = pending_rel_seqs->back();
+ for (unsigned int i = 0; i < pending->writes.size(); i++) {
+ const ModelAction *write = pending->writes[i];
+ curr->get_node()->add_relseq_break(write);
+ }
+
+ /* NULL means don't break the sequence; just synchronize */
+ curr->get_node()->add_relseq_break(NULL);
+}
+
/**
* Build up an initial set of all past writes that this 'read' action may read
* from. This set is determined by the clock vector's "happens before"