// update short-term debts for a resource. // void RSC_WORK_FETCH::update_short_term_debts() { unsigned int i; PROJECT* p; int nprojects=0, nrprojects=0; double share_frac; double total_short_term_debt = 0; double rrs = gstate.runnable_resource_share(rsc_type); // for projects with no runnable jobs, // STD decays by a factor of e every day // double decay_factor = exp(-secs_this_debt_interval/86400); for (i=0; i<gstate.projects.size(); i++) { double delta; p = gstate.projects[i]; if (p->non_cpu_intensive) continue; if (!p->resource_share) continue; RSC_PROJECT_WORK_FETCH& rpwf = project_state(p); nprojects++; if (p->runnable(rsc_type)) { nrprojects++; share_frac = p->resource_share/rrs; delta = share_frac*secs_this_debt_interval - rpwf.secs_this_debt_interval; delta /= ninstances; if (log_flags.std_debug) { msg_printf(p, MSG_INFO, "[std] %s STD delta %.2f (%.2f*%.2f - %.2f)/%d", rsc_name(rsc_type), delta, share_frac, secs_this_debt_interval, rpwf.secs_this_debt_interval, ninstances ); } rpwf.short_term_debt += delta; } else { rpwf.short_term_debt *= decay_factor; } total_short_term_debt += rpwf.short_term_debt; } // normalize so mean is zero, and limit abs value to MAX_STD // if (nrprojects) { double avg_short_term_debt = total_short_term_debt / nprojects; for (i=0; i<gstate.projects.size(); i++) { p = gstate.projects[i]; if (p->non_cpu_intensive) continue; if (!p->resource_share) continue; if (p->runnable(rsc_type)) { RSC_PROJECT_WORK_FETCH& rpwf = project_state(p); rpwf.short_term_debt -= avg_short_term_debt; if (rpwf.short_term_debt > MAX_STD) { rpwf.short_term_debt = MAX_STD; } if (rpwf.short_term_debt < -MAX_STD) { rpwf.short_term_debt = -MAX_STD; } if (log_flags.std_debug) { msg_printf(p, MSG_INFO, "[std] %s STD %.2f", rsc_name(rsc_type), rpwf.short_term_debt ); } } } } }