X-Git-Url: http://plrg.eecs.uci.edu/git/?p=c11tester.git;a=blobdiff_plain;f=model.cc;h=e39266d41218feecb14d4fde94701c22cd2040d3;hp=ede2bcc840d8710ae00e3d021accadb6ef8e0698;hb=d3dffe991352938e5c2ab738ce70e3ec0f069d5f;hpb=523dbecc6fc18e58918a1f36860be5eb0ab42ce2 diff --git a/model.cc b/model.cc index ede2bcc8..e39266d4 100644 --- a/model.cc +++ b/model.cc @@ -721,7 +721,6 @@ bool ModelChecker::process_read(ModelAction *curr, bool second_part_of_rmw) r_status = r_modification_order(curr, reads_from); } - if (!second_part_of_rmw && is_infeasible() && (curr->get_node()->increment_read_from() || curr->get_node()->increment_future_value())) { mo_graph->rollbackChanges(); priv->too_many_reads = false; @@ -737,6 +736,7 @@ bool ModelChecker::process_read(ModelAction *curr, bool second_part_of_rmw) /* Read from future value */ struct future_value fv = curr->get_node()->get_future_value(); value = fv.value; + curr->set_value(fv.value); curr->set_read_from(NULL); promises->push_back(new Promise(curr, fv)); } @@ -855,10 +855,22 @@ bool ModelChecker::process_mutex(ModelAction *curr) void ModelChecker::add_future_value(const ModelAction *writer, ModelAction *reader) { /* Do more ambitious checks now that mo is more complete */ - if (mo_may_allow(writer, reader) && - reader->get_node()->add_future_value(writer, - writer->get_seq_number() + params.maxfuturedelay)) - set_latest_backtrack(reader); + if (mo_may_allow(writer, reader)) { + Node *node = reader->get_node(); + + /* Find an ancestor thread which exists at the time of the reader */ + Thread *write_thread = get_thread(writer); + while (id_to_int(write_thread->get_id()) >= node->get_num_threads()) + write_thread = write_thread->get_parent(); + + struct future_value fv = { + writer->get_value(), + writer->get_seq_number() + params.maxfuturedelay, + write_thread->get_id(), + }; + if (node->add_future_value(fv)) + set_latest_backtrack(reader); + } } /** @@ -955,6 +967,12 @@ bool ModelChecker::process_thread_action(ModelAction *curr) case THREAD_CREATE: { Thread *th = curr->get_thread_operand(); th->set_creation(curr); + /* Promises can be satisfied by children */ + for (unsigned int i = 0; i < promises->size(); i++) { + Promise *promise = (*promises)[i]; + if (promise->thread_is_available(curr->get_tid())) + promise->add_thread(th->get_id()); + } break; } case THREAD_JOIN: { @@ -971,6 +989,13 @@ bool ModelChecker::process_thread_action(ModelAction *curr) scheduler->wake(get_thread(act)); } th->complete(); + /* Completed thread can't satisfy promises */ + for (unsigned int i = 0; i < promises->size(); i++) { + Promise *promise = (*promises)[i]; + if (promise->thread_is_available(th->get_id())) + if (promise->eliminate_thread(th->get_id())) + priv->failed_promise = true; + } updated = true; /* trigger rel-seq checks */ break; } @@ -1347,8 +1372,6 @@ void ModelChecker::print_infeasibility(const char *prefix) const { char buf[100]; char *ptr = buf; - if (mo_graph->checkForRMWViolation()) - ptr += sprintf(ptr, "[RMW atomicity]"); if (mo_graph->checkForCycles()) ptr += sprintf(ptr, "[mo cycle]"); if (priv->failed_promise) @@ -1382,21 +1405,10 @@ bool ModelChecker::is_feasible_prefix_ignore_relseq() const */ bool ModelChecker::is_infeasible() const { - return mo_graph->checkForRMWViolation() || is_infeasible_ignoreRMW(); -} - -/** - * Check If the current partial trace is infeasible, while ignoring - * infeasibility related to 2 RMW's reading from the same store. It does not - * check end-of-execution feasibility. - * @see ModelChecker::is_infeasible - * @return whether the current partial trace is infeasible, ignoring multiple - * RMWs reading from the same store. - * */ -bool ModelChecker::is_infeasible_ignoreRMW() const -{ - return mo_graph->checkForCycles() || priv->failed_promise || - priv->too_many_reads || priv->bad_synchronization || + return mo_graph->checkForCycles() || + priv->failed_promise || + priv->too_many_reads || + priv->bad_synchronization || promises_expired(); } @@ -1785,10 +1797,10 @@ bool ModelChecker::w_modification_order(ModelAction *curr) */ if (thin_air_constraint_may_allow(curr, act)) { - if (!is_infeasible() || - (curr->is_rmw() && act->is_rmw() && curr->get_reads_from() == act->get_reads_from() && !is_infeasible_ignoreRMW())) { + if (!is_infeasible()) futurevalues->push_back(PendingFutureValue(curr, act)); - } + else if (curr->is_rmw() && act->is_rmw() && curr->get_reads_from() && curr->get_reads_from() == act->get_reads_from()) + add_future_value(curr, act); } } } @@ -2327,7 +2339,7 @@ bool ModelChecker::resolve_promises(ModelAction *write) post_r_modification_order(read, write); //Make sure the promise's value matches the write's value ASSERT(promise->get_value() == write->get_value()); - delete(promise); + delete promise; promises->erase(promises->begin() + promise_index); actions_to_check.push_back(read); @@ -2462,7 +2474,7 @@ void ModelChecker::mo_check_promises(thread_id_t tid, const ModelAction *write, } // Don't do any lookups twice for the same thread - if (promise->thread_is_eliminated(tid)) + if (!promise->thread_is_available(tid)) continue; if (promise->get_write() && mo_graph->checkReachable(promise->get_write(), write)) { @@ -2635,7 +2647,6 @@ void ModelChecker::dumpGraph(char *filename) const void ModelChecker::print_summary() const { #if SUPPORT_MOD_ORDER_DUMP - scheduler->print(); char buffername[100]; sprintf(buffername, "exec%04u", stats.num_total); mo_graph->dumpGraphToFile(buffername);