X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=nodestack.cc;h=80bf5c41bf1d1721e20ad7d6d38fe7f141ed869f;hb=e7e175a74d95b5ed0a50750453168275f2fa3589;hp=c757af25f647339fe7ef590ad1eb989271aff222;hpb=e6789461057e3395ba78575b85c114b553f4ed19;p=model-checker.git diff --git a/nodestack.cc b/nodestack.cc index c757af2..80bf5c4 100644 --- a/nodestack.cc +++ b/nodestack.cc @@ -9,6 +9,7 @@ #include "model.h" #include "threads-model.h" #include "modeltypes.h" +#include "execution.h" /** * @brief Node constructor @@ -96,7 +97,8 @@ int Node::get_yield_data(int tid1, int tid2) const { } void Node::update_yield(Scheduler * scheduler) { - yield_data=(int *) model_calloc(1, sizeof(int)*num_threads*num_threads); + if (yield_data==NULL) + yield_data=(int *) model_calloc(1, sizeof(int)*num_threads*num_threads); //handle base case if (parent == NULL) { for(int i = 0; i < num_threads*num_threads; i++) { @@ -189,87 +191,7 @@ void Node::print() const model_print(" rel seq break: %s\n", relseq_break_empty() ? "empty" : "non-empty"); } -/*********************************** promise **********************************/ - -/** - * Sets a promise to explore meeting with the given node. - * @param i is the promise index. - */ -void Node::set_promise(unsigned int i) -{ - if (i >= resolve_promise.size()) - resolve_promise.resize(i + 1, false); - resolve_promise[i] = true; -} - -/** - * Looks up whether a given promise should be satisfied by this node. - * @param i The promise index. - * @return true if the promise should be satisfied by the given ModelAction. - */ -bool Node::get_promise(unsigned int i) const -{ - return (i < resolve_promise.size()) && (int)i == resolve_promise_idx; -} - -/** - * Increments to the next promise to resolve. - * @return true if we have a valid combination. - */ -bool Node::increment_promise() -{ - DBG(); - if (resolve_promise.empty()) - return false; - int prev_idx = resolve_promise_idx; - resolve_promise_idx++; - for ( ; resolve_promise_idx < (int)resolve_promise.size(); resolve_promise_idx++) - if (resolve_promise[resolve_promise_idx]) - return true; - resolve_promise_idx = prev_idx; - return false; -} - -/** - * Returns whether the promise set is empty. - * @return true if we have explored all promise combinations. - */ -bool Node::promise_empty() const -{ - for (int i = resolve_promise_idx + 1; i < (int)resolve_promise.size(); i++) - if (i >= 0 && resolve_promise[i]) - return false; - return true; -} - -/** @brief Clear any promise-resolution information for this Node */ -void Node::clear_promise_resolutions() -{ - resolve_promise.clear(); - resolve_promise_idx = -1; -} - -/******************************* end promise **********************************/ - -void Node::set_misc_max(int i) -{ - misc_max = i; -} - -int Node::get_misc() const -{ - return misc_index; -} - -bool Node::increment_misc() -{ - return (misc_index < misc_max) && ((++misc_index) < misc_max); -} - -bool Node::misc_empty() const -{ - return (misc_index + 1) >= misc_max; -} +/****************************** threads backtracking **************************/ /** * Checks if the Thread associated with this thread ID has been explored from @@ -293,6 +215,17 @@ bool Node::backtrack_empty() const return (numBacktracks == 0); } +void Node::explore(thread_id_t tid) +{ + int i = id_to_int(tid); + ASSERT(i < ((int)backtrack.size())); + if (backtrack[i]) { + backtrack[i] = false; + numBacktracks--; + } + explored_children[i] = true; +} + /** * Mark the appropriate backtracking information for exploring a thread choice. * @param act The ModelAction to explore @@ -353,6 +286,90 @@ void Node::clear_backtracking() numBacktracks = 0; } +/************************** end threads backtracking **************************/ + +/*********************************** promise **********************************/ + +/** + * Sets a promise to explore meeting with the given node. + * @param i is the promise index. + */ +void Node::set_promise(unsigned int i) +{ + if (i >= resolve_promise.size()) + resolve_promise.resize(i + 1, false); + resolve_promise[i] = true; +} + +/** + * Looks up whether a given promise should be satisfied by this node. + * @param i The promise index. + * @return true if the promise should be satisfied by the given ModelAction. + */ +bool Node::get_promise(unsigned int i) const +{ + return (i < resolve_promise.size()) && (int)i == resolve_promise_idx; +} + +/** + * Increments to the next promise to resolve. + * @return true if we have a valid combination. + */ +bool Node::increment_promise() +{ + DBG(); + if (resolve_promise.empty()) + return false; + int prev_idx = resolve_promise_idx; + resolve_promise_idx++; + for ( ; resolve_promise_idx < (int)resolve_promise.size(); resolve_promise_idx++) + if (resolve_promise[resolve_promise_idx]) + return true; + resolve_promise_idx = prev_idx; + return false; +} + +/** + * Returns whether the promise set is empty. + * @return true if we have explored all promise combinations. + */ +bool Node::promise_empty() const +{ + for (int i = resolve_promise_idx + 1; i < (int)resolve_promise.size(); i++) + if (i >= 0 && resolve_promise[i]) + return false; + return true; +} + +/** @brief Clear any promise-resolution information for this Node */ +void Node::clear_promise_resolutions() +{ + resolve_promise.clear(); + resolve_promise_idx = -1; +} + +/******************************* end promise **********************************/ + +void Node::set_misc_max(int i) +{ + misc_max = i; +} + +int Node::get_misc() const +{ + return misc_index; +} + +bool Node::increment_misc() +{ + return (misc_index < misc_max) && ((++misc_index) < misc_max); +} + +bool Node::misc_empty() const +{ + return (misc_index + 1) >= misc_max; +} + bool Node::is_enabled(Thread *t) const { int thread_id = id_to_int(t->get_id()); @@ -654,6 +671,8 @@ bool Node::increment_future_value() /************************** end future values *********************************/ +/*********************** breaking release sequences ***************************/ + /** * Add a write ModelAction to the set of writes that may break the release * sequence. This is used during replay exploration of pending release @@ -706,15 +725,27 @@ bool Node::relseq_break_empty() const return ((relseq_break_index + 1) >= ((int)relseq_break_writes.size())); } -void Node::explore(thread_id_t tid) +/******************* end breaking release sequences ***************************/ + +/** + * Increments some behavior's index, if a new behavior is available + * @return True if there is a new behavior available; otherwise false + */ +bool Node::increment_behaviors() { - int i = id_to_int(tid); - ASSERT(i < ((int)backtrack.size())); - if (backtrack[i]) { - backtrack[i] = false; - numBacktracks--; - } - explored_children[i] = true; + /* satisfy a different misc_index values */ + if (increment_misc()) + return true; + /* satisfy a different set of promises */ + if (increment_promise()) + return true; + /* read from a different value */ + if (increment_read_from()) + return true; + /* resolve a release sequence differently */ + if (increment_relseq_break()) + return true; + return false; } NodeStack::NodeStack() : @@ -731,6 +762,15 @@ NodeStack::~NodeStack() delete node_list[i]; } +/** + * @brief Register the model-checker object with this NodeStack + * @param exec The execution structure for the ModelChecker + */ +void NodeStack::register_engine(const ModelExecution *exec) +{ + this->execution = exec; +} + void NodeStack::print() const { model_print("............................................\n"); @@ -763,7 +803,7 @@ ModelAction * NodeStack::explore_action(ModelAction *act, enabled_type_t *is_ena prevfairness = node_list[head_idx - model->params.fairwindow]; } - int next_threads = model->get_num_threads(); + int next_threads = execution->get_num_threads(); if (act->get_type() == THREAD_CREATE) next_threads++; node_list.push_back(new Node(act, head, next_threads, prevfairness));