Logo AND Algorithmique Numérique Distribuée

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