+ ASSERT(act);
+ act->set_node(this);
+ int currtid = id_to_int(act->get_tid());
+ int prevtid = prevfairness ? id_to_int(prevfairness->action->get_tid()) : 0;
+
+ if (get_params()->fairwindow != 0) {
+ for (int i = 0; i < num_threads; i++) {
+ ASSERT(i < ((int)fairness.size()));
+ struct fairness_info *fi = &fairness[i];
+ struct fairness_info *prevfi = (parent && i < parent->get_num_threads()) ? &parent->fairness[i] : NULL;
+ if (prevfi) {
+ *fi = *prevfi;
+ }
+ if (parent && parent->is_enabled(int_to_id(i))) {
+ fi->enabled_count++;
+ }
+ if (i == currtid) {
+ fi->turns++;
+ fi->priority = false;
+ }
+ /* Do window processing */
+ if (prevfairness != NULL) {
+ if (prevfairness->parent->is_enabled(int_to_id(i)))
+ fi->enabled_count--;
+ if (i == prevtid) {
+ fi->turns--;
+ }
+ /* Need full window to start evaluating
+ * conditions
+ * If we meet the enabled count and have no
+ * turns, give us priority */
+ if ((fi->enabled_count >= get_params()->enabledcount) &&
+ (fi->turns == 0))
+ fi->priority = true;
+ }
+ }
+ }
+}
+
+int Node::get_yield_data(int tid1, int tid2) const {
+ if (tid1<num_threads && tid2 < num_threads)
+ return yield_data[YIELD_INDEX(tid1,tid2,num_threads)];
+ else
+ return YIELD_S | YIELD_D;
+}
+
+void Node::update_yield(Scheduler * scheduler) {
+ 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++) {
+ yield_data[i] = YIELD_S | YIELD_D;
+ }
+ return;
+ }
+ int curr_tid=id_to_int(action->get_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;
+ }
+ }