Logo AND Algorithmique Numérique Distribuée

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