Logo AND Algorithmique Numérique Distribuée

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