Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
0fbcc94e8d72048337f44418f44d2487a3ba2ae4
[simgrid.git] / src / surf / surf_routing_generic.c
1 /* Copyright (c) 2009, 2010, 2011. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include <pcre.h>               /* regular expression library */
8
9 #include "simgrid/platf_interface.h"    // platform creation API internal interface
10
11 #include "surf_routing_private.h"
12 #include "surf/surf_routing.h"
13 #include "surf/surfxml_parse_values.h"
14
15 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_routing_generic, surf_route, "Generic implementation of the surf routing");
16
17 static int no_bypassroute_declared = 1;
18
19 AS_t model_generic_create_sized(size_t childsize) {
20   AS_t new_component = model_none_create_sized(childsize);
21
22   new_component->parse_PU = generic_parse_PU;
23   new_component->parse_AS = generic_parse_AS;
24   new_component->parse_route = NULL;
25   new_component->parse_ASroute = NULL;
26   new_component->parse_bypassroute = generic_parse_bypassroute;
27   new_component->get_route_and_latency = NULL;
28   new_component->get_onelink_routes = NULL;
29   new_component->get_bypass_route =
30       generic_get_bypassroute;
31   new_component->finalize = model_generic_finalize;
32   new_component->bypassRoutes = xbt_dict_new_homogeneous((void (*)(void *)) generic_free_route);
33
34   return new_component;
35 }
36 void model_generic_finalize(AS_t as) {
37   xbt_dict_free(&as->bypassRoutes);
38   model_none_finalize(as);
39 }
40
41 int generic_parse_PU(AS_t as, network_element_t elm)
42 {
43   XBT_DEBUG("Load process unit \"%s\"", elm->name);
44   xbt_dynar_push_as(as->index_network_elm,network_element_t,elm);
45   return xbt_dynar_length(as->index_network_elm)-1;
46 }
47
48 int generic_parse_AS(AS_t as, network_element_t elm)
49 {
50   XBT_DEBUG("Load Autonomous system \"%s\"", elm->name);
51   xbt_dynar_push_as(as->index_network_elm,network_element_t,elm);
52   return xbt_dynar_length(as->index_network_elm)-1;
53 }
54
55 void generic_parse_bypassroute(AS_t rc,
56                              const char *src, const char *dst,
57                              route_t e_route)
58 {
59   if(e_route->dst_gateway)
60     XBT_INFO("Load bypassASroute from \"%s\" to \"%s\"", src, dst);
61   else
62     XBT_INFO("Load bypassRoute from \"%s\" to \"%s\"", src, dst);
63   xbt_dict_t dict_bypassRoutes = rc->bypassRoutes;
64   char *route_name;
65
66   route_name = bprintf("%s#%s", src, dst);
67   xbt_assert(!xbt_dynar_is_empty(e_route->link_list),
68              "Invalid count of links, must be greater than zero (%s,%s)",
69              src, dst);
70   xbt_assert(!xbt_dict_get_or_null(dict_bypassRoutes, route_name),
71              "The bypass route between \"%s\"(\"%s\") and \"%s\"(\"%s\") already exists",
72              src, e_route->src_gateway->name, dst, e_route->dst_gateway->name);
73
74   route_t new_e_route = NULL;
75   if(e_route->dst_gateway)
76     new_e_route =  generic_new_extended_route(SURF_ROUTING_RECURSIVE, e_route, 1);
77   else
78     new_e_route =  generic_new_route(SURF_ROUTING_BASE, e_route, 1);
79
80   xbt_dynar_free(&(e_route->link_list));
81   xbt_free(e_route);
82
83   xbt_dict_set(dict_bypassRoutes, route_name, new_e_route, NULL);
84   no_bypassroute_declared = 0;
85   xbt_free(route_name);
86 }
87
88 /* ************************************************************************** */
89 /* *********************** GENERIC BUSINESS METHODS ************************* */
90
91 xbt_dynar_t generic_get_onelink_routes(AS_t rc) { // FIXME: kill that stub
92   xbt_die("\"generic_get_onelink_routes\" not implemented yet");
93   return NULL;
94 }
95
96 route_t generic_get_bypassroute(AS_t rc, network_element_t src, network_element_t dst, double *lat)
97 {
98   // If never set a bypass route return NULL without any further computations
99   XBT_DEBUG("generic_get_bypassroute from %s to %s",src->name,dst->name);
100   if(no_bypassroute_declared)
101     return NULL;
102
103   xbt_dict_t dict_bypassRoutes = rc->bypassRoutes;
104
105   if (src == NULL || dst == NULL)
106     xbt_die("Ask for route \"from\"(%s) or \"to\"(%s) no found at AS \"%s\"",
107             src->name, dst->name, rc->name);
108
109   char *route_name = bprintf("%s#%s", src->name, dst->name);
110   route_t e_route_bypass = xbt_dict_get_or_null(dict_bypassRoutes, route_name);
111   if(e_route_bypass)
112     XBT_DEBUG("Find bypass route with %ld links",xbt_dynar_length(e_route_bypass->link_list));
113   free(route_name);
114
115   route_t new_e_route = NULL;
116   if (e_route_bypass) {
117     void *link;
118     unsigned int cpt = 0;
119     new_e_route = xbt_new0(s_route_t, 1);
120     new_e_route->src_gateway = e_route_bypass->src_gateway;
121     new_e_route->dst_gateway = e_route_bypass->dst_gateway;
122     new_e_route->link_list =
123         xbt_dynar_new(global_routing->size_of_link, NULL);
124     xbt_dynar_foreach(e_route_bypass->link_list, cpt, link) {
125       xbt_dynar_push(new_e_route->link_list, &link);
126       if (lat)
127         *lat += surf_network_model->extension.network.get_link_latency(link);
128     }
129   }
130
131   return new_e_route;
132 }
133
134 /* ************************************************************************** */
135 /* ************************* GENERIC AUX FUNCTIONS ************************** */
136
137 route_t
138 generic_new_route(e_surf_routing_hierarchy_t hierarchy, void *data, int order)
139 {
140
141   char *link_name;
142   route_t new_route;
143   unsigned int cpt;
144   xbt_dynar_t links = NULL, links_id = NULL;
145
146   new_route = xbt_new0(s_route_t, 1);
147   new_route->link_list = xbt_dynar_new(global_routing->size_of_link, NULL);
148
149   xbt_assert(hierarchy == SURF_ROUTING_BASE,
150              "the hierarchy type is not SURF_ROUTING_BASE");
151
152   links = ((route_t) data)->link_list;
153
154
155   links_id = new_route->link_list;
156
157   xbt_dynar_foreach(links, cpt, link_name) {
158
159     void *link = xbt_lib_get_or_null(link_lib, link_name, SURF_LINK_LEVEL);
160     if (link) {
161       if (order)
162         xbt_dynar_push(links_id, &link);
163       else
164         xbt_dynar_unshift(links_id, &link);
165     } else
166       THROWF(mismatch_error, 0, "Link %s not found", link_name);
167   }
168
169   return new_route;
170 }
171
172 route_t
173 generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy,
174                            void *data, int order)
175 {
176
177   char *link_name;
178   route_t e_route, new_e_route;
179   route_t route;
180   unsigned int cpt;
181   xbt_dynar_t links = NULL, links_id = NULL;
182
183   new_e_route = xbt_new0(s_route_t, 1);
184   new_e_route->link_list = xbt_dynar_new(global_routing->size_of_link, NULL);
185
186   xbt_assert(hierarchy == SURF_ROUTING_BASE
187              || hierarchy == SURF_ROUTING_RECURSIVE,
188              "the hierarchy type is not defined");
189
190   if (hierarchy == SURF_ROUTING_BASE) {
191
192     route = (route_t) data;
193     links = route->link_list;
194
195   } else if (hierarchy == SURF_ROUTING_RECURSIVE) {
196
197     e_route = (route_t) data;
198     xbt_assert(e_route->src_gateway
199                && e_route->dst_gateway, "bad gateway, is null");
200     links = e_route->link_list;
201
202     /* remeber not erase the gateway names */
203     new_e_route->src_gateway = e_route->src_gateway;
204     new_e_route->dst_gateway = e_route->dst_gateway;
205   }
206
207   links_id = new_e_route->link_list;
208
209   xbt_dynar_foreach(links, cpt, link_name) {
210
211     void *link = xbt_lib_get_or_null(link_lib, link_name, SURF_LINK_LEVEL);
212     if (link) {
213       if (order)
214         xbt_dynar_push(links_id, &link);
215       else
216         xbt_dynar_unshift(links_id, &link);
217     } else
218       THROWF(mismatch_error, 0, "Link %s not found", link_name);
219   }
220
221   return new_e_route;
222 }
223
224 void generic_free_route(route_t route)
225 {
226   if (route) {
227     xbt_dynar_free(&route->link_list);
228     xbt_free(route);
229   }
230 }
231
232 static AS_t generic_as_exist(AS_t find_from,
233                                             AS_t to_find)
234 {
235   //return to_find; // FIXME: BYPASSERROR OF FOREACH WITH BREAK
236   xbt_dict_cursor_t cursor = NULL;
237   char *key;
238   int found = 0;
239   AS_t elem;
240   xbt_dict_foreach(find_from->routing_sons, cursor, key, elem) {
241     if (to_find == elem || generic_as_exist(elem, to_find)) {
242       found = 1;
243       break;
244     }
245   }
246   if (found)
247     return to_find;
248   return NULL;
249 }
250
251 AS_t
252 generic_autonomous_system_exist(AS_t rc, char *element)
253 {
254   //return rc; // FIXME: BYPASSERROR OF FOREACH WITH BREAK
255   AS_t element_as, result, elem;
256   xbt_dict_cursor_t cursor = NULL;
257   char *key;
258   element_as = ((network_element_t)
259                 xbt_lib_get_or_null(as_router_lib, element,
260                                     ROUTING_ASR_LEVEL))->rc_component;
261   result = ((AS_t) - 1);
262   if (element_as != rc)
263     result = generic_as_exist(rc, element_as);
264
265   int found = 0;
266   if (result) {
267     xbt_dict_foreach(element_as->routing_sons, cursor, key, elem) {
268       found = !strcmp(elem->name, element);
269       if (found)
270         break;
271     }
272     if (found)
273       return element_as;
274   }
275   return NULL;
276 }
277
278 AS_t
279 generic_processing_units_exist(AS_t rc, char *element)
280 {
281   AS_t element_as;
282   element_as = ((network_element_t)
283                 xbt_lib_get_or_null(host_lib,
284                                     element, ROUTING_HOST_LEVEL))->rc_component;
285   if (element_as == rc)
286     return element_as;
287   return generic_as_exist(rc, element_as);
288 }
289
290 void generic_src_dst_check(AS_t rc, network_element_t src,
291     network_element_t dst)
292 {
293
294   network_element_t src_data = src;
295   network_element_t dst_data = dst;
296
297   if (src_data == NULL || dst_data == NULL)
298     xbt_die("Ask for route \"from\"(%s) or \"to\"(%s) no found at AS \"%s\"",
299         src->name,
300         dst->name,
301         rc->name);
302
303   AS_t src_as =
304       (src_data)->rc_component;
305   AS_t dst_as =
306       (dst_data)->rc_component;
307
308   if (src_as != dst_as)
309     xbt_die("The src(%s in %s) and dst(%s in %s) are in differents AS",
310         src->name, src_as->name,
311         dst->name, dst_as->name);
312
313   if (rc != dst_as)
314     xbt_die
315         ("The routing component of src'%s' and dst'%s' is not the same as the network elements belong (%s?=%s?=%s)",
316             src->name,
317             dst->name,
318             src_as->name,
319             dst_as->name,
320             rc->name);
321 }