Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
At least. ignore ignorable
[simgrid.git] / src / surf / network.c
1 /*      $Id$     */
2
3 /* Copyright (c) 2004 Arnaud Legrand. All rights reserved.                  */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 #include "network_private.h"
9 #include "xbt/log.h"
10 #include "xbt/str.h"
11
12 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network, surf,
13                                 "Logging specific to the SURF network module");
14
15 surf_network_model_t surf_network_model = NULL;
16 static lmm_system_t network_maxmin_system = NULL;
17 static void (*network_solve) (lmm_system_t) = NULL;
18 xbt_dict_t link_set = NULL;
19 xbt_dict_t network_card_set = NULL;
20
21 double latency_factor = 1.0; /* default value */
22 double bandwidth_factor = 1.0; /* default value */
23 double weight_S_parameter = 0.0; /* default value */
24
25 int card_number = 0;
26 int host_number = 0;
27 link_CM02_t **routing_table = NULL;
28 int *routing_table_size = NULL;
29 static link_CM02_t loopback = NULL;
30
31 static void create_routing_table(void)
32 {
33   routing_table =
34       xbt_new0(link_CM02_t *, /*card_number * card_number */ host_number * host_number);
35   routing_table_size = xbt_new0(int, /*card_number * card_number*/ host_number * host_number);
36 }
37
38 static void link_free(void *nw_link)
39 {
40   free(((link_CM02_t) nw_link)->name);
41   xbt_dict_free(&(((link_CM02_t)nw_link)->properties));
42   free(nw_link);
43 }
44
45 static link_CM02_t link_new(char *name,
46                             double bw_initial,
47                             tmgr_trace_t bw_trace,
48                             double lat_initial,
49                             tmgr_trace_t lat_trace,
50                             e_surf_link_state_t
51                             state_initial,
52                             tmgr_trace_t state_trace,
53                             e_surf_link_sharing_policy_t
54                             policy, xbt_dict_t properties)
55 {
56   link_CM02_t nw_link = xbt_new0(s_link_CM02_t, 1);
57   xbt_assert1(!xbt_dict_get_or_null(link_set, name), 
58               "Link '%s' declared several times in the platform file.", name);   
59
60   nw_link->model = (surf_model_t) surf_network_model;
61   nw_link->name = name;
62   nw_link->bw_current = bw_initial;
63   if (bw_trace)
64     nw_link->bw_event =
65         tmgr_history_add_trace(history, bw_trace, 0.0, 0, nw_link);
66   nw_link->lat_current = lat_initial;
67   if (lat_trace)
68     nw_link->lat_event =
69         tmgr_history_add_trace(history, lat_trace, 0.0, 0, nw_link);
70   nw_link->state_current = state_initial;
71   if (state_trace)
72     nw_link->state_event =
73         tmgr_history_add_trace(history, state_trace, 0.0, 0, nw_link);
74
75   nw_link->constraint =
76       lmm_constraint_new(network_maxmin_system, nw_link,
77                          bandwidth_factor*nw_link->bw_current);
78
79   if (policy == SURF_LINK_FATPIPE)
80     lmm_constraint_shared(nw_link->constraint);
81
82   nw_link->properties = properties;
83
84   current_property_set = properties;
85
86   xbt_dict_set(link_set, name, nw_link, link_free);
87
88   return nw_link;
89 }
90
91 static void network_card_free(void *nw_card)
92 {
93   free(((network_card_CM02_t) nw_card)->name);
94   free(nw_card);
95 }
96
97 static int network_card_new(const char *card_name)
98 {
99   network_card_CM02_t card =
100       xbt_dict_get_or_null(network_card_set, card_name);
101
102   if (!card) {
103     card = xbt_new0(s_network_card_CM02_t, 1);
104     card->name = xbt_strdup(card_name);
105     card->id = host_number++;
106     xbt_dict_set(network_card_set, card_name, card, network_card_free);
107   }
108   return card->id;
109 }
110
111 static void route_new(int src_id, int dst_id,
112                       link_CM02_t * link_list, int nb_link)
113 {
114   ROUTE_SIZE(src_id, dst_id) = nb_link;
115   ROUTE(src_id, dst_id) = link_list =
116       xbt_realloc(link_list, sizeof(link_CM02_t) * nb_link);
117 }
118
119 static void parse_link_init(void)
120 {
121   char *name_link;
122   double bw_initial;
123   tmgr_trace_t bw_trace;
124   double lat_initial;
125   tmgr_trace_t lat_trace;
126   e_surf_link_state_t state_initial_link = SURF_LINK_ON;
127   e_surf_link_sharing_policy_t policy_initial_link = SURF_LINK_SHARED;
128   tmgr_trace_t state_trace;
129
130   name_link = xbt_strdup(A_surfxml_link_id);
131   surf_parse_get_double(&bw_initial, A_surfxml_link_bandwidth);
132   surf_parse_get_trace(&bw_trace, A_surfxml_link_bandwidth_file);
133   surf_parse_get_double(&lat_initial, A_surfxml_link_latency);
134   surf_parse_get_trace(&lat_trace, A_surfxml_link_latency_file);
135
136   xbt_assert0((A_surfxml_link_state ==
137                A_surfxml_link_state_ON)
138               || (A_surfxml_link_state ==
139                   A_surfxml_link_state_OFF), "Invalid state");
140   if (A_surfxml_link_state == A_surfxml_link_state_ON)
141     state_initial_link = SURF_LINK_ON;
142   else if (A_surfxml_link_state ==
143            A_surfxml_link_state_OFF)
144     state_initial_link = SURF_LINK_OFF;
145
146   if (A_surfxml_link_sharing_policy ==
147       A_surfxml_link_sharing_policy_SHARED)
148     policy_initial_link = SURF_LINK_SHARED;
149   else if (A_surfxml_link_sharing_policy ==
150            A_surfxml_link_sharing_policy_FATPIPE)
151     policy_initial_link = SURF_LINK_FATPIPE;
152
153   surf_parse_get_trace(&state_trace, A_surfxml_link_state_file);
154
155   link_new(name_link, bw_initial, bw_trace,
156                    lat_initial, lat_trace, state_initial_link, state_trace,
157                    policy_initial_link, xbt_dict_new());
158
159 }
160
161 static int src_id = -1;
162 static int dst_id = -1;
163
164 static void parse_route_set_endpoints(void)
165 {
166   src_id = network_card_new(A_surfxml_route_src);
167   dst_id = network_card_new(A_surfxml_route_dst);
168   route_action = A_surfxml_route_action;
169 }
170
171 static void parse_route_set_route(void)
172 {
173   char *name;
174   if (src_id != -1 && dst_id != -1) {
175     name = bprintf("%x#%x",src_id, dst_id);
176     manage_route(route_table, name, route_action, 0);
177     free(name);    
178   }
179 }
180
181 static void add_loopback(void)
182 {
183   int i;
184   /* Adding loopback if needed */
185   for (i = 0; i < host_number; i++)
186     if (!ROUTE_SIZE(i, i)) {
187       if (!loopback)
188         loopback = link_new(xbt_strdup("__MSG_loopback__"),
189                                     498000000, NULL, 0.000015, NULL,
190                                     SURF_LINK_ON, NULL,
191                                     SURF_LINK_FATPIPE,NULL);
192       ROUTE_SIZE(i, i) = 1;
193       ROUTE(i, i) = xbt_new0(link_CM02_t, 1);
194       ROUTE(i, i)[0] = loopback;
195     }
196 }
197
198 static void add_route(void)
199 {
200   xbt_ex_t e;
201   int nb_link = 0;
202   unsigned int cpt = 0;    
203   int link_list_capacity = 0;
204   link_CM02_t *link_list = NULL;
205   xbt_dict_cursor_t cursor = NULL;
206   char *key,*data, *end;
207   const char *sep = "#";
208   xbt_dynar_t links, keys;
209
210   if (routing_table == NULL) create_routing_table();
211
212   xbt_dict_foreach(route_table, cursor, key, data) {
213           char* link = NULL;
214     nb_link = 0;
215     links = (xbt_dynar_t)data;
216     keys = xbt_str_split_str(key, sep);
217
218     link_list_capacity = xbt_dynar_length(links);
219     link_list = xbt_new(link_CM02_t, link_list_capacity);
220
221     src_id = strtol(xbt_dynar_get_as(keys, 0, char*), &end, 16);
222     dst_id = strtol(xbt_dynar_get_as(keys, 1, char*), &end, 16);
223     xbt_dynar_free(&keys);
224  
225     xbt_dynar_foreach (links, cpt, link) {
226       TRY {
227         link_list[nb_link++] = xbt_dict_get(link_set, link);
228       }
229       CATCH(e) {
230         RETHROW1("Link %s not found (dict raised this exception: %s)", link);
231       }     
232     }
233     route_new(src_id, dst_id, link_list, nb_link);
234    }
235 }
236
237 static void count_hosts(void)
238 {
239    host_number++;
240 }
241
242
243 static void add_traces(void) {
244    xbt_dict_cursor_t cursor=NULL;
245    char *trace_name,*elm;
246    
247    static int called = 0;
248    if (called) return;
249    called = 1;
250
251    /* connect all traces relative to network */
252    xbt_dict_foreach(trace_connect_list_link_avail, cursor, trace_name, elm) {
253       tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
254       link_CM02_t link = xbt_dict_get_or_null(link_set, elm);
255       
256       xbt_assert1(link, "Link %s undefined", elm);
257       xbt_assert1(trace, "Trace %s undefined", trace_name);
258       
259       link->state_event = tmgr_history_add_trace(history, trace, 0.0, 0, link);
260    }
261
262    xbt_dict_foreach(trace_connect_list_bandwidth, cursor, trace_name, elm) {
263       tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
264       link_CM02_t link = xbt_dict_get_or_null(link_set, elm);
265       
266       xbt_assert1(link, "Link %s undefined", elm);
267       xbt_assert1(trace, "Trace %s undefined", trace_name);
268       
269       link->bw_event = tmgr_history_add_trace(history, trace, 0.0, 0, link);
270    }
271    
272    xbt_dict_foreach(trace_connect_list_latency, cursor, trace_name, elm) {
273       tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
274       link_CM02_t link = xbt_dict_get_or_null(link_set, elm);
275       
276       xbt_assert1(link, "Link %s undefined", elm);
277       xbt_assert1(trace, "Trace %s undefined", trace_name);
278       
279       link->lat_event = tmgr_history_add_trace(history, trace, 0.0, 0, link);
280    }
281 }
282
283 static void define_callbacks(const char *file)
284 {
285   /* Figuring out the network links */
286   surfxml_add_callback(STag_surfxml_host_cb_list, &count_hosts);
287   surfxml_add_callback(STag_surfxml_link_cb_list, &parse_link_init);
288   surfxml_add_callback(STag_surfxml_route_cb_list, &parse_route_set_endpoints);
289   surfxml_add_callback(ETag_surfxml_route_cb_list, &parse_route_set_route);
290   surfxml_add_callback(ETag_surfxml_platform_cb_list, &add_traces);
291   surfxml_add_callback(ETag_surfxml_platform_cb_list, &add_route);
292   surfxml_add_callback(ETag_surfxml_platform_cb_list, &add_loopback);
293 }
294
295 static void *name_service(const char *name)
296 {
297   network_card_CM02_t card = xbt_dict_get_or_null(network_card_set, name);
298   return card;
299 }
300
301 static const char *get_resource_name(void *resource_id)
302 {
303   return ((network_card_CM02_t) resource_id)->name;
304 }
305
306 static int resource_used(void *resource_id)
307 {
308   return lmm_constraint_used(network_maxmin_system,
309                              ((link_CM02_t) resource_id)->
310                              constraint);
311 }
312
313 static int action_free(surf_action_t action)
314 {
315   action->refcount --;
316   if (!action->refcount ) {
317     xbt_swag_remove(action, action->state_set);
318     if (((surf_action_network_CM02_t) action)->variable)
319       lmm_variable_free(network_maxmin_system,
320                         ((surf_action_network_CM02_t) action)->variable);
321     free(action);
322     return 1;
323   }
324   return 0;
325 }
326
327 static void action_use(surf_action_t action)
328 {
329   action->refcount ++;
330 }
331
332 static void action_cancel(surf_action_t action)
333 {
334   return;
335 }
336
337 static void action_recycle(surf_action_t action)
338 {
339   return;
340 }
341
342 static void action_change_state(surf_action_t action,
343                                 e_surf_action_state_t state)
344 {
345 /*   if((state==SURF_ACTION_DONE) || (state==SURF_ACTION_FAILED)) */
346 /*     if(((surf_action_network_CM02_t)action)->variable) { */
347 /*       lmm_variable_disable(network_maxmin_system, ((surf_action_network_CM02_t)action)->variable); */
348 /*       ((surf_action_network_CM02_t)action)->variable = NULL; */
349 /*     } */
350
351   surf_action_change_state(action, state);
352   return;
353 }
354
355 static double share_resources(double now)
356 {
357   s_surf_action_network_CM02_t s_action;
358   surf_action_network_CM02_t action = NULL;
359   xbt_swag_t running_actions =
360       surf_network_model->common_public->states.running_action_set;
361   double min;
362
363   min = generic_maxmin_share_resources(running_actions,
364                                        xbt_swag_offset(s_action,
365                                                        variable),
366                                        network_maxmin_system,
367                                        network_solve);
368
369 #define VARIABLE(action) (*((lmm_variable_t*)(((char *) (action)) + xbt_swag_offset(s_action, variable)  )))
370   
371   xbt_swag_foreach(action, running_actions) {
372     if (action->latency > 0) {
373       if (min < 0)
374         min = action->latency;
375       else if (action->latency < min)
376         min = action->latency;
377     }
378   }
379
380   return min;
381 }
382
383 static void update_actions_state(double now, double delta)
384 {
385   double deltap = 0.0;
386   surf_action_network_CM02_t action = NULL;
387   surf_action_network_CM02_t next_action = NULL;
388   xbt_swag_t running_actions =
389       surf_network_model->common_public->states.running_action_set;
390   /*
391      xbt_swag_t failed_actions =
392      surf_network_model->common_public->states.failed_action_set;
393    */
394
395   xbt_swag_foreach_safe(action, next_action, running_actions) {
396     deltap = delta;
397     if (action->latency > 0) {
398       if (action->latency > deltap) {
399         double_update(&(action->latency), deltap);
400         deltap = 0.0;
401       } else {
402         double_update(&(deltap), action->latency);
403         action->latency = 0.0;
404       }
405       if ((action->latency == 0.0) && !(action->suspended))
406         lmm_update_variable_weight(network_maxmin_system, action->variable,
407                                    action->weight);
408     }
409     double_update(&(action->generic_action.remains),
410                   lmm_variable_getvalue(action->variable) * deltap);
411     if (action->generic_action.max_duration != NO_MAX_DURATION)
412       double_update(&(action->generic_action.max_duration), delta);
413
414     if ((action->generic_action.remains <= 0) &&
415         (lmm_get_variable_weight(action->variable) > 0)) {
416       action->generic_action.finish = surf_get_clock();
417       action_change_state((surf_action_t) action, SURF_ACTION_DONE);
418     } else if ((action->generic_action.max_duration != NO_MAX_DURATION) &&
419                (action->generic_action.max_duration <= 0)) {
420       action->generic_action.finish = surf_get_clock();
421       action_change_state((surf_action_t) action, SURF_ACTION_DONE);
422     }
423   }
424
425   return;
426 }
427
428 static void update_resource_state(void *id,
429                                   tmgr_trace_event_t event_type,
430                                   double value, double date)
431 {
432   link_CM02_t nw_link = id;
433   /*   printf("[" "%lg" "] Asking to update network card \"%s\" with value " */
434   /*     "%lg" " for event %p\n", surf_get_clock(), nw_link->name, */
435   /*     value, event_type); */
436
437   if (event_type == nw_link->bw_event) {
438     double delta = weight_S_parameter/value - weight_S_parameter/nw_link->bw_current;
439     lmm_variable_t var = NULL;
440     lmm_element_t elem = NULL;
441     surf_action_network_CM02_t action = NULL;
442
443     nw_link->bw_current = value;
444     lmm_update_constraint_bound(network_maxmin_system, nw_link->constraint,
445                                 bandwidth_factor*nw_link->bw_current);
446     if(weight_S_parameter>0) {
447       while ((var= lmm_get_var_from_cnst
448               (network_maxmin_system, nw_link->constraint, &elem))) {
449         action = lmm_variable_id(var);
450         action->weight += delta;
451         if (!(action->suspended))
452           lmm_update_variable_weight(network_maxmin_system, action->variable,
453                                      action->weight);
454       }
455     }
456   } else if (event_type == nw_link->lat_event) {
457     double delta = value - nw_link->lat_current;
458     lmm_variable_t var = NULL;
459     lmm_element_t elem = NULL;
460     surf_action_network_CM02_t action = NULL;
461
462     nw_link->lat_current = value;
463     while ((var= lmm_get_var_from_cnst
464            (network_maxmin_system, nw_link->constraint, &elem))) {
465       action = lmm_variable_id(var);
466       action->lat_current += delta;
467       action->weight += delta;
468       if (action->rate < 0)
469         lmm_update_variable_bound(network_maxmin_system, action->variable,
470                                   SG_TCP_CTE_GAMMA / (2.0 *
471                                                       action->
472                                                       lat_current));
473       else
474         lmm_update_variable_bound(network_maxmin_system, action->variable,
475                                   min(action->rate,
476                                       SG_TCP_CTE_GAMMA / (2.0 *
477                                                           action->
478                                                           lat_current)));
479       if (!(action->suspended))
480         lmm_update_variable_weight(network_maxmin_system, action->variable,
481                                    action->weight);
482
483     }
484   } else if (event_type == nw_link->state_event) {
485     if (value > 0)
486       nw_link->state_current = SURF_LINK_ON;
487     else {
488       lmm_constraint_t cnst = nw_link->constraint;
489       lmm_variable_t var = NULL;
490       lmm_element_t elem = NULL;
491
492       nw_link->state_current = SURF_LINK_OFF;
493       while ((var= lmm_get_var_from_cnst
494               (network_maxmin_system, cnst, &elem))) {
495         surf_action_t action = lmm_variable_id(var) ;
496
497         if(surf_action_get_state(action)==SURF_ACTION_RUNNING ||
498            surf_action_get_state(action)==SURF_ACTION_READY) {
499           action->finish = date;
500           action_change_state( action, SURF_ACTION_FAILED);
501         }
502       }
503     }
504   } else {
505     CRITICAL0("Unknown event ! \n");
506     xbt_abort();
507   }
508
509   return;
510 }
511
512 static surf_action_t communicate(void *src, void *dst, double size,
513                                  double rate)
514 {
515   surf_action_network_CM02_t action = NULL;
516   /* LARGE PLATFORMS HACK:
517      Add a link_CM02_t *link and a int link_nb to network_card_CM02_t. It will represent local links for this node
518      Use the cluster_id for ->id */
519   network_card_CM02_t card_src = src;
520   network_card_CM02_t card_dst = dst;
521   int route_size = ROUTE_SIZE(card_src->id, card_dst->id);
522   link_CM02_t *route = ROUTE(card_src->id, card_dst->id);
523   /* LARGE PLATFORMS HACK:
524      total_route_size = route_size + src->link_nb + dst->nb */
525   int i;
526
527   XBT_IN4("(%s,%s,%g,%g)", card_src->name, card_dst->name, size, rate);
528   /* LARGE PLATFORMS HACK:
529      assert on total_route_size */
530   xbt_assert2(route_size,
531               "You're trying to send data from %s to %s but there is no connexion between these two cards.",
532               card_src->name, card_dst->name);
533
534   action = xbt_new0(s_surf_action_network_CM02_t, 1);
535
536   action->generic_action.refcount  = 1;
537   action->generic_action.cost = size;
538   action->generic_action.remains = size;
539   action->generic_action.max_duration = NO_MAX_DURATION;
540   action->generic_action.start = surf_get_clock();
541   action->generic_action.finish = -1.0;
542   action->generic_action.model_type =
543       (surf_model_t) surf_network_model;
544   action->suspended = 0;        /* Should be useless because of the 
545                                    calloc but it seems to help valgrind... */
546   action->generic_action.state_set =
547       surf_network_model->common_public->states.running_action_set;
548   for (i = 0; i < route_size; i++) 
549     if(route[i]->state_current == SURF_LINK_OFF) {
550       action->generic_action.state_set =
551         surf_network_model->common_public->states.failed_action_set;
552       break;
553     }
554   
555   xbt_swag_insert(action, action->generic_action.state_set);
556   action->rate = rate;
557
558   action->latency = 0.0;
559   action->weight = 0.0;
560   for (i = 0; i < route_size; i++) {
561     action->latency += route[i]->lat_current;
562     action->weight += route[i]->lat_current + weight_S_parameter/route[i]->bw_current;
563   }
564   /* LARGE PLATFORMS HACK:
565      Add src->link and dst->link latencies */
566   action->lat_current = action->latency;
567   action->latency *= latency_factor;
568
569   /* LARGE PLATFORMS HACK:
570      lmm_variable_new(..., total_route_size)*/
571   if (action->latency > 0)
572     action->variable =
573         lmm_variable_new(network_maxmin_system, action, 0.0, -1.0,
574                          route_size);
575   else
576     action->variable =
577         lmm_variable_new(network_maxmin_system, action, 1.0, -1.0,
578                          route_size);
579
580   if (action->rate < 0) {
581     if (action->lat_current > 0)
582       lmm_update_variable_bound(network_maxmin_system, action->variable,
583                                 SG_TCP_CTE_GAMMA / (2.0 *
584                                                     action->lat_current));
585     else
586       lmm_update_variable_bound(network_maxmin_system, action->variable,
587                                 -1.0);
588   } else {
589     if (action->lat_current > 0)
590       lmm_update_variable_bound(network_maxmin_system, action->variable,
591                                 min(action->rate,
592                                     SG_TCP_CTE_GAMMA / (2.0 *
593                                                         action->
594                                                         lat_current)));
595     else
596       lmm_update_variable_bound(network_maxmin_system, action->variable,
597                                 action->rate);
598   }
599
600   for (i = 0; i < route_size; i++)
601     lmm_expand(network_maxmin_system, route[i]->constraint,
602                action->variable, 1.0);
603   /* LARGE PLATFORMS HACK:
604      expand also with src->link and dst->link */
605
606   XBT_OUT;
607
608   return (surf_action_t) action;
609 }
610
611 /* returns an array of link_CM02_t */
612 static const void **get_route(void *src, void *dst)
613 {
614   network_card_CM02_t card_src = src;
615   network_card_CM02_t card_dst = dst;
616   return (const void **) ROUTE(card_src->id, card_dst->id);
617 }
618
619 static int get_route_size(void *src, void *dst)
620 {
621   network_card_CM02_t card_src = src;
622   network_card_CM02_t card_dst = dst;
623   return ROUTE_SIZE(card_src->id, card_dst->id);
624 }
625
626 static const char *get_link_name(const void *link)
627 {
628   return ((link_CM02_t) link)->name;
629 }
630
631 static double get_link_bandwidth(const void *link)
632 {
633   return ((link_CM02_t) link)->bw_current;
634 }
635
636 static double get_link_latency(const void *link)
637 {
638   return ((link_CM02_t) link)->lat_current;
639 }
640
641 static int link_shared(const void *link)
642 {
643   return lmm_constraint_is_shared(((link_CM02_t) link)->constraint);
644 }
645
646 static xbt_dict_t get_properties(void *link)
647 {
648  return ((link_CM02_t) link)->properties;
649 }
650
651 static void action_suspend(surf_action_t action)
652 {
653   ((surf_action_network_CM02_t) action)->suspended = 1;
654   lmm_update_variable_weight(network_maxmin_system,
655                              ((surf_action_network_CM02_t) action)->
656                              variable, 0.0);
657 }
658
659 static void action_resume(surf_action_t action)
660 {
661   if (((surf_action_network_CM02_t) action)->suspended) {
662     lmm_update_variable_weight(network_maxmin_system,
663                                ((surf_action_network_CM02_t) action)->
664                                variable,
665                                ((surf_action_network_CM02_t) action)->
666                                weight);
667     ((surf_action_network_CM02_t) action)->suspended = 0;
668   }
669 }
670
671 static int action_is_suspended(surf_action_t action)
672 {
673   return ((surf_action_network_CM02_t) action)->suspended;
674 }
675
676 static void action_set_max_duration(surf_action_t action, double duration)
677 {
678   action->max_duration = duration;
679 }
680
681 static void finalize(void)
682 {
683   int i, j;
684
685   xbt_dict_free(&network_card_set);
686   xbt_dict_free(&link_set);
687   xbt_swag_free(surf_network_model->common_public->states.
688                 ready_action_set);
689   xbt_swag_free(surf_network_model->common_public->states.
690                 running_action_set);
691   xbt_swag_free(surf_network_model->common_public->states.
692                 failed_action_set);
693   xbt_swag_free(surf_network_model->common_public->states.
694                 done_action_set);
695   free(surf_network_model->common_public);
696   free(surf_network_model->common_private);
697   free(surf_network_model->extension_public);
698
699   free(surf_network_model);
700   surf_network_model = NULL;
701
702   loopback = NULL;
703   for (i = 0; i < host_number; i++)
704     for (j = 0; j < host_number; j++)
705       free(ROUTE(i, j));
706   free(routing_table);
707   routing_table = NULL;
708   free(routing_table_size);
709   routing_table_size = NULL;
710   host_number = 0;
711   lmm_system_free(network_maxmin_system);
712   network_maxmin_system = NULL;
713 }
714
715 static void surf_network_model_init_internal(void)
716 {
717   s_surf_action_t action;
718
719   surf_network_model = xbt_new0(s_surf_network_model_t, 1);
720
721   surf_network_model->common_private =
722       xbt_new0(s_surf_model_private_t, 1);
723   surf_network_model->common_public =
724       xbt_new0(s_surf_model_public_t, 1);
725   surf_network_model->extension_public =
726       xbt_new0(s_surf_network_model_extension_public_t, 1);
727
728   surf_network_model->common_public->states.ready_action_set =
729       xbt_swag_new(xbt_swag_offset(action, state_hookup));
730   surf_network_model->common_public->states.running_action_set =
731       xbt_swag_new(xbt_swag_offset(action, state_hookup));
732   surf_network_model->common_public->states.failed_action_set =
733       xbt_swag_new(xbt_swag_offset(action, state_hookup));
734   surf_network_model->common_public->states.done_action_set =
735       xbt_swag_new(xbt_swag_offset(action, state_hookup));
736
737   surf_network_model->common_public->name_service = name_service;
738   surf_network_model->common_public->get_resource_name =
739       get_resource_name;
740   surf_network_model->common_public->action_get_state =
741       surf_action_get_state;
742   surf_network_model->common_public->action_get_start_time =
743       surf_action_get_start_time;
744   surf_network_model->common_public->action_get_finish_time =
745       surf_action_get_finish_time;
746   surf_network_model->common_public->action_free = action_free;
747   surf_network_model->common_public->action_use = action_use;
748   surf_network_model->common_public->action_cancel = action_cancel;
749   surf_network_model->common_public->action_recycle = action_recycle;
750   surf_network_model->common_public->action_change_state =
751       action_change_state;
752   surf_network_model->common_public->action_set_data =
753       surf_action_set_data;
754   surf_network_model->common_public->name = "network";
755
756   surf_network_model->common_private->resource_used = resource_used;
757   surf_network_model->common_private->share_resources = share_resources;
758   surf_network_model->common_private->update_actions_state =
759       update_actions_state;
760   surf_network_model->common_private->update_resource_state =
761       update_resource_state;
762   surf_network_model->common_private->finalize = finalize;
763
764   surf_network_model->common_public->suspend = action_suspend;
765   surf_network_model->common_public->resume = action_resume;
766   surf_network_model->common_public->is_suspended = action_is_suspended;
767   surf_cpu_model->common_public->set_max_duration =
768       action_set_max_duration;
769
770   surf_network_model->extension_public->communicate = communicate;
771   surf_network_model->extension_public->get_route = get_route;
772   surf_network_model->extension_public->get_route_size = get_route_size;
773   surf_network_model->extension_public->get_link_name = get_link_name;
774   surf_network_model->extension_public->get_link_bandwidth =
775       get_link_bandwidth;
776   surf_network_model->extension_public->get_link_latency =
777       get_link_latency;
778   surf_network_model->extension_public->link_shared =
779       link_shared;
780
781   surf_network_model->common_public->get_properties =  get_properties;
782
783   link_set = xbt_dict_new();
784   network_card_set = xbt_dict_new();
785
786   if (!network_maxmin_system)
787     network_maxmin_system = lmm_system_new();
788 }
789
790 /************************************************************************/
791 /* New model based on optimizations discussed during this thesis        */
792 /************************************************************************/
793 void surf_network_model_init_LegrandVelho(const char *filename)
794 {
795
796   if (surf_network_model)
797     return;
798   surf_network_model_init_internal();
799   define_callbacks(filename);
800   xbt_dynar_push(model_list, &surf_network_model);
801   network_solve = lmm_solve;
802
803   latency_factor = 10.4;
804   bandwidth_factor = 0.92;
805   weight_S_parameter = 8775;
806
807   update_model_description(surf_network_model_description,
808                            "LegrandVelho",
809                            (surf_model_t) surf_network_model);
810 }
811
812 /***************************************************************************/
813 /* The nice TCP sharing model designed by Loris Marchal and Henri Casanova */
814 /***************************************************************************/
815 /* @TechReport{      rr-lip2002-40, */
816 /*   author        = {Henri Casanova and Loris Marchal}, */
817 /*   institution   = {LIP}, */
818 /*   title         = {A Network Model for Simulation of Grid Application}, */
819 /*   number        = {2002-40}, */
820 /*   month         = {oct}, */
821 /*   year          = {2002} */
822 /* } */
823 void surf_network_model_init_CM02(const char *filename)
824 {
825
826   if (surf_network_model)
827     return;
828   surf_network_model_init_internal();
829   define_callbacks(filename);
830   xbt_dynar_push(model_list, &surf_network_model);
831   network_solve = lmm_solve;
832
833   update_model_description(surf_network_model_description,
834                            "CM02",
835                            (surf_model_t) surf_network_model);
836 }
837
838 void surf_network_model_init_Reno(const char *filename)
839 {
840   if (surf_network_model)
841     return;
842   surf_network_model_init_internal();
843   define_callbacks(filename);
844
845   xbt_dynar_push(model_list, &surf_network_model);
846   lmm_set_default_protocol_function(func_reno_f, func_reno_fp,
847                                     func_reno_fpi);
848   network_solve = lagrange_solve;
849
850   update_model_description(surf_network_model_description,
851                            "Reno",
852                            (surf_model_t) surf_network_model);
853 }
854
855
856 void surf_network_model_init_Reno2(const char *filename)
857 {
858   if (surf_network_model)
859     return;
860   surf_network_model_init_internal();
861   define_callbacks(filename);
862
863   xbt_dynar_push(model_list, &surf_network_model);
864   lmm_set_default_protocol_function(func_reno2_f, func_reno2_fp,
865                                     func_reno2_fpi);
866   network_solve = lagrange_solve;
867
868   update_model_description(surf_network_model_description,
869                            "Reno2",
870                            (surf_model_t) surf_network_model);
871 }
872
873 void surf_network_model_init_Vegas(const char *filename)
874 {
875   if (surf_network_model)
876     return;
877   surf_network_model_init_internal();
878   define_callbacks(filename);
879
880   xbt_dynar_push(model_list, &surf_network_model);
881   lmm_set_default_protocol_function(func_vegas_f, func_vegas_fp,
882                                     func_vegas_fpi);
883   network_solve = lagrange_solve;
884
885   update_model_description(surf_network_model_description,
886                            "Vegas",
887                            (surf_model_t) surf_network_model);
888 }
889
890 #ifdef HAVE_SDP
891  void surf_network_model_init_SDP(const char *filename)
892 {
893   if (surf_network_model)
894     return;
895   surf_network_model_init_internal();
896   define_callbacks(filename);
897
898   xbt_dynar_push(model_list, &surf_network_model);
899   network_solve = sdp_solve;
900
901   update_model_description(surf_network_model_description,
902                            "SDP",
903                            (surf_model_t) surf_network_model);
904 }
905 #endif