Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
move GTNETS initialization to the right place and comply with the new parser
[simgrid.git] / src / surf / network_gtnets.c
1 /*     $Id$     */
2
3 /* Copyright (c) 2005 Henri Casanova. 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_gtnets_private.h"
9 #include "gtnets/gtnets_interface.h"
10 #include "xbt/str.h"
11
12 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network_gtnets, surf,
13                                 "Logging specific to the SURF network module");
14
15 /** QUESTIONS for GTNetS integration
16  **   1. Check that we did the right thing with name_service and get_resource_name
17  **   2. Right now there is no "kill flow" in our GTNetS implementation. Do we
18  **      need to do something about this?
19  **   3. We ignore the fact there is some max_duration on flows (see #2 above)
20  **   4. share_resources() returns a duration, not a date, right?
21  **   5. We don't suppoer "rates"
22  **   6. We don't update "remaining" for ongoing flows. Is it bad?
23  **/
24
25 /* Free memory for a network link */
26 static void link_free(void *nw_link)
27 {
28   free(((network_link_GTNETS_t) nw_link)->name);
29   xbt_dict_free(&(((network_link_GTNETS_t)nw_link)->properties));
30   free(nw_link);
31 }
32
33 /* Instantiate a new network link */
34 /* name: some name for the link, from the XML */
35 /* bw: The bandwidth value            */
36 /* lat: The latency value             */
37 static void link_new(char *name, double bw, double lat, xbt_dict_t props)
38 {
39   static int link_count = -1;
40   network_link_GTNETS_t gtnets_link;
41
42   /* If link already exists, nothing to do (FIXME: check that multiple definition match?) */
43   if (xbt_dict_get_or_null(link_set, name)) {
44     return;
45   }
46
47   /* KF: Increment the link counter for GTNetS */
48   link_count++;
49
50 /*
51   nw_link->model = (surf_model_t) surf_network_model;
52   nw_link->name = name;
53   nw_link->bw_current = bw_initial;
54   if (bw_trace)
55     nw_link->bw_event =
56         tmgr_history_add_trace(history, bw_trace, 0.0, 0, nw_link);
57   nw_link->lat_current = lat_initial;
58   if (lat_trace)
59     nw_link->lat_event =
60         tmgr_history_add_trace(history, lat_trace, 0.0, 0, nw_link);
61   nw_link->state_current = state_initial;
62   if (state_trace)
63     nw_link->state_event =
64         tmgr_history_add_trace(history, state_trace, 0.0, 0, nw_link);
65 */
66
67   /* KF: Add the link to the GTNetS simulation */
68   if (gtnets_add_link(link_count, bw, lat)) {
69     xbt_assert0(0, "Cannot create GTNetS link");
70   }
71
72   /* KF: Insert entry in the dictionary */
73   gtnets_link = xbt_new0(s_network_link_GTNETS_t, 1);
74   gtnets_link->name = name;
75   gtnets_link->bw_current = bw;
76   gtnets_link->lat_current = lat;
77   gtnets_link->id = link_count;
78   /* Add the properties */
79   gtnets_link->properties = props;
80
81   xbt_dict_set(link_set, name, gtnets_link, link_free);
82
83   return;
84 }
85
86 /* free the network card */
87 static void network_card_free(void *nw_card)
88 {
89   free(((network_card_GTNETS_t) nw_card)->name);
90   free(nw_card);
91 }
92
93 /* Instantiate a new network card: MODIFYED BY KF */
94 static int network_card_new(const char *name)
95 {
96   static int card_count = -1;
97
98   /* KF: Check that we haven't seen the network card before */
99   network_card_GTNETS_t card =
100       xbt_dict_get_or_null(network_card_set, name);
101
102   if (!card) {
103     /* KF: Increment the card counter for GTNetS */
104     card_count++;
105
106     /* KF: just use the dictionary to map link names to link indices */
107     card = xbt_new0(s_network_card_GTNETS_t, 1);
108     card->name = xbt_strdup(name);
109     card->id = card_count;
110     xbt_dict_set(network_card_set, name, card, network_card_free);
111   }
112
113   /* KF: just return the GTNetS ID as the SURF ID */
114   return card->id;
115 }
116
117 /* Instantiate a new route: MODIFY BY KF */
118 static void route_new(int src_id, int dst_id, network_link_GTNETS_t *links, int nb_link)
119 {
120   int i;
121   int *gtnets_links;
122
123   /* KF: Build the list of gtnets link IDs */
124   gtnets_links = (int *) calloc(nb_link, sizeof(int));
125   for (i = 0; i < nb_link; i++) {
126     gtnets_links[i] = links[i]->id;
127   }
128
129   /* KF: Create the GTNets route */
130   if (gtnets_add_route(src_id, dst_id, gtnets_links, nb_link)) {
131     xbt_assert0(0, "Cannot create GTNetS route");
132   }
133 }
134
135 /* Instantiate a new route: MODIFY BY KF */
136 static void route_onehop_new(int src_id, int dst_id, network_link_GTNETS_t *links, int nb_link)
137 {
138   int linkid;
139
140   if (nb_link != 1) {
141     xbt_assert0(0, "In onehop_new, nb_link should be 1");
142   }
143
144   /* KF: Build the list of gtnets link IDs */
145   linkid = links[0]->id;
146
147   /* KF: Create the GTNets route */
148   if (gtnets_add_onehop_route(src_id, dst_id, linkid)) {
149     xbt_assert0(0, "Cannot create GTNetS route");
150   }
151 }
152
153
154
155 /* Parse the XML for a network link */
156 static void parse_link_init(void)
157 {
158   char *name;
159   double bw;
160   double lat;
161   e_surf_link_state_t state;
162
163   name = xbt_strdup(A_surfxml_link_id);
164   surf_parse_get_double(&bw, A_surfxml_link_bandwidth);
165   surf_parse_get_double(&lat, A_surfxml_link_latency);
166   state = SURF_LINK_ON;
167
168   tmgr_trace_t bw_trace;
169   tmgr_trace_t state_trace;
170   tmgr_trace_t lat_trace;
171   
172   surf_parse_get_trace(&bw_trace, A_surfxml_link_bandwidth_file);
173   surf_parse_get_trace(&lat_trace, A_surfxml_link_latency_file);
174   surf_parse_get_trace(&state_trace, A_surfxml_link_state_file);
175
176   if (bw_trace)
177     INFO0("The GTNetS network model doesn't support bandwidth state traces");
178   if (lat_trace)
179     INFO0("The GTNetS network model doesn't support latency state traces");
180   if (state_trace)
181     INFO0("The GTNetS network model doesn't support link state traces");
182
183   current_property_set = xbt_dict_new();
184   link_new(name, bw, lat, current_property_set);
185 }
186
187 static int nb_link = 0;
188 static int src_id = -1;
189 static int dst_id = -1;
190
191 /* Parses a route from the XML: UNMODIFIED BY HC */
192 static void parse_route_set_endpoints(void)
193 {
194   src_id = network_card_new(A_surfxml_route_src);
195   dst_id = network_card_new(A_surfxml_route_dst);
196   route_action = A_surfxml_route_action;
197 }
198
199 /* KF*/
200 static void parse_route_set_routers(void)
201 {
202   int id = network_card_new(A_surfxml_router_id);
203
204   /* KF: Create the GTNets router */
205   if (gtnets_add_router(id)) {
206     xbt_assert0(0, "Cannot add GTNetS router");
207   }
208 }
209
210 /* Create the route (more than one hops): MODIFIED BY KF */
211 static void parse_route_set_route(void)
212 {
213   char *name;
214   if (src_id != -1 && dst_id != -1) {
215     name = bprintf("%x#%x",src_id, dst_id);
216     manage_route(route_table, name, route_action, 0);
217     free(name);    
218   }
219 }
220
221 static void add_route()
222 {
223   xbt_ex_t e;
224   unsigned int cpt = 0;    
225   int i = 0;
226   xbt_dict_cursor_t cursor = NULL;
227   char *key,*data, *end;
228   const char *sep = "#";
229   xbt_dynar_t links, keys;
230   static network_link_GTNETS_t *link_list = NULL;
231
232   DEBUG0("Entering add_route()");
233   xbt_dict_foreach(route_table, cursor, key, data) {
234     nb_link = 0;
235     links = (xbt_dynar_t)data;
236     keys = xbt_str_split_str(key, sep);
237
238     nb_link = xbt_dynar_length(links);
239     link_list = xbt_realloc(link_list, (nb_link) * sizeof(network_link_GTNETS_t));
240
241     src_id = strtol(xbt_dynar_get_as(keys, 0, char*), &end, 16);
242     dst_id = strtol(xbt_dynar_get_as(keys, 1, char*), &end, 16);
243   
244     i = 0;
245     char* link = NULL;
246     xbt_dynar_foreach (links, cpt, link) {
247       TRY {
248         link_list[i++] = xbt_dict_get(link_set, link);
249       }
250       CATCH(e) {
251         RETHROW1("Link %s not found (dict raised this exception: %s)", link);
252       }     
253     }
254     if (nb_link > 1)
255       route_new(src_id, dst_id, link_list, nb_link);
256     if (nb_link == 1)
257       route_onehop_new(src_id, dst_id, link_list, nb_link);
258    }
259
260   xbt_dict_free(&route_table);
261   DEBUG0("Bailling add_route()");
262 }
263
264 /* Main XML parsing */
265 static void define_callbacks(const char *file)
266 {
267   surfxml_add_callback(STag_surfxml_router_cb_list,   &parse_route_set_routers);
268   surfxml_add_callback(STag_surfxml_link_cb_list,     &parse_link_init);
269   surfxml_add_callback(STag_surfxml_route_cb_list,    &parse_route_set_endpoints);
270   surfxml_add_callback(ETag_surfxml_route_cb_list,    &parse_route_set_route);
271   surfxml_add_callback(ETag_surfxml_platform_cb_list, &add_route);
272 }
273
274 static void *name_service(const char *name)
275 {
276   return xbt_dict_get_or_null(network_card_set, name);
277 }
278
279 static const char *get_resource_name(void *resource_id)
280 {
281   return ((network_card_GTNETS_t) resource_id)->name;
282 }
283
284 static xbt_dict_t get_properties(void *link)
285 {
286   return ((network_card_GTNETS_t) link)->properties;
287 }
288
289
290 /* We do not care about this: only used for traces */
291 static int resource_used(void *resource_id)
292 {
293   return 0;                     /* We don't care */
294 }
295
296 static int action_free(surf_action_t action)
297 {
298   action->using--;
299   if (!action->using) {
300     xbt_swag_remove(action, action->state_set);
301     /* KF: No explicit freeing needed for GTNeTS here */
302     free(action);
303     return 1;
304   }
305   return 0;
306 }
307
308 static void action_use(surf_action_t action)
309 {
310   action->using++;
311 }
312
313 static void action_cancel(surf_action_t action)
314 {
315   xbt_assert0(0, "Cannot cancel GTNetS flow");
316   return;
317 }
318
319 static void action_recycle(surf_action_t action)
320 {
321   xbt_assert0(0, "Cannot recycle GTNetS flow");
322   return;
323 }
324
325 static void action_change_state(surf_action_t action,
326                                 e_surf_action_state_t state)
327 {
328 /*   if((state==SURF_ACTION_DONE) || (state==SURF_ACTION_FAILED)) */
329 /*     if(((surf_action_network_GTNETS_t)action)->variable) { */
330 /*       lmm_variable_disable(maxmin_system, ((surf_action_network_GTNETS_t)action)->variable); */
331 /*       ((surf_action_network_GTNETS_t)action)->variable = NULL; */
332 /*     } */
333
334   surf_action_change_state(action, state);
335   return;
336 }
337
338
339 /* share_resources() */
340 static double share_resources(double now)
341 {
342   xbt_swag_t running_actions = surf_network_model->common_public->states.running_action_set;
343
344   //get the first relevant value from the running_actions list
345   if (!xbt_swag_size(running_actions))
346     return -1.0;
347
348   return gtnets_get_time_to_next_flow_completion();
349 }
350
351 /* delta: by how many time units the simulation must advance */
352 /* In this function: change the state of actions that terminate */
353 /* The delta may not come from the network, and thus may be different (smaller) 
354    than the one returned by the function above */
355 /* If the delta is a network-caused min, then do not emulate any timer in the
356    network simulation, otherwise fake a timer somehow to advance the simulation of min seconds */
357
358 static void update_actions_state(double now, double delta)
359 {
360   surf_action_network_GTNETS_t action = NULL;
361   //  surf_action_network_GTNETS_t next_action = NULL;
362   xbt_swag_t running_actions =
363       surf_network_model->common_public->states.running_action_set;
364
365   double time_to_next_flow_completion =
366       gtnets_get_time_to_next_flow_completion();
367
368   /* If there are no renning flows, just return */
369   if (time_to_next_flow_completion < 0.0) {
370     return;
371   }
372
373   /*KF: if delta == time_to_next_flow_completion, too. */
374   if (time_to_next_flow_completion <= delta) {  /* run until the first flow completes */
375     void **metadata;
376     int i, num_flows;
377
378     num_flows = 0;
379
380     if (gtnets_run_until_next_flow_completion(&metadata, &num_flows)) {
381       xbt_assert0(0,
382                   "Cannot run GTNetS simulation until next flow completion");
383     }
384     if (num_flows < 1) {
385       xbt_assert0(0,
386                   "GTNetS simulation couldn't find a flow that would complete");
387     }
388
389
390
391     xbt_swag_foreach(action, running_actions) {
392       DEBUG1("]]]]]]]]] Action remains old value: %f", action->generic_action.remains);
393       double remain = gtnets_get_flow_rx(action);
394       //need to trust this remain value
395       if(remain == 0){
396         action->generic_action.remains=0;
397       }else {
398         action->generic_action.remains-=remain;
399       }
400       DEBUG1("[[[[[[[[[ Action remains new value: %f", action->generic_action.remains);
401     }
402
403     for (i = 0; i < num_flows; i++) {
404       action =  (surf_action_network_GTNETS_t) (metadata[i]);
405       
406       action->generic_action.finish = now + time_to_next_flow_completion;
407       action_change_state((surf_action_t) action, SURF_ACTION_DONE);
408       /* TODO: Anything else here? */
409
410       //need to map this action to the gtnets engine
411       DEBUG1("]]]]]]]]] Action remains old value: %f", action->generic_action.remains);
412       action->generic_action.remains -= gtnets_get_flow_rx(metadata[i]);
413       DEBUG1("[[[[[[[[[ Action remains new value: %f", action->generic_action.remains);
414     }
415
416
417   } else {                      /* run for a given number of seconds */
418     if (gtnets_run(delta)) {
419       xbt_assert0(0, "Cannot run GTNetS simulation");
420     }
421   }
422
423   return;
424 }
425
426 /* UNUSED HERE: no traces */
427 static void update_resource_state(void *id,
428                                   tmgr_trace_event_t event_type,
429                                   double value, double date)
430 {
431   xbt_assert0(0, "Cannot update model state for GTNetS simulation");
432   return;
433 }
434
435 /* KF: Rate not supported */
436 static surf_action_t communicate(void *src, void *dst, double size,
437                                  double rate)
438 {
439   surf_action_network_GTNETS_t action = NULL;
440   network_card_GTNETS_t card_src = src;
441   network_card_GTNETS_t card_dst = dst;
442 /*
443   int route_size = ROUTE_SIZE(card_src->id, card_dst->id);
444   network_link_GTNETS_t *route = ROUTE(card_src->id, card_dst->id);
445 */
446
447 /*
448   xbt_assert2(route_size,"You're trying to send data from %s to %s but there is no connexion between these two cards.", card_src->name, card_dst->name);
449 */
450
451   action = xbt_new0(s_surf_action_network_GTNETS_t, 1);
452
453   action->generic_action.using = 1;
454   action->generic_action.cost = size;
455   action->generic_action.remains = size;
456   /* Max durations are not supported */
457   action->generic_action.max_duration = NO_MAX_DURATION;
458   action->generic_action.start = surf_get_clock();
459   action->generic_action.finish = -1.0;
460   action->generic_action.model_type =
461       (surf_model_t) surf_network_model;
462
463   action->generic_action.state_set =
464       surf_network_model->common_public->states.running_action_set;
465
466   xbt_swag_insert(action, action->generic_action.state_set);
467
468   /* KF: Add a flow to the GTNets Simulation, associated to this action */
469   if (gtnets_create_flow(card_src->id, card_dst->id, size, (void *) action)
470       < 0) {
471     xbt_assert2(0, "Not route between host %s and host %s", card_src->name,
472                 card_dst->name);
473   }
474
475   return (surf_action_t) action;
476 }
477
478 /* Suspend a flow() */
479 static void action_suspend(surf_action_t action)
480 {
481   xbt_assert0(0,
482               "action_suspend() not supported for the GTNets network model");
483 }
484
485 /* Resume a flow() */
486 static void action_resume(surf_action_t action)
487 {
488   xbt_assert0(0,
489               "action_resume() not supported for the GTNets network model");
490 }
491
492 /* Test whether a flow is suspended */
493 static int action_is_suspended(surf_action_t action)
494 {
495   return 0;
496 }
497
498 static void finalize(void)
499 {
500 #if 0
501   int i, j;
502 #endif
503   xbt_dict_free(&network_card_set);
504   xbt_dict_free(&link_set);
505   xbt_swag_free(surf_network_model->common_public->states.
506                 ready_action_set);
507   xbt_swag_free(surf_network_model->common_public->states.
508                 running_action_set);
509   xbt_swag_free(surf_network_model->common_public->states.
510                 failed_action_set);
511   xbt_swag_free(surf_network_model->common_public->states.
512                 done_action_set);
513   free(surf_network_model->common_public);
514   free(surf_network_model->common_private);
515   free(surf_network_model->extension_public);
516
517   free(surf_network_model);
518   surf_network_model = NULL;
519
520 #if 0
521   for (i = 0; i < card_number; i++)
522     for (j = 0; j < card_number; j++)
523       free(ROUTE(i, j));
524   free(routing_table);
525   routing_table = NULL;
526   free(routing_table_size);
527   routing_table_size = NULL;
528   card_number = 0;
529 #endif
530
531   /* ADDED BY KF */
532   gtnets_finalize();
533   /* END ADDITION */
534 }
535
536 static void surf_network_model_init_internal(void)
537 {
538   s_surf_action_t action;
539
540   surf_network_model = xbt_new0(s_surf_network_model_t, 1);
541
542   surf_network_model->common_private =
543       xbt_new0(s_surf_model_private_t, 1);
544   surf_network_model->common_public =
545       xbt_new0(s_surf_model_public_t, 1);
546   surf_network_model->extension_public =
547       xbt_new0(s_surf_network_model_extension_public_t, 1);
548
549   surf_network_model->common_public->states.ready_action_set =
550       xbt_swag_new(xbt_swag_offset(action, state_hookup));
551   surf_network_model->common_public->states.running_action_set =
552       xbt_swag_new(xbt_swag_offset(action, state_hookup));
553   surf_network_model->common_public->states.failed_action_set =
554       xbt_swag_new(xbt_swag_offset(action, state_hookup));
555   surf_network_model->common_public->states.done_action_set =
556       xbt_swag_new(xbt_swag_offset(action, state_hookup));
557
558   surf_network_model->common_public->name_service = name_service;
559   surf_network_model->common_public->get_resource_name =
560       get_resource_name;
561   surf_network_model->common_public->action_get_state =
562       surf_action_get_state;
563   surf_network_model->common_public->action_use = action_use;
564   surf_network_model->common_public->action_free = action_free;
565   surf_network_model->common_public->action_cancel = action_cancel;
566   surf_network_model->common_public->action_recycle = action_recycle;
567   surf_network_model->common_public->action_change_state =
568       action_change_state;
569   surf_network_model->common_public->action_set_data =
570       surf_action_set_data;
571   surf_network_model->common_public->name = "network";
572
573   surf_network_model->common_private->resource_used = resource_used;
574   surf_network_model->common_private->share_resources = share_resources;
575   surf_network_model->common_private->update_actions_state =
576       update_actions_state;
577   surf_network_model->common_private->update_resource_state = update_resource_state;
578   surf_network_model->common_private->finalize = finalize;
579
580   surf_network_model->common_public->suspend = action_suspend;
581   surf_network_model->common_public->resume = action_resume;
582   surf_network_model->common_public->is_suspended = action_is_suspended;
583
584   surf_network_model->extension_public->communicate = communicate;
585
586   /*for the props of the link*/
587   surf_network_model->common_public->get_properties =  get_properties;
588
589   link_set = xbt_dict_new();
590   network_card_set = xbt_dict_new();
591
592   /* KF: Added the initialization for GTNetS interface */
593   if (gtnets_initialize()) {
594     xbt_assert0(0, "impossible to initialize GTNetS interface");
595   }
596 }
597
598 #ifdef HAVE_GTNETS
599 void surf_network_model_init_GTNETS(const char *filename)
600 {
601   if (surf_network_model)
602     return;
603   surf_network_model_init_internal();
604   define_callbacks(filename);
605   xbt_dynar_push(model_list, &surf_network_model);
606
607   update_model_description(surf_network_model_description,
608                            "GTNets",
609                            (surf_model_t) surf_network_model);
610 }
611 #endif