From: Augustin Degomme Date: Tue, 14 Oct 2014 12:24:22 +0000 (+0200) Subject: Add a safe version of lmm_get_var_from_cnst to avoid looping forever when iterating... X-Git-Tag: v3_12~732^2~285^2~9 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/b5bb23bbab9e4dda8dc341c2220b10cd27d2e0d7?ds=sidebyside Add a safe version of lmm_get_var_from_cnst to avoid looping forever when iterating on a dynar we reorder dynamically --- diff --git a/src/include/surf/maxmin.h b/src/include/surf/maxmin.h index cf32554faa..2a5dc0aad2 100644 --- a/src/include/surf/maxmin.h +++ b/src/include/surf/maxmin.h @@ -284,6 +284,24 @@ XBT_PUBLIC(lmm_variable_t) lmm_get_var_from_cnst(lmm_system_t sys, lmm_constraint_t cnst, lmm_element_t * elem); +/** + * @brief Get a var associated to a constraint + * @details Get the first variable of the next variable of elem if elem is not NULL + * + * @param sys The system associated to the variable (not used) + * @param cnst A constraint + * @param elem A element of constraint of the constraint or NULL + * @param nextelem A element of constraint of the constraint or NULL, the one after elem + * @param numelem parameter representing the number of elements to go + * + * @return A variable associated to a constraint + */ +XBT_PUBLIC(lmm_variable_t) lmm_get_var_from_cnst_safe(lmm_system_t /*sys*/, + lmm_constraint_t cnst, + lmm_element_t * elem, + lmm_element_t * nextelem, + int * numelem); + /** * @brief Get the first active constraint of a system * diff --git a/src/surf/maxmin.cpp b/src/surf/maxmin.cpp index cd74d2a97d..ba1f601acb 100644 --- a/src/surf/maxmin.cpp +++ b/src/surf/maxmin.cpp @@ -431,6 +431,31 @@ lmm_variable_t lmm_get_var_from_cnst(lmm_system_t /*sys*/, return NULL; } +//if we modify the swag between calls, normal version may loop forever +//this safe version ensures that we browse the swag elements only once +lmm_variable_t lmm_get_var_from_cnst_safe(lmm_system_t /*sys*/, + lmm_constraint_t cnst, + lmm_element_t * elem, + lmm_element_t * nextelem, + int * numelem) +{ + if (!(*elem)){ + *elem = (lmm_element_t) xbt_swag_getFirst(&(cnst->element_set)); + *numelem = xbt_swag_size(&(cnst->element_set))-1; + }else{ + *elem = *nextelem; + if(*numelem>0){ + (*numelem) --; + }else + return NULL; + } + if (*elem){ + *nextelem = (lmm_element_t) xbt_swag_getNext(*elem, cnst->element_set.offset); + return (*elem)->variable; + }else + return NULL; +} + void *lmm_constraint_id(lmm_constraint_t cnst) { return cnst->id; diff --git a/src/surf/network_cm02.cpp b/src/surf/network_cm02.cpp index 637a243f08..fe4d32da08 100644 --- a/src/surf/network_cm02.cpp +++ b/src/surf/network_cm02.cpp @@ -614,6 +614,9 @@ void NetworkCm02Link::updateBandwidth(double value, double date){ (p_power.peak * p_power.scale); lmm_variable_t var = NULL; lmm_element_t elem = NULL; + lmm_element_t nextelem = NULL; + int numelem = 0; + NetworkCm02ActionPtr action = NULL; p_power.peak = value; @@ -625,7 +628,7 @@ void NetworkCm02Link::updateBandwidth(double value, double date){ TRACE_surf_link_set_bandwidth(date, getName(), sg_bandwidth_factor * p_power.peak * p_power.scale); #endif if (sg_weight_S_parameter > 0) { - while ((var = lmm_get_var_from_cnst(getModel()->getMaxminSystem(), getConstraint(), &elem))) { + while ((var = lmm_get_var_from_cnst_safe(getModel()->getMaxminSystem(), getConstraint(), &elem, &nextelem, &numelem))) { action = (NetworkCm02ActionPtr) lmm_variable_id(var); action->m_weight += delta; if (!action->isSuspended()) @@ -638,10 +641,12 @@ void NetworkCm02Link::updateLatency(double value, double date){ double delta = value - m_latCurrent; lmm_variable_t var = NULL; lmm_element_t elem = NULL; + lmm_element_t nextelem = NULL; + int numelem = 0; NetworkCm02ActionPtr action = NULL; m_latCurrent = value; - while ((var = lmm_get_var_from_cnst(getModel()->getMaxminSystem(), getConstraint(), &elem))) { + while ((var = lmm_get_var_from_cnst_safe(getModel()->getMaxminSystem(), getConstraint(), &elem, &nextelem, &numelem))) { action = (NetworkCm02ActionPtr) lmm_variable_id(var); action->m_latCurrent += delta; action->m_weight += delta;