X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=nodestack.cc;h=c757af25f647339fe7ef590ad1eb989271aff222;hb=20994240335ce1d54fb6c4b2c8df684182f0a3f9;hp=e6f0269c0c2720a09d1c74882cb597a8afefd044;hpb=bb168337e93650eddb90df61b109db4e1e8570c9;p=model-checker.git diff --git a/nodestack.cc b/nodestack.cc index e6f0269..c757af2 100644 --- a/nodestack.cc +++ b/nodestack.cc @@ -27,6 +27,7 @@ Node::Node(ModelAction *act, Node *par, int nthreads, Node *prevfairness) : read_from_status(READ_FROM_PAST), action(act), + uninit_action(NULL), parent(par), num_threads(nthreads), explored_children(num_threads), @@ -45,7 +46,8 @@ Node::Node(ModelAction *act, Node *par, int nthreads, Node *prevfairness) : relseq_break_writes(), relseq_break_index(0), misc_index(0), - misc_max(0) + misc_max(0), + yield_data(NULL) { ASSERT(act); act->set_node(this); @@ -86,18 +88,81 @@ Node::Node(ModelAction *act, Node *par, int nthreads, Node *prevfairness) : } } +int Node::get_yield_data(int tid1, int tid2) const { + if (tid1get_tid()); + + for(int u = 0; u < num_threads; u++) { + for(int v = 0; v < num_threads; v++) { + int yield_state=parent->get_yield_data(u, v); + bool next_enabled=scheduler->is_enabled(int_to_id(v)); + bool curr_enabled=parent->is_enabled(int_to_id(v)); + if (!next_enabled) { + //Compute intersection of ES and E + yield_state&=~YIELD_E; + //Check to see if we disabled the thread + if (u==curr_tid && curr_enabled) + yield_state|=YIELD_D; + } + yield_data[YIELD_INDEX(u, v, num_threads)]=yield_state; + } + yield_data[YIELD_INDEX(u, curr_tid, num_threads)]=(yield_data[YIELD_INDEX(u, curr_tid, num_threads)]&~YIELD_P)|YIELD_S; + } + //handle curr.yield(t) part of computation + if (action->is_yield()) { + for(int v = 0; v < num_threads; v++) { + int yield_state=yield_data[YIELD_INDEX(curr_tid, v, num_threads)]; + if ((yield_state & (YIELD_E | YIELD_D)) && (!(yield_state & YIELD_S))) + yield_state |= YIELD_P; + yield_state &= YIELD_P; + if (scheduler->is_enabled(int_to_id(v))) { + yield_state|=YIELD_E; + } + yield_data[YIELD_INDEX(curr_tid, v, num_threads)]=yield_state; + } + } +} + /** @brief Node desctructor */ Node::~Node() { delete action; + if (uninit_action) + delete uninit_action; if (enabled_array) model_free(enabled_array); + if (yield_data) + model_free(yield_data); } /** Prints debugging info for the ModelAction associated with this Node */ void Node::print() const { action->print(); + model_print(" thread status: "); + if (enabled_array) { + for (int i = 0; i < num_threads; i++) { + char str[20]; + enabled_type_to_string(enabled_array[i], str); + model_print("[%d: %s]", i, str); + } + model_print("\n"); + } else + model_print("(info not available)\n"); model_print(" backtrack: %s", backtrack_empty() ? "empty" : "non-empty "); for (int i = 0; i < (int)backtrack.size(); i++) if (backtrack[i] == true) @@ -285,6 +350,7 @@ void Node::clear_backtracking() backtrack[i] = false; for (unsigned int i = 0; i < explored_children.size(); i++) explored_children[i] = false; + numBacktracks = 0; } bool Node::is_enabled(Thread *t) const @@ -313,6 +379,11 @@ bool Node::has_priority(thread_id_t tid) const return fairness[id_to_int(tid)].priority; } +bool Node::has_priority_over(thread_id_t tid1, thread_id_t tid2) const +{ + return get_yield_data(id_to_int(tid1), id_to_int(tid2)) & YIELD_P; +} + /*********************************** read from ********************************/ /** @@ -457,11 +528,28 @@ void Node::add_read_from_promise(const ModelAction *reader) */ Promise * Node::get_read_from_promise() const { - if (read_from_promise_idx < 0 || read_from_promise_idx >= ((int)read_from_promises.size())) - return NULL; + ASSERT(read_from_promise_idx >= 0 && read_from_promise_idx < ((int)read_from_promises.size())); return read_from_promises[read_from_promise_idx]->get_reads_from_promise(); } +/** + * Gets a particular 'read-from-promise' form this Node. Only vlaid for a node + * where this->action is a 'read'. + * @param i The index of the Promise to get + * @return The Promise at index i, if the Promise is still available; NULL + * otherwise + */ +Promise * Node::get_read_from_promise(int i) const +{ + return read_from_promises[i]->get_reads_from_promise(); +} + +/** @return The size of the read-from-promise set */ +int Node::get_read_from_promise_size() const +{ + return read_from_promises.size(); +} + /** * Checks whether the read_from_promises set for this node is empty. * @return true if the read_from_promises set is empty.