1 /* Copyright (c) 2009-2011, 2013-2015. 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 "surf_routing.hpp"
8 #include "surf_routing_private.hpp"
9 #include "surf_routing_cluster.hpp"
11 #include "simgrid/platf_interface.h" // platform creation API internal interface
12 #include "simgrid/sg_config.h"
13 #include "storage_interface.hpp"
14 #include "src/surf/platform.hpp"
15 #include "surf/surfxml_parse_values.h"
24 simgrid::xbt::signal<void(simgrid::surf::NetCard*)> netcardCreatedCallbacks;
25 simgrid::xbt::signal<void(simgrid::surf::As*)> asCreatedCallbacks;
31 * @ingroup SURF_build_api
32 * @brief A library containing all known hosts
36 int COORD_HOST_LEVEL=0; //Coordinates level
38 int MSG_FILE_LEVEL; //Msg file level
40 int SIMIX_STORAGE_LEVEL; //Simix storage level
41 int MSG_STORAGE_LEVEL; //Msg storage level
43 xbt_lib_t as_router_lib;
44 int ROUTING_ASR_LEVEL; //Routing level
45 int COORD_ASR_LEVEL; //Coordinates level
46 int NS3_ASR_LEVEL; //host node for ns3
47 int ROUTING_PROP_ASR_LEVEL; //Where the properties are stored
49 /** @brief Retrieve a netcard from its name
51 * Netcards are the thing that connect host or routers to the network
53 simgrid::surf::NetCard *sg_netcard_by_name_or_null(const char *name)
55 sg_host_t h = sg_host_by_name(name);
56 simgrid::surf::NetCard *net_elm = h==NULL?NULL: h->pimpl_netcard;
58 net_elm = (simgrid::surf::NetCard*) xbt_lib_get_or_null(as_router_lib, name, ROUTING_ASR_LEVEL);
63 simgrid::surf::RoutingPlatf *routing_platf = NULL;
65 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route, surf, "Routing part of surf");
67 /** The current AS in the parsing */
68 static simgrid::surf::As *current_routing = NULL;
69 simgrid::surf::As* routing_get_current()
71 return current_routing;
74 /* this lines are only for replace use like index in the model table */
79 SURF_MODEL_DIJKSTRACACHE,
83 SURF_MODEL_TORUS_CLUSTER,
84 SURF_MODEL_FAT_TREE_CLUSTER,
87 struct s_model_type routing_models[] = {
89 "Full routing data (fast, large memory requirements, fully expressive)",
92 "Floyd routing data (slow initialization, fast lookup, lesser memory requirements, shortest path routing only)",
95 "Dijkstra routing data (fast initialization, slow lookup, small memory requirements, shortest path routing only)",
96 model_dijkstra_create},
98 "Dijkstra routing data (fast initialization, fast lookup, small memory requirements, shortest path routing only)",
99 model_dijkstracache_create},
100 {"none", "No routing (Unless you know what you are doing, avoid using this mode in combination with a non Constant network model).",
102 {"Vivaldi", "Vivaldi routing", model_vivaldi_create},
103 {"Cluster", "Cluster routing", model_cluster_create},
104 {"Torus_Cluster", "Torus Cluster routing", model_torus_cluster_create},
105 {"Fat_Tree_Cluster", "Fat Tree Cluster routing", model_fat_tree_cluster_create},
110 * \brief Add a netcard connecting an host to the network element list
111 * FIXME: integrate into host constructor
113 void sg_platf_new_netcard(sg_platf_host_link_cbarg_t netcard)
115 simgrid::surf::NetCard *info = sg_host_by_name(netcard->id)->pimpl_netcard;
116 xbt_assert(info, "Host '%s' not found!", netcard->id);
117 xbt_assert(current_routing->p_modelDesc == &routing_models[SURF_MODEL_CLUSTER] ||
118 current_routing->p_modelDesc == &routing_models[SURF_MODEL_VIVALDI],
119 "You have to be in model Cluster to use tag host_link!");
121 s_surf_parsing_link_up_down_t link_up_down;
122 link_up_down.link_up = Link::byName(netcard->link_up);
123 link_up_down.link_down = Link::byName(netcard->link_down);
125 xbt_assert(link_up_down.link_up, "Link '%s' not found!",netcard->link_up);
126 xbt_assert(link_up_down.link_down, "Link '%s' not found!",netcard->link_down);
128 if(!current_routing->p_linkUpDownList)
129 current_routing->p_linkUpDownList = xbt_dynar_new(sizeof(s_surf_parsing_link_up_down_t),NULL);
131 // If dynar is is greater than netcard id and if the host_link is already defined
132 if((int)xbt_dynar_length(current_routing->p_linkUpDownList) > info->getId() &&
133 xbt_dynar_get_as(current_routing->p_linkUpDownList, info->getId(), void*))
134 surf_parse_error("Host_link for '%s' is already defined!",netcard->id);
136 XBT_DEBUG("Push Host_link for host '%s' to position %d", info->getName(), info->getId());
137 xbt_dynar_set_as(current_routing->p_linkUpDownList, info->getId(), s_surf_parsing_link_up_down_t, link_up_down);
140 void sg_platf_new_trace(sg_platf_trace_cbarg_t trace)
142 tmgr_trace_t tmgr_trace;
143 if (!trace->file || strcmp(trace->file, "") != 0) {
144 tmgr_trace = tmgr_trace_new_from_file(trace->file);
146 xbt_assert(strcmp(trace->pc_data, ""),
147 "Trace '%s' must have either a content, or point to a file on disk.",trace->id);
148 tmgr_trace = tmgr_trace_new_from_string(trace->id, trace->pc_data, trace->periodicity);
150 xbt_dict_set(traces_set_list, trace->id, (void *) tmgr_trace, NULL);
154 * \brief Make a new routing component to the platform
156 * Add a new autonomous system to the platform. Any elements (such as host,
157 * router or sub-AS) added after this call and before the corresponding call
158 * to sg_platf_new_AS_close() will be added to this AS.
160 * Once this function was called, the configuration concerning the used
161 * models cannot be changed anymore.
163 * @param AS_id name of this autonomous system. Must be unique in the platform
164 * @param wanted_routing_type one of Full, Floyd, Dijkstra or similar. Full list in the variable routing_models, in src/surf/surf_routing.c
166 void routing_AS_begin(sg_platf_AS_cbarg_t AS)
168 XBT_DEBUG("routing_AS_begin");
169 routing_model_description_t model = NULL;
171 xbt_assert(!xbt_lib_get_or_null
172 (as_router_lib, AS->id, ROUTING_ASR_LEVEL),
173 "The AS \"%s\" already exists", AS->id);
175 _sg_cfg_init_status = 2; /* horrible hack: direct access to the global
176 * controlling the level of configuration to prevent
177 * any further config */
179 /* search the routing model */
181 case A_surfxml_AS_routing_Cluster: model = &routing_models[SURF_MODEL_CLUSTER];break;
182 case A_surfxml_AS_routing_Cluster___torus: model = &routing_models[SURF_MODEL_TORUS_CLUSTER];break;
183 case A_surfxml_AS_routing_Cluster___fat___tree: model = &routing_models[SURF_MODEL_FAT_TREE_CLUSTER];break;
184 case A_surfxml_AS_routing_Dijkstra: model = &routing_models[SURF_MODEL_DIJKSTRA];break;
185 case A_surfxml_AS_routing_DijkstraCache: model = &routing_models[SURF_MODEL_DIJKSTRACACHE];break;
186 case A_surfxml_AS_routing_Floyd: model = &routing_models[SURF_MODEL_FLOYD];break;
187 case A_surfxml_AS_routing_Full: model = &routing_models[SURF_MODEL_FULL];break;
188 case A_surfxml_AS_routing_None: model = &routing_models[SURF_MODEL_NONE];break;
189 case A_surfxml_AS_routing_Vivaldi: model = &routing_models[SURF_MODEL_VIVALDI];break;
190 default: xbt_die("Not a valid model!!!");
194 /* make a new routing component */
195 simgrid::surf::As *new_as = model->create();
197 new_as->p_modelDesc = model;
198 new_as->p_hierarchy = SURF_ROUTING_NULL;
199 new_as->p_name = xbt_strdup(AS->id);
201 simgrid::surf::NetCard *info =
202 new simgrid::surf::NetCardImpl(xbt_strdup(new_as->p_name),
204 SURF_NETWORK_ELEMENT_AS,
206 if (current_routing == NULL && routing_platf->p_root == NULL) {
208 /* it is the first one */
209 new_as->p_routingFather = NULL;
210 routing_platf->p_root = new_as;
212 } else if (current_routing != NULL && routing_platf->p_root != NULL) {
214 xbt_assert(!xbt_dict_get_or_null
215 (current_routing->p_routingSons, AS->id),
216 "The AS \"%s\" already exists", AS->id);
217 /* it is a part of the tree */
218 new_as->p_routingFather = current_routing;
219 /* set the father behavior */
220 if (current_routing->p_hierarchy == SURF_ROUTING_NULL)
221 current_routing->p_hierarchy = SURF_ROUTING_RECURSIVE;
222 /* add to the sons dictionary */
223 xbt_dict_set(current_routing->p_routingSons, AS->id,
224 (void *) new_as, NULL);
225 /* add to the father element list */
226 info->setId(current_routing->parseAS(info));
228 THROWF(arg_error, 0, "All defined components must belong to a AS");
231 xbt_lib_set(as_router_lib, info->getName(), ROUTING_ASR_LEVEL,
233 XBT_DEBUG("Having set name '%s' id '%d'", new_as->p_name, info->getId());
235 /* set the new current component of the tree */
236 current_routing = new_as;
237 current_routing->p_netcard = info;
239 simgrid::surf::netcardCreatedCallbacks(info);
240 simgrid::surf::asCreatedCallbacks(new_as);
244 * \brief Specify that the current description of AS is finished
246 * Once you've declared all the content of your AS, you have to close
247 * it with this call. Your AS is not usable until you call this function.
249 * @fixme: this call is not as robust as wanted: bad things WILL happen
250 * if you call it twice for the same AS, or if you forget calling it, or
251 * even if you add stuff to a closed AS
254 void routing_AS_end()
257 if (current_routing == NULL) {
258 THROWF(arg_error, 0, "Close an AS, but none was under construction");
260 current_routing->Seal();
261 current_routing = current_routing->p_routingFather;
265 /* Aux Business methods */
268 * \brief Get the AS father and the first elements of the chain
270 * \param src the source host name
271 * \param dst the destination host name
273 * Get the common father of the to processing units, and the first different
274 * father in the chain
276 static void elements_father(sg_netcard_t src, sg_netcard_t dst,
281 xbt_assert(src && dst, "bad parameters for \"elements_father\" method");
282 #define ELEMENTS_FATHER_MAXDEPTH 16 /* increase if it is not enough */
283 simgrid::surf::As *src_as, *dst_as;
284 simgrid::surf::As *path_src[ELEMENTS_FATHER_MAXDEPTH];
285 simgrid::surf::As *path_dst[ELEMENTS_FATHER_MAXDEPTH];
288 simgrid::surf::As *current;
289 simgrid::surf::As *current_src;
290 simgrid::surf::As *current_dst;
291 simgrid::surf::As *father;
293 /* (1) find the as where the src and dst are located */
294 sg_netcard_t src_data = src;
295 sg_netcard_t dst_data = dst;
296 src_as = src_data->getRcComponent();
297 dst_as = dst_data->getRcComponent();
299 char* src_name = src_data->getName();
300 char* dst_name = dst_data->getName();
303 xbt_assert(src_as && dst_as,
304 "Ask for route \"from\"(%s) or \"to\"(%s) no found", src_name, dst_name);
306 /* (2) find the path to the root routing component */
307 for (current = src_as; current != NULL; current = current->p_routingFather) {
308 if (index_src >= ELEMENTS_FATHER_MAXDEPTH)
309 xbt_die("ELEMENTS_FATHER_MAXDEPTH should be increased for path_src");
310 path_src[index_src++] = current;
312 for (current = dst_as; current != NULL; current = current->p_routingFather) {
313 if (index_dst >= ELEMENTS_FATHER_MAXDEPTH)
314 xbt_die("ELEMENTS_FATHER_MAXDEPTH should be increased for path_dst");
315 path_dst[index_dst++] = current;
318 /* (3) find the common father */
320 current_src = path_src[--index_src];
321 current_dst = path_dst[--index_dst];
322 } while (index_src > 0 && index_dst > 0 && current_src == current_dst);
324 /* (4) they are not in the same routing component, make the path */
325 if (current_src == current_dst)
326 father = current_src;
328 father = path_src[index_src + 1];
330 /* (5) result generation */
331 *res_father = father; /* first the common father of src and dst */
332 *res_src = current_src; /* second the first different father of src */
333 *res_dst = current_dst; /* three the first different father of dst */
335 #undef ELEMENTS_FATHER_MAXDEPTH
338 /* Global Business methods */
341 * \brief Recursive function for get_route_latency
343 * \param src the source host name
344 * \param dst the destination host name
345 * \param *route the route where the links are stored. It is either NULL or a ready to use dynar
346 * \param *latency the latency, if needed
348 * This function is called by "get_route" and "get_latency". It allows to walk
349 * recursively through the ASes tree.
351 static void _get_route_and_latency(
352 simgrid::surf::NetCard *src, simgrid::surf::NetCard *dst,
353 xbt_dynar_t * links, double *latency)
355 s_sg_platf_route_cbarg_t route = SG_PLATF_ROUTE_INITIALIZER;
356 memset(&route,0,sizeof(route));
358 xbt_assert(src && dst, "bad parameters for \"_get_route_latency\" method");
359 XBT_DEBUG("Solve route/latency \"%s\" to \"%s\"", src->getName(), dst->getName());
361 /* Find how src and dst are interconnected */
362 simgrid::surf::As *common_father, *src_father, *dst_father;
363 elements_father(src, dst, &common_father, &src_father, &dst_father);
364 XBT_DEBUG("elements_father: common father '%s' src_father '%s' dst_father '%s'",
365 common_father->p_name, src_father->p_name, dst_father->p_name);
367 /* Check whether a direct bypass is defined */
368 sg_platf_route_cbarg_t e_route_bypass = NULL;
369 //FIXME:REMOVE:if (common_father->get_bypass_route)
371 e_route_bypass = common_father->getBypassRoute(src, dst, latency);
373 /* Common ancestor is kind enough to declare a bypass route from src to dst -- use it and bail out */
374 if (e_route_bypass) {
375 xbt_dynar_merge(links, &e_route_bypass->link_list);
376 routing_route_free(e_route_bypass);
380 /* If src and dst are in the same AS, life is good */
381 if (src_father == dst_father) { /* SURF_ROUTING_BASE */
382 route.link_list = *links;
383 common_father->getRouteAndLatency(src, dst, &route, latency);
384 // if vivaldi latency+=vivaldi(src,dst)
388 /* Not in the same AS, no bypass. We'll have to find our path between the ASes recursively*/
390 route.link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
391 // Find the net_card corresponding to father
392 simgrid::surf::NetCard *src_father_netcard = src_father->p_netcard;
393 simgrid::surf::NetCard *dst_father_netcard = dst_father->p_netcard;
395 common_father->getRouteAndLatency(src_father_netcard, dst_father_netcard,
398 xbt_assert((route.gw_src != NULL) && (route.gw_dst != NULL),
399 "bad gateways for route from \"%s\" to \"%s\"", src->getName(), dst->getName());
401 sg_netcard_t src_gateway_net_elm = route.gw_src;
402 sg_netcard_t dst_gateway_net_elm = route.gw_dst;
404 /* If source gateway is not our source, we have to recursively find our way up to this point */
405 if (src != src_gateway_net_elm)
406 _get_route_and_latency(src, src_gateway_net_elm, links, latency);
407 xbt_dynar_merge(links, &route.link_list);
409 /* If dest gateway is not our destination, we have to recursively find our way from this point */
410 if (dst_gateway_net_elm != dst)
411 _get_route_and_latency(dst_gateway_net_elm, dst, links, latency);
415 AS_t surf_platf_get_root(routing_platf_t platf){
416 return platf->p_root;
419 e_surf_network_element_type_t surf_routing_edge_get_rc_type(sg_netcard_t netcard){
420 return netcard->getRcType();
427 * \brief Find a route between hosts
429 * \param src the network_element_t for src host
430 * \param dst the network_element_t for dst host
431 * \param route where to store the list of links.
432 * If *route=NULL, create a short lived dynar. Else, fill the provided dynar
433 * \param latency where to store the latency experienced on the path (or NULL if not interested)
434 * It is the caller responsability to initialize latency to 0 (we add to provided route)
437 * walk through the routing components tree and find a route between hosts
438 * by calling each "get_route" function in each routing component.
440 void RoutingPlatf::getRouteAndLatency(NetCard *src, NetCard *dst, xbt_dynar_t* route, double *latency)
442 XBT_DEBUG("getRouteAndLatency from %s to %s", src->getName(), dst->getName());
443 if (NULL == *route) {
444 xbt_dynar_reset(routing_platf->p_lastRoute);
445 *route = routing_platf->p_lastRoute;
448 _get_route_and_latency(src, dst, route, latency);
450 xbt_assert(!latency || *latency >= 0.0,
451 "negative latency on route between \"%s\" and \"%s\"", src->getName(), dst->getName());
454 xbt_dynar_t RoutingPlatf::getOneLinkRoutes(){
455 return recursiveGetOneLinkRoutes(p_root);
458 xbt_dynar_t RoutingPlatf::recursiveGetOneLinkRoutes(As *rc)
460 xbt_dynar_t ret = xbt_dynar_new(sizeof(Onelink*), xbt_free_f);
462 //adding my one link routes
463 xbt_dynar_t onelink_mine = rc->getOneLinkRoutes();
465 xbt_dynar_merge(&ret,&onelink_mine);
469 xbt_dict_cursor_t cursor = NULL;
471 xbt_dict_foreach(rc->p_routingSons, cursor, key, rc_child) {
472 xbt_dynar_t onelink_child = recursiveGetOneLinkRoutes(rc_child);
474 xbt_dynar_merge(&ret,&onelink_child);
482 e_surf_network_element_type_t routing_get_network_element_type(const char *name)
484 simgrid::surf::NetCard *rc = sg_netcard_by_name_or_null(name);
486 return rc->getRcType();
488 return SURF_NETWORK_ELEMENT_NULL;
491 /** @brief create the root AS */
492 void routing_model_create( void *loopback)
494 routing_platf = new simgrid::surf::RoutingPlatf(loopback);
497 /* ************************************************************************** */
498 /* ************************* GENERIC PARSE FUNCTIONS ************************ */
500 void routing_cluster_add_backbone(void* bb) {
501 xbt_assert(current_routing->p_modelDesc == &routing_models[SURF_MODEL_CLUSTER],
502 "You have to be in model Cluster to use tag backbone!");
503 xbt_assert(!static_cast<simgrid::surf::AsCluster*>(current_routing)->p_backbone, "The backbone link is already defined!");
504 static_cast<simgrid::surf::AsCluster*>(current_routing)->p_backbone =
505 static_cast<simgrid::surf::Link*>(bb);
506 XBT_DEBUG("Add a backbone to AS '%s'", current_routing->p_name);
509 void sg_platf_new_cabinet(sg_platf_cabinet_cbarg_t cabinet)
512 char *groups , *host_id , *link_id = NULL;
514 xbt_dynar_t radical_elements;
515 xbt_dynar_t radical_ends;
518 radical_elements = xbt_str_split(cabinet->radical, ",");
519 xbt_dynar_foreach(radical_elements, iter, groups) {
521 radical_ends = xbt_str_split(groups, "-");
522 start = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 0, char *));
524 switch (xbt_dynar_length(radical_ends)) {
529 end = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 1, char *));
532 surf_parse_error("Malformed radical");
535 s_sg_platf_host_cbarg_t host = SG_PLATF_HOST_INITIALIZER;
536 memset(&host, 0, sizeof(host));
537 host.initiallyOn = 1;
539 host.speed_scale = 1.0;
540 host.core_amount = 1;
542 s_sg_platf_link_cbarg_t link = SG_PLATF_LINK_INITIALIZER;
543 memset(&link, 0, sizeof(link));
544 link.initiallyOn = 1;
545 link.policy = SURF_LINK_FULLDUPLEX;
546 link.latency = cabinet->lat;
547 link.bandwidth = cabinet->bw;
549 s_sg_platf_host_link_cbarg_t host_link = SG_PLATF_HOST_LINK_INITIALIZER;
550 memset(&host_link, 0, sizeof(host_link));
552 for (i = start; i <= end; i++) {
553 host_id = bprintf("%s%d%s",cabinet->prefix,i,cabinet->suffix);
554 link_id = bprintf("link_%s%d%s",cabinet->prefix,i,cabinet->suffix);
557 host.speed_peak = xbt_dynar_new(sizeof(double), NULL);
558 xbt_dynar_push(host.speed_peak,&cabinet->speed);
559 sg_platf_new_host(&host);
560 xbt_dynar_free(&host.speed_peak);
561 sg_platf_new_link(&link);
563 char* link_up = bprintf("%s_UP",link_id);
564 char* link_down = bprintf("%s_DOWN",link_id);
565 host_link.id = host_id;
566 host_link.link_up = link_up;
567 host_link.link_down = link_down;
568 sg_platf_new_netcard(&host_link);
576 xbt_dynar_free(&radical_ends);
578 xbt_dynar_free(&radical_elements);
581 void sg_platf_new_peer(sg_platf_peer_cbarg_t peer)
583 using simgrid::surf::NetCard;
584 using simgrid::surf::AsCluster;
586 char *host_id = NULL;
587 char *link_id = NULL;
588 char *router_id = NULL;
591 host_id = HOST_PEER(peer->id);
592 link_id = LINK_PEER(peer->id);
593 router_id = ROUTER_PEER(peer->id);
595 XBT_DEBUG("<AS id=\"%s\"\trouting=\"Cluster\">", peer->id);
596 s_sg_platf_AS_cbarg_t AS = SG_PLATF_AS_INITIALIZER;
598 AS.routing = A_surfxml_AS_routing_Cluster;
599 sg_platf_new_AS_begin(&AS);
601 current_routing->p_linkUpDownList = xbt_dynar_new(sizeof(s_surf_parsing_link_up_down_t),NULL);
603 XBT_DEBUG("<host\tid=\"%s\"\tpower=\"%f\"/>", host_id, peer->speed);
604 s_sg_platf_host_cbarg_t host = SG_PLATF_HOST_INITIALIZER;
605 memset(&host, 0, sizeof(host));
606 host.initiallyOn = 1;
609 host.speed_peak = xbt_dynar_new(sizeof(double), NULL);
610 xbt_dynar_push(host.speed_peak,&peer->speed);
612 //host.power_peak = peer->power;
613 host.speed_scale = 1.0;
614 host.speed_trace = peer->availability_trace;
615 host.state_trace = peer->state_trace;
616 host.core_amount = 1;
617 sg_platf_new_host(&host);
618 xbt_dynar_free(&host.speed_peak);
620 s_sg_platf_link_cbarg_t link = SG_PLATF_LINK_INITIALIZER;
621 memset(&link, 0, sizeof(link));
622 link.initiallyOn = 1;
623 link.policy = SURF_LINK_SHARED;
624 link.latency = peer->lat;
626 char* link_up = bprintf("%s_UP",link_id);
627 XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%f\"\tlat=\"%f\"/>", link_up,
628 peer->bw_out, peer->lat);
630 link.bandwidth = peer->bw_out;
631 sg_platf_new_link(&link);
633 char* link_down = bprintf("%s_DOWN",link_id);
634 XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%f\"\tlat=\"%f\"/>", link_down,
635 peer->bw_in, peer->lat);
637 link.bandwidth = peer->bw_in;
638 sg_platf_new_link(&link);
640 XBT_DEBUG("<host_link\tid=\"%s\"\tup=\"%s\"\tdown=\"%s\" />", host_id,link_up,link_down);
641 s_sg_platf_host_link_cbarg_t host_link = SG_PLATF_HOST_LINK_INITIALIZER;
642 memset(&host_link, 0, sizeof(host_link));
643 host_link.id = host_id;
644 host_link.link_up = link_up;
645 host_link.link_down = link_down;
646 sg_platf_new_netcard(&host_link);
648 XBT_DEBUG("<router id=\"%s\"/>", router_id);
649 s_sg_platf_router_cbarg_t router = SG_PLATF_ROUTER_INITIALIZER;
650 memset(&router, 0, sizeof(router));
651 router.id = router_id;
652 router.coord = peer->coord;
653 sg_platf_new_router(&router);
654 static_cast<AsCluster*>(current_routing)->p_router = static_cast<NetCard*>(xbt_lib_get_or_null(as_router_lib, router.id, ROUTING_ASR_LEVEL));
657 sg_platf_new_AS_end();
660 //xbt_dynar_free(&tab_elements_num);
668 // static void routing_parse_Srandom(void)
670 // double mean, std, min, max, seed;
671 // char *random_id = A_surfxml_random_id;
672 // char *random_radical = A_surfxml_random_radical;
673 // char *rd_name = NULL;
675 // mean = surf_parse_get_double(A_surfxml_random_mean);
676 // std = surf_parse_get_double(A_surfxml_random_std___deviation);
677 // min = surf_parse_get_double(A_surfxml_random_min);
678 // max = surf_parse_get_double(A_surfxml_random_max);
679 // seed = surf_parse_get_double(A_surfxml_random_seed);
683 // random_data_t random = xbt_new0(s_random_data_t, 1);
686 // xbt_dynar_t radical_elements;
687 // unsigned int iter;
690 // xbt_dynar_t radical_ends;
692 // switch (A_surfxml_random_generator) {
693 // case AU_surfxml_random_generator:
694 // case A_surfxml_random_generator_NONE:
695 // random->generator = NONE;
697 // case A_surfxml_random_generator_DRAND48:
698 // random->generator = DRAND48;
700 // case A_surfxml_random_generator_RAND:
701 // random->generator = RAND;
703 // case A_surfxml_random_generator_RNGSTREAM:
704 // random->generator = RNGSTREAM;
707 // surf_parse_error("Invalid random generator");
710 // random->seed = seed;
711 // random->min = min;
712 // random->max = max;
714 // /* Check user stupidities */
716 // THROWF(arg_error, 0, "random->max < random->min (%f < %f)", max, min);
718 // THROWF(arg_error, 0, "random->mean < random->min (%f < %f)", mean, min);
720 // THROWF(arg_error, 0, "random->mean > random->max (%f > %f)", mean, max);
722 // /* normalize the mean and standard deviation before storing */
723 // random->mean = (mean - min) / (max - min);
724 // random->std = std / (max - min);
726 // if (random->mean * (1 - random->mean) < random->std * random->std)
727 // THROWF(arg_error, 0, "Invalid mean and standard deviation (%f and %f)",
728 // random->mean, random->std);
731 // ("id = '%s' min = '%f' max = '%f' mean = '%f' std_deviatinon = '%f' generator = '%d' seed = '%ld' radical = '%s'",
732 // random_id, random->min, random->max, random->mean, random->std,
733 // (int)random->generator, random->seed, random_radical);
735 // if (!random_value)
736 // random_value = xbt_dict_new_homogeneous(free);
738 // if (!strcmp(random_radical, "")) {
739 // res = random_generate(random);
740 // rd_value = bprintf("%f", res);
741 // xbt_dict_set(random_value, random_id, rd_value, NULL);
743 // radical_elements = xbt_str_split(random_radical, ",");
744 // xbt_dynar_foreach(radical_elements, iter, groups) {
745 // radical_ends = xbt_str_split(groups, "-");
746 // switch (xbt_dynar_length(radical_ends)) {
748 // xbt_assert(!xbt_dict_get_or_null(random_value, random_id),
749 // "Custom Random '%s' already exists !", random_id);
750 // res = random_generate(random);
752 // bprintf("%s%d", random_id,
753 // atoi(xbt_dynar_getfirst_as(radical_ends, char *)));
754 // xbt_dict_set(random_value, tmpbuf, bprintf("%f", res), NULL);
759 // start = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 0, char *));
760 // end = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 1, char *));
761 // for (i = start; i <= end; i++) {
762 // xbt_assert(!xbt_dict_get_or_null(random_value, random_id),
763 // "Custom Random '%s' already exists !", bprintf("%s%d",
766 // res = random_generate(random);
767 // tmpbuf = bprintf("%s%d", random_id, i);
768 // xbt_dict_set(random_value, tmpbuf, bprintf("%f", res), NULL);
773 // XBT_CRITICAL("Malformed radical");
776 // res = random_generate(random);
777 // rd_name = bprintf("%s_router", random_id);
778 // rd_value = bprintf("%f", res);
779 // xbt_dict_set(random_value, rd_name, rd_value, NULL);
781 // xbt_dynar_free(&radical_ends);
784 // xbt_dynar_free(&radical_elements);
788 static void check_disk_attachment()
790 xbt_lib_cursor_t cursor;
793 simgrid::surf::NetCard *host_elm;
794 xbt_lib_foreach(storage_lib, cursor, key, data) {
795 if(xbt_lib_get_level(xbt_lib_get_elm_or_null(storage_lib, key), SURF_STORAGE_LEVEL) != NULL) {
796 simgrid::surf::Storage *storage = static_cast<simgrid::surf::Storage*>(xbt_lib_get_level(xbt_lib_get_elm_or_null(storage_lib, key), SURF_STORAGE_LEVEL));
797 host_elm = sg_netcard_by_name_or_null(storage->p_attach);
799 surf_parse_error("Unable to attach storage %s: host %s doesn't exist.", storage->getName(), storage->p_attach);
804 void routing_register_callbacks()
806 simgrid::surf::on_postparse.connect(check_disk_attachment);
808 instr_routing_define_callbacks();
812 * \brief Recursive function for finalize
814 * \param rc the source host name
816 * This fuction is call by "finalize". It allow to finalize the
817 * AS or routing components. It delete all the structures.
819 static void finalize_rec(simgrid::surf::As *as) {
820 xbt_dict_cursor_t cursor = NULL;
824 xbt_dict_foreach(as->p_routingSons, cursor, key, elem) {
831 /** \brief Frees all memory allocated by the routing module */
832 void routing_exit(void) {
833 delete routing_platf;
839 RoutingPlatf::RoutingPlatf(void *loopback)
840 : p_loopback(loopback)
843 RoutingPlatf::~RoutingPlatf()
845 xbt_dynar_free(&p_lastRoute);
846 finalize_rec(p_root);
852 AS_t surf_AS_get_routing_root() {
853 return routing_platf->p_root;
856 const char *surf_AS_get_name(simgrid::surf::As *as) {
860 static simgrid::surf::As *surf_AS_recursive_get_by_name(
861 simgrid::surf::As *current, const char * name)
863 xbt_dict_cursor_t cursor = NULL;
866 simgrid::surf::As *tmp = NULL;
868 if(!strcmp(current->p_name, name))
871 xbt_dict_foreach(current->p_routingSons, cursor, key, elem) {
872 tmp = surf_AS_recursive_get_by_name(elem, name);
880 simgrid::surf::As *surf_AS_get_by_name(const char * name)
882 simgrid::surf::As *as = surf_AS_recursive_get_by_name(routing_platf->p_root, name);
884 XBT_WARN("Impossible to find an AS with name %s, please check your input", name);
888 xbt_dict_t surf_AS_get_routing_sons(simgrid::surf::As *as)
890 return as->p_routingSons;
893 const char *surf_AS_get_model(simgrid::surf::As *as)
895 return as->p_modelDesc->name;
898 xbt_dynar_t surf_AS_get_hosts(simgrid::surf::As *as)
900 xbt_dynar_t elms = as->p_indexNetworkElm;
901 int count = xbt_dynar_length(elms);
902 xbt_dynar_t res = xbt_dynar_new(sizeof(sg_host_t), NULL);
903 for (int index = 0; index < count; index++) {
905 xbt_dynar_get_as(elms, index, simgrid::surf::NetCard*);
906 sg_host_t delm = simgrid::s4u::Host::by_name_or_null(relm->getName());
908 xbt_dynar_push(res, &delm);
914 void surf_AS_get_graph(AS_t as, xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges) {
915 as->getGraph(graph, nodes, edges);