1 /* Copyright (c) 2009, 2010, 2011. The SimGrid Team.
2 * All rights reserved. */
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. */
7 #include <pcre.h> /* regular expression library */
9 #include "simgrid/platf_interface.h" // platform creation API internal interface
11 #include "surf_routing_private.h"
12 #include "surf/surf_routing.h"
13 #include "surf/surfxml_parse_values.h"
15 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_routing_generic, surf_route, "Generic implementation of the surf routing");
17 static int no_bypassroute_declared = 1;
19 AS_t model_generic_create_sized(size_t childsize) {
20 AS_t new_component = model_none_create_sized(childsize);
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);
34 new_component->index_network_elm = xbt_dynar_new(sizeof(char*),NULL);
37 void model_generic_finalize(AS_t as) {
38 xbt_dict_free(&as->bypassRoutes);
39 model_none_finalize(as);
42 int generic_parse_PU(AS_t as, network_element_t elm)
44 XBT_DEBUG("Load process unit \"%s\"", elm->name);
45 xbt_dynar_push(as->index_network_elm, elm);
46 return xbt_dynar_length(as->index_network_elm)-1;
49 int generic_parse_AS(AS_t as, network_element_t elm)
51 XBT_DEBUG("Load Autonomous system \"%s\"", elm->name);
52 xbt_dynar_push(as->index_network_elm, elm);
53 return xbt_dynar_length(as->index_network_elm)-1;
56 void generic_parse_bypassroute(AS_t rc,
57 const char *src, const char *dst,
60 XBT_DEBUG("Load bypassRoute from \"%s\" to \"%s\"", src, dst);
61 xbt_dict_t dict_bypassRoutes = rc->bypassRoutes;
64 route_name = bprintf("%s#%s", src, dst);
65 xbt_assert(!xbt_dynar_is_empty(e_route->link_list),
66 "Invalid count of links, must be greater than zero (%s,%s)",
68 xbt_assert(!xbt_dict_get_or_null(dict_bypassRoutes, route_name),
69 "The bypass route between \"%s\"(\"%s\") and \"%s\"(\"%s\") already exists",
70 src, e_route->src_gateway->name, dst, e_route->dst_gateway->name);
73 generic_new_extended_route(SURF_ROUTING_RECURSIVE, e_route, 0);
74 xbt_dynar_free(&(e_route->link_list));
77 xbt_dict_set(dict_bypassRoutes, route_name, new_e_route, NULL);
78 no_bypassroute_declared = 0;
82 /* ************************************************************************** */
83 /* *********************** GENERIC BUSINESS METHODS ************************* */
85 xbt_dynar_t generic_get_onelink_routes(AS_t rc) { // FIXME: kill that stub
86 xbt_die("\"generic_get_onelink_routes\" not implemented yet");
90 route_t generic_get_bypassroute(AS_t rc, network_element_t src, network_element_t dst)
92 // If never set a bypass route return NULL without any further computations
93 if(no_bypassroute_declared)
96 xbt_dict_t dict_bypassRoutes = rc->bypassRoutes;
98 int index_src, index_dst;
99 xbt_dynar_t path_src = NULL;
100 xbt_dynar_t path_dst = NULL;
102 AS_t *current_src = NULL;
103 AS_t *current_dst = NULL;
105 char* src_name = src->name;
106 char* dst_name = dst->name;
108 if (src == NULL || dst == NULL)
109 xbt_die("Ask for route \"from\"(%s) or \"to\"(%s) no found at AS \"%s\"",
110 src_name, dst_name, rc->name);
112 src_as = src->rc_component;
113 dst_as = dst->rc_component;
115 /* (2) find the path to the root routing component */
116 path_src = xbt_dynar_new(sizeof(AS_t), NULL);
118 while (current != NULL) {
119 xbt_dynar_push(path_src, ¤t);
120 current = current->routing_father;
122 path_dst = xbt_dynar_new(sizeof(AS_t), NULL);
124 while (current != NULL) {
125 xbt_dynar_push(path_dst, ¤t);
126 current = current->routing_father;
129 /* (3) find the common father */
130 index_src = path_src->used - 1;
131 index_dst = path_dst->used - 1;
132 current_src = xbt_dynar_get_ptr(path_src, index_src);
133 current_dst = xbt_dynar_get_ptr(path_dst, index_dst);
134 while (index_src >= 0 && index_dst >= 0 && *current_src == *current_dst) {
135 xbt_dynar_pop_ptr(path_src);
136 xbt_dynar_pop_ptr(path_dst);
139 current_src = xbt_dynar_get_ptr(path_src, index_src);
140 current_dst = xbt_dynar_get_ptr(path_dst, index_dst);
143 int max_index_src = path_src->used - 1;
144 int max_index_dst = path_dst->used - 1;
146 int max_index = max(max_index_src, max_index_dst);
149 route_t e_route_bypass = NULL;
151 for (max = 0; max <= max_index; max++) {
152 for (i = 0; i < max; i++) {
153 if (i <= max_index_src && max <= max_index_dst) {
154 char *route_name = bprintf("%s#%s",
156 (xbt_dynar_get_ptr(path_src, i)))->name,
158 (xbt_dynar_get_ptr(path_dst, max)))->name);
159 e_route_bypass = xbt_dict_get_or_null(dict_bypassRoutes, route_name);
160 xbt_free(route_name);
164 if (max <= max_index_src && i <= max_index_dst) {
165 char *route_name = bprintf("%s#%s",
167 (xbt_dynar_get_ptr(path_src, max)))->name,
169 (xbt_dynar_get_ptr(path_dst, i)))->name);
170 e_route_bypass = xbt_dict_get_or_null(dict_bypassRoutes, route_name);
171 xbt_free(route_name);
180 if (max <= max_index_src && max <= max_index_dst) {
181 char *route_name = bprintf("%s#%s",
183 (xbt_dynar_get_ptr(path_src, max)))->name,
185 (xbt_dynar_get_ptr(path_dst, max)))->name);
186 e_route_bypass = xbt_dict_get_or_null(dict_bypassRoutes, route_name);
187 xbt_free(route_name);
193 xbt_dynar_free(&path_src);
194 xbt_dynar_free(&path_dst);
196 route_t new_e_route = NULL;
198 if (e_route_bypass) {
200 unsigned int cpt = 0;
201 new_e_route = xbt_new0(s_route_t, 1);
202 new_e_route->src_gateway = e_route_bypass->src_gateway;
203 new_e_route->dst_gateway = e_route_bypass->dst_gateway;
204 new_e_route->link_list =
205 xbt_dynar_new(global_routing->size_of_link, NULL);
206 xbt_dynar_foreach(e_route_bypass->link_list, cpt, link) {
207 xbt_dynar_push(new_e_route->link_list, &link);
214 /* ************************************************************************** */
215 /* ************************* GENERIC AUX FUNCTIONS ************************** */
218 generic_new_route(e_surf_routing_hierarchy_t hierarchy, void *data, int order)
224 xbt_dynar_t links = NULL, links_id = NULL;
226 new_route = xbt_new0(s_route_t, 1);
227 new_route->link_list = xbt_dynar_new(global_routing->size_of_link, NULL);
229 xbt_assert(hierarchy == SURF_ROUTING_BASE,
230 "the hierarchy type is not SURF_ROUTING_BASE");
232 links = ((route_t) data)->link_list;
235 links_id = new_route->link_list;
237 xbt_dynar_foreach(links, cpt, link_name) {
239 void *link = xbt_lib_get_or_null(link_lib, link_name, SURF_LINK_LEVEL);
242 xbt_dynar_push(links_id, &link);
244 xbt_dynar_unshift(links_id, &link);
246 THROWF(mismatch_error, 0, "Link %s not found", link_name);
253 generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy,
254 void *data, int order)
258 route_t e_route, new_e_route;
261 xbt_dynar_t links = NULL, links_id = NULL;
263 new_e_route = xbt_new0(s_route_t, 1);
264 new_e_route->link_list = xbt_dynar_new(global_routing->size_of_link, NULL);
266 xbt_assert(hierarchy == SURF_ROUTING_BASE
267 || hierarchy == SURF_ROUTING_RECURSIVE,
268 "the hierarchy type is not defined");
270 if (hierarchy == SURF_ROUTING_BASE) {
272 route = (route_t) data;
273 links = route->link_list;
275 } else if (hierarchy == SURF_ROUTING_RECURSIVE) {
277 e_route = (route_t) data;
278 xbt_assert(e_route->src_gateway
279 && e_route->dst_gateway, "bad gateway, is null");
280 links = e_route->link_list;
282 /* remeber not erase the gateway names */
283 new_e_route->src_gateway = e_route->src_gateway;
284 new_e_route->dst_gateway = e_route->dst_gateway;
287 links_id = new_e_route->link_list;
289 xbt_dynar_foreach(links, cpt, link_name) {
291 void *link = xbt_lib_get_or_null(link_lib, link_name, SURF_LINK_LEVEL);
294 xbt_dynar_push(links_id, &link);
296 xbt_dynar_unshift(links_id, &link);
298 THROWF(mismatch_error, 0, "Link %s not found", link_name);
304 void generic_free_route(route_t route)
307 xbt_dynar_free(&route->link_list);
312 static AS_t generic_as_exist(AS_t find_from,
315 //return to_find; // FIXME: BYPASSERROR OF FOREACH WITH BREAK
316 xbt_dict_cursor_t cursor = NULL;
320 xbt_dict_foreach(find_from->routing_sons, cursor, key, elem) {
321 if (to_find == elem || generic_as_exist(elem, to_find)) {
332 generic_autonomous_system_exist(AS_t rc, char *element)
334 //return rc; // FIXME: BYPASSERROR OF FOREACH WITH BREAK
335 AS_t element_as, result, elem;
336 xbt_dict_cursor_t cursor = NULL;
338 element_as = ((network_element_t)
339 xbt_lib_get_or_null(as_router_lib, element,
340 ROUTING_ASR_LEVEL))->rc_component;
341 result = ((AS_t) - 1);
342 if (element_as != rc)
343 result = generic_as_exist(rc, element_as);
347 xbt_dict_foreach(element_as->routing_sons, cursor, key, elem) {
348 found = !strcmp(elem->name, element);
359 generic_processing_units_exist(AS_t rc, char *element)
362 element_as = ((network_element_t)
363 xbt_lib_get_or_null(host_lib,
364 element, ROUTING_HOST_LEVEL))->rc_component;
365 if (element_as == rc)
367 return generic_as_exist(rc, element_as);
370 void generic_src_dst_check(AS_t rc, network_element_t src,
371 network_element_t dst)
374 network_element_t src_data = src;
375 network_element_t dst_data = dst;
377 if (src_data == NULL || dst_data == NULL)
378 xbt_die("Ask for route \"from\"(%s) or \"to\"(%s) no found at AS \"%s\"",
384 (src_data)->rc_component;
386 (dst_data)->rc_component;
388 if (src_as != dst_as)
389 xbt_die("The src(%s in %s) and dst(%s in %s) are in differents AS",
390 src->name, src_as->name,
391 dst->name, dst_as->name);
395 ("The routing component of src'%s' and dst'%s' is not the same as the network elements belong (%s?=%s?=%s)",