Logo AND Algorithmique Numérique Distribuée

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