bool r_status = false;
if (!second_part_of_rmw) {
- check_recency(curr);
+ check_recency(curr, reads_from);
r_status = r_modification_order(curr, reads_from);
}
build_reads_from_past(curr);
curr = newcurr;
+ /* Initialize work_queue with the "current action" work */
work_queue_t work_queue(1, CheckCurrWorkEntry(curr));
while (!work_queue.empty()) {
bool update = false; /* update this location's release seq's */
bool update_all = false; /* update all release seq's */
- process_thread_action(curr);
+ if (process_thread_action(curr))
+ update_all = true;
if (act->is_read() && process_read(act, second_part_of_rmw))
update = true;
if (w_modification_order(act))
updated = true;
}
+ mo_graph->commitChanges();
if (updated)
work_queue.push_back(CheckRelSeqWorkEntry(act->get_location()));
/** @return whether the current partial trace is feasible. */
bool ModelChecker::isfeasible() {
+ if (DBG_ENABLED() && mo_graph->checkForRMWViolation())
+ DEBUG("Infeasible: RMW violation\n");
+
return !mo_graph->checkForRMWViolation() && isfeasibleotherthanRMW();
}
*
* If so, we decide that the execution is no longer feasible.
*/
-void ModelChecker::check_recency(ModelAction *curr) {
+void ModelChecker::check_recency(ModelAction *curr, const ModelAction *rf) {
if (params.maxreads != 0) {
+
if (curr->get_node()->get_read_from_size() <= 1)
return;
-
//Must make sure that execution is currently feasible... We could
//accidentally clear by rolling back
if (!isfeasible())
return;
-
std::vector<action_list_t> *thrd_lists = obj_thrd_map->get_safe_ptr(curr->get_location());
int tid = id_to_int(curr->get_tid());
/* Skip checks */
if ((int)thrd_lists->size() <= tid)
return;
-
action_list_t *list = &(*thrd_lists)[tid];
action_list_t::reverse_iterator rit = list->rbegin();
ModelAction *act = *rit;
if (!act->is_read())
return;
- if (act->get_reads_from() != curr->get_reads_from())
+
+ if (act->get_reads_from() != rf)
return;
if (act->get_node()->get_read_from_size() <= 1)
return;
}
-
for (int i = 0; i<curr->get_node()->get_read_from_size(); i++) {
//Get write
const ModelAction * write = curr->get_node()->get_read_from_at(i);
+
//Need a different write
- if (write==curr->get_reads_from())
+ if (write==rf)
continue;
/* Test to see whether this is a feasible write to read from*/
*/
bool ModelChecker::release_seq_head(const ModelAction *rf, rel_heads_list_t *release_heads) const
{
+ /* Only check for release sequences if there are no cycles */
+ if (mo_graph->checkForCycles())
+ return false;
+
while (rf) {
ASSERT(rf->is_write());
work_queue->push_back(MOEdgeWorkEntry(act));
/* propagate synchronization to later actions */
- action_list_t::reverse_iterator it = action_trace->rbegin();
- for (; (*it) != act; it++) {
- ModelAction *propagate = *it;
+ action_list_t::reverse_iterator rit = action_trace->rbegin();
+ for (; (*rit) != act; rit++) {
+ ModelAction *propagate = *rit;
if (act->happens_before(propagate)) {
propagate->synchronize_with(act);
/* Re-check 'propagate' for mo_graph edges */
Promise *promise = (*promises)[promise_index];
if (write->get_node()->get_promise(i)) {
ModelAction *read = promise->get_action();
- read->read_from(write);
if (read->is_rmw()) {
mo_graph->addRMWEdge(write, read);
}
+ read->read_from(write);
//First fix up the modification order for actions that happened
//before the read
r_modification_order(read, write);
//Next fix up the modification order for actions that happened
//after the read.
post_r_modification_order(read, write);
+
promises->erase(promises->begin() + promise_index);
resolved = true;
} else
if (curr->get_state() == THREAD_READY) {
ASSERT(priv->current_action);
+ if (priv->current_action->get_seq_number()>600)
+ print_summary();
priv->nextThread = check_current_action(priv->current_action);
priv->current_action = NULL;
if (curr->is_blocked() || curr->is_complete())