+ var_list = &(sys->saturated_variable_set);
+
+ xbt_swag_foreach(var, var_list) {
+ /* First check if some of these variables have reach their upper
+ bound and update min_usage accordingly. */
+ DEBUG5("var=%p, var->bound=%f, var->weight=%f, min_usage=%f, var->bound*var->weight=%f",
+ var, var->bound, var->weight, min_usage,var->bound * var->weight);
+ if ((var->bound > 0) && (var->bound * var->weight < min_usage)) {
+ min_usage = var->bound * var->weight;
+ DEBUG1("Updated min_usage=%f",min_usage);
+ }
+ }
+
+
+ while ((var = xbt_swag_getFirst(var_list))) {
+ int i;
+
+ var->value = min_usage / var->weight;
+ DEBUG5("Min usage: %f, Var(%p)->weight: %f, Var(%p)->value: %f ",min_usage,var,var->weight,var,var->value);
+
+
+ /* Update usage */
+
+ for (i = 0; i < var->cnsts_number; i++) {
+ elem = &var->cnsts[i];
+ cnst = elem->constraint;
+ if(cnst->shared) {
+ double_update(&(cnst->remaining), elem->value * var->value);
+ double_update(&(cnst->usage), elem->value / var->weight);
+ make_elem_inactive(elem);
+ } else { /* FIXME one day: We recompute usage.... :( */
+ cnst->usage = 0.0;
+ make_elem_inactive(elem);
+ xbt_swag_foreach(elem, elem_list) {
+ if(elem->variable->weight <=0) break;
+ if(elem->variable->value > 0) break;
+ if ((elem->value > 0)) {
+ if(cnst->usage<elem->value / elem->variable->weight)
+ cnst->usage = elem->value / elem->variable->weight;
+ DEBUG2("Constraint Usage %p : %f",cnst,cnst->usage);
+ make_elem_active(elem);
+ }
+ }
+ }
+ }
+ xbt_swag_remove(var, var_list);
+ }
+
+ /* Find out which variables reach the maximum */
+ cnst_list = &(sys->active_constraint_set);
+ min_usage = -1;
+ xbt_swag_foreach(cnst, cnst_list) {
+ saturated_constraint_set_update(sys, cnst, &min_usage);
+ }
+ saturated_variable_set_update(sys);
+
+ } while (xbt_swag_size(&(sys->saturated_variable_set)));
+
+ sys->modified = 0;
+ if(XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug)) {
+ lmm_print(sys);
+ }
+}
+
+/* Not a O(1) function */
+
+void lmm_update(lmm_system_t sys, lmm_constraint_t cnst,
+ lmm_variable_t var, double value)
+{
+ int i;
+
+ sys->modified = 1;
+ for (i = 0; i < var->cnsts_number; i++)
+ if (var->cnsts[i].constraint == cnst) {
+ var->cnsts[i].value = value;
+ return;
+ }
+}
+
+/** \brief Attribute the value bound to var->bound.
+ *
+ * \param sys the lmm_system_t
+ * \param var the lmm_variable_t
+ * \param bound the new bound to associate with var
+ *
+ * Makes var->bound equal to bound. Whenever this function is called
+ * a change is signed in the system. To
+ * avoid false system changing detection it is a good idea to test
+ * (bound != 0) before calling it.
+ *
+ */
+void lmm_update_variable_bound(lmm_system_t sys, lmm_variable_t var,
+ double bound)
+{
+ sys->modified = 1;
+ var->bound = bound;
+}
+
+/** \brief Add the value delta to var->df (the sum of latencies).
+ *
+ * \param sys the lmm_system_t associated
+ * \param var the lmm_variable_t which need to updated
+ * \param delta the variation of the latency
+ *
+ * Add the value delta to var->df (the sum of latencys associated to the
+ * flow). Whenever this function is called a change is signed in the system. To
+ * avoid false system changing detection it is a good idea to test
+ * (delta != 0) before calling it.
+ *
+ */
+void lmm_update_variable_latency(lmm_system_t sys, lmm_variable_t var,
+ double delta)
+{
+ sys->modified = 1;
+ var->df += delta;
+}
+
+void lmm_update_variable_weight(lmm_system_t sys, lmm_variable_t var,
+ double weight)
+{
+ int i ;
+ lmm_element_t elem;