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 {"TorusCluster", "Torus Cluster routing", model_torus_cluster_create},
105 {"FatTreeCluster", "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(NULL == xbt_lib_get_or_null(as_router_lib, AS->id, ROUTING_ASR_LEVEL),
172 "Refusing to create a second AS called \"%s\".", AS->id);
174 _sg_cfg_init_status = 2; /* horrible hack: direct access to the global
175 * controlling the level of configuration to prevent
176 * any further config */
178 /* search the routing model */
180 case A_surfxml_AS_routing_Cluster: model = &routing_models[SURF_MODEL_CLUSTER];break;
181 case A_surfxml_AS_routing_ClusterTorus: model = &routing_models[SURF_MODEL_TORUS_CLUSTER];break;
182 case A_surfxml_AS_routing_ClusterFatTree: model = &routing_models[SURF_MODEL_FAT_TREE_CLUSTER];break;
183 case A_surfxml_AS_routing_Dijkstra: model = &routing_models[SURF_MODEL_DIJKSTRA];break;
184 case A_surfxml_AS_routing_DijkstraCache: model = &routing_models[SURF_MODEL_DIJKSTRACACHE];break;
185 case A_surfxml_AS_routing_Floyd: model = &routing_models[SURF_MODEL_FLOYD];break;
186 case A_surfxml_AS_routing_Full: model = &routing_models[SURF_MODEL_FULL];break;
187 case A_surfxml_AS_routing_None: model = &routing_models[SURF_MODEL_NONE];break;
188 case A_surfxml_AS_routing_Vivaldi: model = &routing_models[SURF_MODEL_VIVALDI];break;
189 default: xbt_die("Not a valid model!!!");
193 /* make a new routing component */
194 simgrid::surf::As *new_as = model->create();
196 new_as->p_modelDesc = model;
197 new_as->p_hierarchy = SURF_ROUTING_NULL;
198 new_as->p_name = xbt_strdup(AS->id);
200 simgrid::surf::NetCard *info =
201 new simgrid::surf::NetCardImpl(xbt_strdup(new_as->p_name),
203 SURF_NETWORK_ELEMENT_AS,
205 if (current_routing == NULL && routing_platf->p_root == NULL) {
207 /* it is the first one */
208 new_as->p_routingFather = NULL;
209 routing_platf->p_root = new_as;
211 } else if (current_routing != NULL && routing_platf->p_root != NULL) {
213 xbt_assert(!xbt_dict_get_or_null
214 (current_routing->p_routingSons, AS->id),
215 "The AS \"%s\" already exists", AS->id);
216 /* it is a part of the tree */
217 new_as->p_routingFather = current_routing;
218 /* set the father behavior */
219 if (current_routing->p_hierarchy == SURF_ROUTING_NULL)
220 current_routing->p_hierarchy = SURF_ROUTING_RECURSIVE;
221 /* add to the sons dictionary */
222 xbt_dict_set(current_routing->p_routingSons, AS->id,
223 (void *) new_as, NULL);
224 /* add to the father element list */
225 info->setId(current_routing->parseAS(info));
227 THROWF(arg_error, 0, "All defined components must belong to a AS");
230 xbt_lib_set(as_router_lib, info->getName(), ROUTING_ASR_LEVEL,
232 XBT_DEBUG("Having set name '%s' id '%d'", new_as->p_name, info->getId());
234 /* set the new current component of the tree */
235 current_routing = new_as;
236 current_routing->p_netcard = info;
238 simgrid::surf::netcardCreatedCallbacks(info);
239 simgrid::surf::asCreatedCallbacks(new_as);
243 * \brief Specify that the current description of AS is finished
245 * Once you've declared all the content of your AS, you have to close
246 * it with this call. Your AS is not usable until you call this function.
248 * @fixme: this call is not as robust as wanted: bad things WILL happen
249 * if you call it twice for the same AS, or if you forget calling it, or
250 * even if you add stuff to a closed AS
253 void routing_AS_end()
255 xbt_assert(current_routing, "Cannot seal the current AS: none under construction");
256 current_routing->Seal();
257 current_routing = current_routing->p_routingFather;
260 /* Aux Business methods */
263 * \brief Get the AS father and the first elements of the chain
265 * \param src the source host name
266 * \param dst the destination host name
268 * Get the common father of the to processing units, and the first different
269 * father in the chain
271 static void elements_father(sg_netcard_t src, sg_netcard_t dst,
276 xbt_assert(src && dst, "bad parameters for \"elements_father\" method");
277 #define ELEMENTS_FATHER_MAXDEPTH 16 /* increase if it is not enough */
278 simgrid::surf::As *src_as, *dst_as;
279 simgrid::surf::As *path_src[ELEMENTS_FATHER_MAXDEPTH];
280 simgrid::surf::As *path_dst[ELEMENTS_FATHER_MAXDEPTH];
283 simgrid::surf::As *current;
284 simgrid::surf::As *current_src;
285 simgrid::surf::As *current_dst;
286 simgrid::surf::As *father;
288 /* (1) find the as where the src and dst are located */
289 sg_netcard_t src_data = src;
290 sg_netcard_t dst_data = dst;
291 src_as = src_data->getRcComponent();
292 dst_as = dst_data->getRcComponent();
294 char* src_name = src_data->getName();
295 char* dst_name = dst_data->getName();
298 xbt_assert(src_as && dst_as,
299 "Ask for route \"from\"(%s) or \"to\"(%s) no found", src_name, dst_name);
301 /* (2) find the path to the root routing component */
302 for (current = src_as; current != NULL; current = current->p_routingFather) {
303 if (index_src >= ELEMENTS_FATHER_MAXDEPTH)
304 xbt_die("ELEMENTS_FATHER_MAXDEPTH should be increased for path_src");
305 path_src[index_src++] = current;
307 for (current = dst_as; current != NULL; current = current->p_routingFather) {
308 if (index_dst >= ELEMENTS_FATHER_MAXDEPTH)
309 xbt_die("ELEMENTS_FATHER_MAXDEPTH should be increased for path_dst");
310 path_dst[index_dst++] = current;
313 /* (3) find the common father */
315 current_src = path_src[--index_src];
316 current_dst = path_dst[--index_dst];
317 } while (index_src > 0 && index_dst > 0 && current_src == current_dst);
319 /* (4) they are not in the same routing component, make the path */
320 if (current_src == current_dst)
321 father = current_src;
323 father = path_src[index_src + 1];
325 /* (5) result generation */
326 *res_father = father; /* first the common father of src and dst */
327 *res_src = current_src; /* second the first different father of src */
328 *res_dst = current_dst; /* three the first different father of dst */
330 #undef ELEMENTS_FATHER_MAXDEPTH
333 /* Global Business methods */
336 * \brief Recursive function for get_route_latency
338 * \param src the source host name
339 * \param dst the destination host name
340 * \param *route the route where the links are stored. It is either NULL or a ready to use dynar
341 * \param *latency the latency, if needed
343 * This function is called by "get_route" and "get_latency". It allows to walk
344 * recursively through the ASes tree.
346 static void _get_route_and_latency(
347 simgrid::surf::NetCard *src, simgrid::surf::NetCard *dst,
348 xbt_dynar_t * links, double *latency)
350 s_sg_platf_route_cbarg_t route = SG_PLATF_ROUTE_INITIALIZER;
351 memset(&route,0,sizeof(route));
353 xbt_assert(src && dst, "bad parameters for \"_get_route_latency\" method");
354 XBT_DEBUG("Solve route/latency \"%s\" to \"%s\"", src->getName(), dst->getName());
356 /* Find how src and dst are interconnected */
357 simgrid::surf::As *common_father, *src_father, *dst_father;
358 elements_father(src, dst, &common_father, &src_father, &dst_father);
359 XBT_DEBUG("elements_father: common father '%s' src_father '%s' dst_father '%s'",
360 common_father->p_name, src_father->p_name, dst_father->p_name);
362 /* Check whether a direct bypass is defined */
363 sg_platf_route_cbarg_t e_route_bypass = NULL;
364 //FIXME:REMOVE:if (common_father->get_bypass_route)
366 e_route_bypass = common_father->getBypassRoute(src, dst, latency);
368 /* Common ancestor is kind enough to declare a bypass route from src to dst -- use it and bail out */
369 if (e_route_bypass) {
370 xbt_dynar_merge(links, &e_route_bypass->link_list);
371 routing_route_free(e_route_bypass);
375 /* If src and dst are in the same AS, life is good */
376 if (src_father == dst_father) { /* SURF_ROUTING_BASE */
377 route.link_list = *links;
378 common_father->getRouteAndLatency(src, dst, &route, latency);
379 // if vivaldi latency+=vivaldi(src,dst)
383 /* Not in the same AS, no bypass. We'll have to find our path between the ASes recursively*/
385 route.link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
386 // Find the net_card corresponding to father
387 simgrid::surf::NetCard *src_father_netcard = src_father->p_netcard;
388 simgrid::surf::NetCard *dst_father_netcard = dst_father->p_netcard;
390 common_father->getRouteAndLatency(src_father_netcard, dst_father_netcard,
393 xbt_assert((route.gw_src != NULL) && (route.gw_dst != NULL),
394 "bad gateways for route from \"%s\" to \"%s\"", src->getName(), dst->getName());
396 sg_netcard_t src_gateway_net_elm = route.gw_src;
397 sg_netcard_t dst_gateway_net_elm = route.gw_dst;
399 /* If source gateway is not our source, we have to recursively find our way up to this point */
400 if (src != src_gateway_net_elm)
401 _get_route_and_latency(src, src_gateway_net_elm, links, latency);
402 xbt_dynar_merge(links, &route.link_list);
404 /* If dest gateway is not our destination, we have to recursively find our way from this point */
405 if (dst_gateway_net_elm != dst)
406 _get_route_and_latency(dst_gateway_net_elm, dst, links, latency);
410 AS_t surf_platf_get_root(routing_platf_t platf){
411 return platf->p_root;
414 e_surf_network_element_type_t surf_routing_edge_get_rc_type(sg_netcard_t netcard){
415 return netcard->getRcType();
422 * \brief Find a route between hosts
424 * \param src the network_element_t for src host
425 * \param dst the network_element_t for dst host
426 * \param route where to store the list of links.
427 * If *route=NULL, create a short lived dynar. Else, fill the provided dynar
428 * \param latency where to store the latency experienced on the path (or NULL if not interested)
429 * It is the caller responsability to initialize latency to 0 (we add to provided route)
432 * walk through the routing components tree and find a route between hosts
433 * by calling each "get_route" function in each routing component.
435 void RoutingPlatf::getRouteAndLatency(NetCard *src, NetCard *dst, xbt_dynar_t* route, double *latency)
437 XBT_DEBUG("getRouteAndLatency from %s to %s", src->getName(), dst->getName());
438 if (NULL == *route) {
439 xbt_dynar_reset(routing_platf->p_lastRoute);
440 *route = routing_platf->p_lastRoute;
443 _get_route_and_latency(src, dst, route, latency);
445 xbt_assert(!latency || *latency >= 0.0,
446 "negative latency on route between \"%s\" and \"%s\"", src->getName(), dst->getName());
449 xbt_dynar_t RoutingPlatf::getOneLinkRoutes(){
450 return recursiveGetOneLinkRoutes(p_root);
453 xbt_dynar_t RoutingPlatf::recursiveGetOneLinkRoutes(As *rc)
455 xbt_dynar_t ret = xbt_dynar_new(sizeof(Onelink*), xbt_free_f);
457 //adding my one link routes
458 xbt_dynar_t onelink_mine = rc->getOneLinkRoutes();
460 xbt_dynar_merge(&ret,&onelink_mine);
464 xbt_dict_cursor_t cursor = NULL;
466 xbt_dict_foreach(rc->p_routingSons, cursor, key, rc_child) {
467 xbt_dynar_t onelink_child = recursiveGetOneLinkRoutes(rc_child);
469 xbt_dynar_merge(&ret,&onelink_child);
477 e_surf_network_element_type_t routing_get_network_element_type(const char *name)
479 simgrid::surf::NetCard *rc = sg_netcard_by_name_or_null(name);
481 return rc->getRcType();
483 return SURF_NETWORK_ELEMENT_NULL;
486 /** @brief create the root AS */
487 void routing_model_create( void *loopback)
489 routing_platf = new simgrid::surf::RoutingPlatf(loopback);
492 /* ************************************************************************** */
493 /* ************************* GENERIC PARSE FUNCTIONS ************************ */
495 void routing_cluster_add_backbone(void* bb) {
496 xbt_assert(current_routing->p_modelDesc == &routing_models[SURF_MODEL_CLUSTER],
497 "You have to be in model Cluster to use tag backbone!");
498 xbt_assert(!static_cast<simgrid::surf::AsCluster*>(current_routing)->p_backbone, "The backbone link is already defined!");
499 static_cast<simgrid::surf::AsCluster*>(current_routing)->p_backbone =
500 static_cast<simgrid::surf::Link*>(bb);
501 XBT_DEBUG("Add a backbone to AS '%s'", current_routing->p_name);
504 void sg_platf_new_cabinet(sg_platf_cabinet_cbarg_t cabinet)
507 char *groups , *host_id , *link_id = NULL;
509 xbt_dynar_t radical_elements;
510 xbt_dynar_t radical_ends;
513 radical_elements = xbt_str_split(cabinet->radical, ",");
514 xbt_dynar_foreach(radical_elements, iter, groups) {
516 radical_ends = xbt_str_split(groups, "-");
517 start = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 0, char *));
519 switch (xbt_dynar_length(radical_ends)) {
524 end = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 1, char *));
527 surf_parse_error("Malformed radical");
530 s_sg_platf_host_cbarg_t host = SG_PLATF_HOST_INITIALIZER;
531 memset(&host, 0, sizeof(host));
532 host.initiallyOn = 1;
534 host.speed_scale = 1.0;
535 host.core_amount = 1;
537 s_sg_platf_link_cbarg_t link = SG_PLATF_LINK_INITIALIZER;
538 memset(&link, 0, sizeof(link));
539 link.initiallyOn = 1;
540 link.policy = SURF_LINK_FULLDUPLEX;
541 link.latency = cabinet->lat;
542 link.bandwidth = cabinet->bw;
544 s_sg_platf_host_link_cbarg_t host_link = SG_PLATF_HOST_LINK_INITIALIZER;
545 memset(&host_link, 0, sizeof(host_link));
547 for (i = start; i <= end; i++) {
548 host_id = bprintf("%s%d%s",cabinet->prefix,i,cabinet->suffix);
549 link_id = bprintf("link_%s%d%s",cabinet->prefix,i,cabinet->suffix);
552 host.speed_peak = xbt_dynar_new(sizeof(double), NULL);
553 xbt_dynar_push(host.speed_peak,&cabinet->speed);
554 sg_platf_new_host(&host);
555 xbt_dynar_free(&host.speed_peak);
556 sg_platf_new_link(&link);
558 char* link_up = bprintf("%s_UP",link_id);
559 char* link_down = bprintf("%s_DOWN",link_id);
560 host_link.id = host_id;
561 host_link.link_up = link_up;
562 host_link.link_down = link_down;
563 sg_platf_new_netcard(&host_link);
571 xbt_dynar_free(&radical_ends);
573 xbt_dynar_free(&radical_elements);
576 void sg_platf_new_peer(sg_platf_peer_cbarg_t peer)
578 using simgrid::surf::NetCard;
579 using simgrid::surf::AsCluster;
581 char *host_id = NULL;
582 char *link_id = NULL;
583 char *router_id = NULL;
586 host_id = HOST_PEER(peer->id);
587 link_id = LINK_PEER(peer->id);
588 router_id = ROUTER_PEER(peer->id);
590 XBT_DEBUG("<AS id=\"%s\"\trouting=\"Cluster\">", peer->id);
591 s_sg_platf_AS_cbarg_t AS = SG_PLATF_AS_INITIALIZER;
593 AS.routing = A_surfxml_AS_routing_Cluster;
594 sg_platf_new_AS_begin(&AS);
596 current_routing->p_linkUpDownList = xbt_dynar_new(sizeof(s_surf_parsing_link_up_down_t),NULL);
598 XBT_DEBUG("<host\tid=\"%s\"\tpower=\"%f\"/>", host_id, peer->speed);
599 s_sg_platf_host_cbarg_t host = SG_PLATF_HOST_INITIALIZER;
600 memset(&host, 0, sizeof(host));
601 host.initiallyOn = 1;
604 host.speed_peak = xbt_dynar_new(sizeof(double), NULL);
605 xbt_dynar_push(host.speed_peak,&peer->speed);
607 //host.power_peak = peer->power;
608 host.speed_scale = 1.0;
609 host.speed_trace = peer->availability_trace;
610 host.state_trace = peer->state_trace;
611 host.core_amount = 1;
612 sg_platf_new_host(&host);
613 xbt_dynar_free(&host.speed_peak);
615 s_sg_platf_link_cbarg_t link = SG_PLATF_LINK_INITIALIZER;
616 memset(&link, 0, sizeof(link));
617 link.initiallyOn = 1;
618 link.policy = SURF_LINK_SHARED;
619 link.latency = peer->lat;
621 char* link_up = bprintf("%s_UP",link_id);
622 XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%f\"\tlat=\"%f\"/>", link_up,
623 peer->bw_out, peer->lat);
625 link.bandwidth = peer->bw_out;
626 sg_platf_new_link(&link);
628 char* link_down = bprintf("%s_DOWN",link_id);
629 XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%f\"\tlat=\"%f\"/>", link_down,
630 peer->bw_in, peer->lat);
632 link.bandwidth = peer->bw_in;
633 sg_platf_new_link(&link);
635 XBT_DEBUG("<host_link\tid=\"%s\"\tup=\"%s\"\tdown=\"%s\" />", host_id,link_up,link_down);
636 s_sg_platf_host_link_cbarg_t host_link = SG_PLATF_HOST_LINK_INITIALIZER;
637 memset(&host_link, 0, sizeof(host_link));
638 host_link.id = host_id;
639 host_link.link_up = link_up;
640 host_link.link_down = link_down;
641 sg_platf_new_netcard(&host_link);
643 XBT_DEBUG("<router id=\"%s\"/>", router_id);
644 s_sg_platf_router_cbarg_t router = SG_PLATF_ROUTER_INITIALIZER;
645 memset(&router, 0, sizeof(router));
646 router.id = router_id;
647 router.coord = peer->coord;
648 sg_platf_new_router(&router);
649 static_cast<AsCluster*>(current_routing)->p_router = static_cast<NetCard*>(xbt_lib_get_or_null(as_router_lib, router.id, ROUTING_ASR_LEVEL));
652 sg_platf_new_AS_end();
655 //xbt_dynar_free(&tab_elements_num);
663 // static void routing_parse_Srandom(void)
665 // double mean, std, min, max, seed;
666 // char *random_id = A_surfxml_random_id;
667 // char *random_radical = A_surfxml_random_radical;
668 // char *rd_name = NULL;
670 // mean = surf_parse_get_double(A_surfxml_random_mean);
671 // std = surf_parse_get_double(A_surfxml_random_std___deviation);
672 // min = surf_parse_get_double(A_surfxml_random_min);
673 // max = surf_parse_get_double(A_surfxml_random_max);
674 // seed = surf_parse_get_double(A_surfxml_random_seed);
678 // random_data_t random = xbt_new0(s_random_data_t, 1);
681 // xbt_dynar_t radical_elements;
682 // unsigned int iter;
685 // xbt_dynar_t radical_ends;
687 // switch (A_surfxml_random_generator) {
688 // case AU_surfxml_random_generator:
689 // case A_surfxml_random_generator_NONE:
690 // random->generator = NONE;
692 // case A_surfxml_random_generator_DRAND48:
693 // random->generator = DRAND48;
695 // case A_surfxml_random_generator_RAND:
696 // random->generator = RAND;
698 // case A_surfxml_random_generator_RNGSTREAM:
699 // random->generator = RNGSTREAM;
702 // surf_parse_error("Invalid random generator");
705 // random->seed = seed;
706 // random->min = min;
707 // random->max = max;
709 // /* Check user stupidities */
711 // THROWF(arg_error, 0, "random->max < random->min (%f < %f)", max, min);
713 // THROWF(arg_error, 0, "random->mean < random->min (%f < %f)", mean, min);
715 // THROWF(arg_error, 0, "random->mean > random->max (%f > %f)", mean, max);
717 // /* normalize the mean and standard deviation before storing */
718 // random->mean = (mean - min) / (max - min);
719 // random->std = std / (max - min);
721 // if (random->mean * (1 - random->mean) < random->std * random->std)
722 // THROWF(arg_error, 0, "Invalid mean and standard deviation (%f and %f)",
723 // random->mean, random->std);
726 // ("id = '%s' min = '%f' max = '%f' mean = '%f' std_deviatinon = '%f' generator = '%d' seed = '%ld' radical = '%s'",
727 // random_id, random->min, random->max, random->mean, random->std,
728 // (int)random->generator, random->seed, random_radical);
730 // if (!random_value)
731 // random_value = xbt_dict_new_homogeneous(free);
733 // if (!strcmp(random_radical, "")) {
734 // res = random_generate(random);
735 // rd_value = bprintf("%f", res);
736 // xbt_dict_set(random_value, random_id, rd_value, NULL);
738 // radical_elements = xbt_str_split(random_radical, ",");
739 // xbt_dynar_foreach(radical_elements, iter, groups) {
740 // radical_ends = xbt_str_split(groups, "-");
741 // switch (xbt_dynar_length(radical_ends)) {
743 // xbt_assert(!xbt_dict_get_or_null(random_value, random_id),
744 // "Custom Random '%s' already exists !", random_id);
745 // res = random_generate(random);
747 // bprintf("%s%d", random_id,
748 // atoi(xbt_dynar_getfirst_as(radical_ends, char *)));
749 // xbt_dict_set(random_value, tmpbuf, bprintf("%f", res), NULL);
754 // start = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 0, char *));
755 // end = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 1, char *));
756 // for (i = start; i <= end; i++) {
757 // xbt_assert(!xbt_dict_get_or_null(random_value, random_id),
758 // "Custom Random '%s' already exists !", bprintf("%s%d",
761 // res = random_generate(random);
762 // tmpbuf = bprintf("%s%d", random_id, i);
763 // xbt_dict_set(random_value, tmpbuf, bprintf("%f", res), NULL);
768 // XBT_CRITICAL("Malformed radical");
771 // res = random_generate(random);
772 // rd_name = bprintf("%s_router", random_id);
773 // rd_value = bprintf("%f", res);
774 // xbt_dict_set(random_value, rd_name, rd_value, NULL);
776 // xbt_dynar_free(&radical_ends);
779 // xbt_dynar_free(&radical_elements);
783 static void check_disk_attachment()
785 xbt_lib_cursor_t cursor;
788 simgrid::surf::NetCard *host_elm;
789 xbt_lib_foreach(storage_lib, cursor, key, data) {
790 if(xbt_lib_get_level(xbt_lib_get_elm_or_null(storage_lib, key), SURF_STORAGE_LEVEL) != NULL) {
791 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));
792 host_elm = sg_netcard_by_name_or_null(storage->p_attach);
794 surf_parse_error("Unable to attach storage %s: host %s doesn't exist.", storage->getName(), storage->p_attach);
799 void routing_register_callbacks()
801 simgrid::surf::on_postparse.connect(check_disk_attachment);
803 instr_routing_define_callbacks();
807 * \brief Recursive function for finalize
809 * \param rc the source host name
811 * This fuction is call by "finalize". It allow to finalize the
812 * AS or routing components. It delete all the structures.
814 static void finalize_rec(simgrid::surf::As *as) {
815 xbt_dict_cursor_t cursor = NULL;
819 xbt_dict_foreach(as->p_routingSons, cursor, key, elem) {
826 /** \brief Frees all memory allocated by the routing module */
827 void routing_exit(void) {
828 delete routing_platf;
834 RoutingPlatf::RoutingPlatf(void *loopback)
835 : p_loopback(loopback)
838 RoutingPlatf::~RoutingPlatf()
840 xbt_dynar_free(&p_lastRoute);
841 finalize_rec(p_root);
847 AS_t surf_AS_get_routing_root() {
848 return routing_platf->p_root;
851 const char *surf_AS_get_name(simgrid::surf::As *as) {
855 static simgrid::surf::As *surf_AS_recursive_get_by_name(
856 simgrid::surf::As *current, const char * name)
858 xbt_dict_cursor_t cursor = NULL;
861 simgrid::surf::As *tmp = NULL;
863 if(!strcmp(current->p_name, name))
866 xbt_dict_foreach(current->p_routingSons, cursor, key, elem) {
867 tmp = surf_AS_recursive_get_by_name(elem, name);
875 simgrid::surf::As *surf_AS_get_by_name(const char * name)
877 simgrid::surf::As *as = surf_AS_recursive_get_by_name(routing_platf->p_root, name);
879 XBT_WARN("Impossible to find an AS with name %s, please check your input", name);
883 xbt_dict_t surf_AS_get_routing_sons(simgrid::surf::As *as)
885 return as->p_routingSons;
888 const char *surf_AS_get_model(simgrid::surf::As *as)
890 return as->p_modelDesc->name;
893 xbt_dynar_t surf_AS_get_hosts(simgrid::surf::As *as)
895 xbt_dynar_t elms = as->p_indexNetworkElm;
896 int count = xbt_dynar_length(elms);
897 xbt_dynar_t res = xbt_dynar_new(sizeof(sg_host_t), NULL);
898 for (int index = 0; index < count; index++) {
900 xbt_dynar_get_as(elms, index, simgrid::surf::NetCard*);
901 sg_host_t delm = simgrid::s4u::Host::by_name_or_null(relm->getName());
903 xbt_dynar_push(res, &delm);
909 void surf_AS_get_graph(AS_t as, xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges) {
910 as->getGraph(graph, nodes, edges);