+ unsigned int i;
+ link_CM02_t link;
+ int failed = 0;
+ surf_action_network_CM02_t action = NULL;
+ double bandwidth_bound;
+ double latency=0.0;
+ /* LARGE PLATFORMS HACK:
+ Add a link_CM02_t *link and a int link_nb to network_card_CM02_t. It will represent local links for this node
+ Use the cluster_id for ->id */
+
+ xbt_dynar_t back_route = NULL;
+ int constraints_per_variable = 0;
+ xbt_dynar_t route;
+ // I will need this route for some time so require for no cleanup
+ global_routing->get_route_latency(src_name, dst_name, &route, &latency, 0);
+
+ if (sg_network_fullduplex == 1) {
+ back_route = global_routing->get_route(dst_name, src_name);
+ }
+
+ /* LARGE PLATFORMS HACK:
+ total_route_size = route_size + src->link_nb + dst->nb */
+
+ XBT_IN("(%s,%s,%g,%g)", src_name, dst_name, size, rate);
+ /* LARGE PLATFORMS HACK:
+ assert on total_route_size */
+ xbt_assert(xbt_dynar_length(route) || latency,
+ "You're trying to send data from %s to %s but there is no connection at all between these two hosts.",
+ src_name, dst_name);
+
+ xbt_dynar_foreach(route, i, link) {
+ if (link->lmm_resource.state_current == SURF_RESOURCE_OFF) {
+ failed = 1;
+ break;
+ }
+ }
+ action =
+ surf_action_new(sizeof(s_surf_action_network_CM02_t), size,
+ surf_network_model, failed);
+#ifdef HAVE_LATENCY_BOUND_TRACKING
+ (action->generic_action).latency_limited = 0;
+#endif
+ action->weight = action->latency = latency;
+
+ xbt_swag_insert(action, action->generic_action.state_set);
+ action->rate = rate;
+
+ bandwidth_bound = -1.0;
+
+ xbt_dynar_foreach(route, i, link) {
+ action->weight +=
+ sg_weight_S_parameter /
+ (link->lmm_resource.power.peak * link->lmm_resource.power.scale);
+ if (bandwidth_bound < 0.0)
+ bandwidth_bound =
+ (*bandwidth_factor_callback) (size) *
+ (link->lmm_resource.power.peak * link->lmm_resource.power.scale);
+ else
+ bandwidth_bound =
+ min(bandwidth_bound,
+ (*bandwidth_factor_callback) (size) *
+ (link->lmm_resource.power.peak *
+ link->lmm_resource.power.scale));
+ }
+ /* LARGE PLATFORMS HACK:
+ Add src->link and dst->link latencies */
+ action->lat_current = action->latency;
+ action->latency *= (*latency_factor_callback) (size);
+ action->rate =
+ (*bandwidth_constraint_callback) (action->rate, bandwidth_bound,
+ size);
+
+ if(xbt_dynar_length(route) > 0) {
+ link = *(link_CM02_t*)xbt_dynar_get_ptr(route, 0);
+ gap_append(size, link, action);
+ XBT_DEBUG("Comm %p: %s -> %s gap=%f (lat=%f)",
+ action, src_name, dst_name, action->sender.gap, action->latency);
+ } else {
+ gap_unknown(action);
+ }
+
+
+ /* LARGE PLATFORMS HACK:
+ lmm_variable_new(..., total_route_size) */
+ if (back_route != NULL) {
+ constraints_per_variable =
+ xbt_dynar_length(route) + xbt_dynar_length(back_route);
+ } else {
+ constraints_per_variable = xbt_dynar_length(route);
+ }
+
+ if (action->latency > 0)
+ action->variable =
+ lmm_variable_new(network_maxmin_system, action, 0.0, -1.0,
+ constraints_per_variable);
+ else
+ action->variable =
+ lmm_variable_new(network_maxmin_system, action, 1.0, -1.0,
+ constraints_per_variable);
+
+ if (action->rate < 0) {
+ if (action->lat_current > 0)
+ lmm_update_variable_bound(network_maxmin_system, action->variable,
+ sg_tcp_gamma / (2.0 *
+ action->lat_current));
+ else
+ lmm_update_variable_bound(network_maxmin_system, action->variable,
+ -1.0);
+ } else {
+ if (action->lat_current > 0)
+ lmm_update_variable_bound(network_maxmin_system, action->variable,
+ min(action->rate,
+ sg_tcp_gamma / (2.0 *
+ action->lat_current)));
+ else
+ lmm_update_variable_bound(network_maxmin_system, action->variable,
+ action->rate);
+ }
+
+ xbt_dynar_foreach(route, i, link) {
+ lmm_expand(network_maxmin_system, link->lmm_resource.constraint,
+ action->variable, 1.0);
+ }
+
+ if (sg_network_fullduplex == 1) {
+ XBT_DEBUG("Fullduplex active adding backward flow using 5%c", '%');
+ xbt_dynar_foreach(back_route, i, link) {
+ lmm_expand(network_maxmin_system, link->lmm_resource.constraint,
+ action->variable, .05);
+ }
+ }
+ /* LARGE PLATFORMS HACK:
+ expand also with src->link and dst->link */
+#ifdef HAVE_TRACING
+ if (TRACE_is_enabled()) {
+ action->src_name = xbt_strdup(src_name);
+ action->dst_name = xbt_strdup(dst_name);
+ } else {
+ action->src_name = action->dst_name = NULL;
+ }
+#endif
+
+ xbt_dynar_free(&route);
+ XBT_OUT();
+
+ return (surf_action_t) action;
+}
+
+static xbt_dynar_t net_get_route(const char *src, const char *dst)
+{
+ return global_routing->get_route(src, dst);
+}
+
+static double net_get_link_bandwidth(const void *link)
+{
+ surf_resource_lmm_t lmm = (surf_resource_lmm_t) link;
+ return lmm->power.peak * lmm->power.scale;
+}
+
+static double net_get_link_latency(const void *link)
+{
+ return ((link_CM02_t) link)->lat_current;
+}
+
+static int net_link_shared(const void *link)
+{
+ return
+ lmm_constraint_is_shared(((surf_resource_lmm_t) link)->constraint);
+}
+
+static void net_action_suspend(surf_action_t action)
+{
+ ((surf_action_network_CM02_t) action)->suspended = 1;
+ lmm_update_variable_weight(network_maxmin_system,
+ ((surf_action_network_CM02_t)
+ action)->variable, 0.0);
+}
+
+static void net_action_resume(surf_action_t action)
+{
+ if (((surf_action_network_CM02_t) action)->suspended) {
+ lmm_update_variable_weight(network_maxmin_system,
+ ((surf_action_network_CM02_t)
+ action)->variable,
+ ((surf_action_network_CM02_t)
+ action)->weight);
+ ((surf_action_network_CM02_t) action)->suspended = 0;
+ }