X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=model.cc;h=c86a6f676718d3fab6122282483786dd85589cb0;hb=a02d0bed3bc5ab757c3ed30a9589c53b05919688;hp=31809918361c185cedc7d1ac791044f01bd23bad;hpb=21c976cef707ef9ccd33ec72f07a297b4cec057d;p=model-checker.git diff --git a/model.cc b/model.cc index 3180991..c86a6f6 100644 --- a/model.cc +++ b/model.cc @@ -162,7 +162,10 @@ bool ModelChecker::next_execution() DBG(); num_executions++; - print_summary(); + + if (isfeasible() || DBG_ENABLED()) + print_summary(); + if ((diverge = model->get_next_backtrack()) == NULL) return false; @@ -232,6 +235,11 @@ void ModelChecker::set_backtracking(ModelAction *act) } } +/** + * Returns last backtracking point. The model checker will explore a different + * path for this point in the next execution. + * @return The ModelAction at which the next execution should diverge. + */ ModelAction * ModelChecker::get_next_backtrack() { ModelAction *next = next_backtrack; @@ -249,6 +257,15 @@ void ModelChecker::check_current_action(void) return; } + if (curr->is_rmw()) { + //We have a RMW action + process_rmw(curr); + //Force the current thread to continue since the RMW should be atomic + nextThread = thread_current()->get_id(); + delete curr; + return; + } + tmp = node_stack->explore_action(curr); if (tmp) { /* Discard duplicate ModelAction; use action from NodeStack */ @@ -271,6 +288,10 @@ void ModelChecker::check_current_action(void) th->set_creation(curr); } + /* Is there a better interface for setting the next thread rather + than this field/convoluted approach? Perhaps like just returning + it or something? */ + nextThread = get_next_replay_thread(); Node *currnode = curr->get_node(); @@ -283,8 +304,6 @@ void ModelChecker::check_current_action(void) set_backtracking(curr); /* Assign reads_from values */ - /* TODO: perform release/acquire synchronization here; include - * reads_from as ModelAction member? */ Thread *th = get_thread(curr->get_tid()); uint64_t value = VALUE_NONE; if (curr->is_read()) { @@ -303,10 +322,24 @@ void ModelChecker::check_current_action(void) add_action_to_lists(curr); } +/** @returns whether the current trace is feasible. */ bool ModelChecker::isfeasible() { return !cyclegraph->checkForCycles(); } +/** Process a RMW by converting previous read into a RMW. */ +void ModelChecker::process_rmw(ModelAction * act) { + int tid = id_to_int(act->get_tid()); + ModelAction *lastread=get_last_action(tid); + lastread->upgrade_rmw(act); + cyclegraph->addRMWEdge(lastread->get_reads_from(),lastread); +} + +/** + * Updates the cyclegraph with the constraints imposed from the current read. + * @param curr The current action. Must be a read. + * @param rf The action that curr reads from. Must be a write. + */ void ModelChecker::r_modification_order(ModelAction * curr, const ModelAction *rf) { std::vector *thrd_lists = &(*obj_thrd_map)[curr->get_location()]; unsigned int i; @@ -335,6 +368,10 @@ void ModelChecker::r_modification_order(ModelAction * curr, const ModelAction *r } } +/** + * Updates the cyclegraph with the constraints imposed from the current write. + * @param curr The current action. Must be a write. + */ void ModelChecker::w_modification_order(ModelAction * curr) { std::vector *thrd_lists = &(*obj_thrd_map)[curr->get_location()]; unsigned int i; @@ -425,6 +462,11 @@ ModelAction * ModelChecker::get_parent_action(thread_id_t tid) return parent; } +/** + * Returns the clock vector for a given thread. + * @param tid The thread whose clock vector we want + * @return Desired clock vector + */ ClockVector * ModelChecker::get_cv(thread_id_t tid) { return get_parent_action(tid)->get_cv(); } @@ -519,11 +561,11 @@ void ModelChecker::print_summary(void) printf("\n"); printf("Number of executions: %d\n", num_executions); printf("Total nodes created: %d\n", node_stack->get_total_nodes()); - if (!isfeasible()) - printf("INFEASIBLE EXECUTION!\n"); scheduler->print(); + if (!isfeasible()) + printf("INFEASIBLE EXECUTION!\n"); print_list(action_trace); printf("\n"); }