Logo AND Algorithmique Numérique Distribuée

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