X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/ddabdf505ca5684fbcc0a4000ca27b89b4732abc..347996b4a10c4e8579080692afa60e0afb88b60a:/src/surf/surf_routing.cpp diff --git a/src/surf/surf_routing.cpp b/src/surf/surf_routing.cpp index 470214230e..3028a23b2a 100644 --- a/src/surf/surf_routing.cpp +++ b/src/surf/surf_routing.cpp @@ -8,10 +8,8 @@ #include "surf_routing_private.hpp" #include "surf_routing_cluster.hpp" -#include "simgrid/platf_interface.h" // platform creation API internal interface #include "simgrid/sg_config.h" #include "storage_interface.hpp" -#include "src/surf/platform.hpp" #include "surf/surfxml_parse_values.h" #include "src/surf/surf_routing_cluster_torus.hpp" @@ -20,6 +18,9 @@ #include "src/surf/surf_routing_floyd.hpp" #include "src/surf/surf_routing_full.hpp" #include "src/surf/surf_routing_vivaldi.hpp" +#include "src/surf/xml/platf.hpp" // FIXME: move that back to the parsing area + +#include XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route, surf, "Routing part of surf"); @@ -38,6 +39,10 @@ namespace surf { xbt_dict_free(&sons_); xbt_dynar_free(&vertices_); xbt_dynar_free(&upDownLinks); + if (nullptr != bypassRoutes_) + for (auto &kv : *bypassRoutes_) + delete kv.second; + delete bypassRoutes_; xbt_free(name_); delete netcard_; } @@ -46,11 +51,10 @@ namespace surf { sealed_ = true; } - sg_platf_route_cbarg_t As::getBypassRoute(NetCard * /*src*/, NetCard * /*dst*/, double * /*lat*/) { + xbt_dynar_t As::getOneLinkRoutes() { return NULL; } - int As::addComponent(NetCard *elm) { XBT_DEBUG("Load component \"%s\"", elm->name()); xbt_dynar_push_as(vertices_, NetCard*, elm); @@ -60,8 +64,151 @@ namespace surf { void As::addRoute(sg_platf_route_cbarg_t /*route*/){ xbt_die("AS %s does not accept new routes (wrong class).",name_); } - void As::parseBypassroute(sg_platf_route_cbarg_t /*e_route*/){ - xbt_die("AS %s does not accept new bypass routes (wrong class).",name_); + + std::vector *As::getBypassRoute(NetCard *src, NetCard *dst) + { + // If never set a bypass route return NULL without any further computations + XBT_DEBUG("generic_get_bypassroute from %s to %s", src->name(), dst->name()); + if (bypassRoutes_ == nullptr) + return nullptr; + + std::vector *bypassedRoute = nullptr; + + if(dst->containingAS() == this && src->containingAS() == this ){ + char *route_name = bprintf("%s#%s", src->name(), dst->name()); + if (bypassRoutes_->find(route_name) != bypassRoutes_->end()) { + bypassedRoute = bypassRoutes_->at(route_name); + XBT_DEBUG("Found a bypass route with %zu links",bypassedRoute->size()); + } + free(route_name); + return bypassedRoute; + } + + int index_src, index_dst; + As **current_src = NULL; + As **current_dst = NULL; + + As *src_as = src->containingAS(); + As *dst_as = dst->containingAS(); + + /* (2) find the path to the root routing component */ + xbt_dynar_t path_src = xbt_dynar_new(sizeof(As*), NULL); + As *current = src_as; + while (current != NULL) { + xbt_dynar_push(path_src, ¤t); + current = current->father_; + } + xbt_dynar_t path_dst = xbt_dynar_new(sizeof(As*), NULL); + current = dst_as; + while (current != NULL) { + xbt_dynar_push(path_dst, ¤t); + current = current->father_; + } + + /* (3) find the common father */ + index_src = path_src->used - 1; + index_dst = path_dst->used - 1; + current_src = (As **) xbt_dynar_get_ptr(path_src, index_src); + current_dst = (As **) xbt_dynar_get_ptr(path_dst, index_dst); + while (index_src >= 0 && index_dst >= 0 && *current_src == *current_dst) { + xbt_dynar_pop_ptr(path_src); + xbt_dynar_pop_ptr(path_dst); + index_src--; + index_dst--; + current_src = (As **) xbt_dynar_get_ptr(path_src, index_src); + current_dst = (As **) xbt_dynar_get_ptr(path_dst, index_dst); + } + + int max_index_src = path_src->used - 1; + int max_index_dst = path_dst->used - 1; + + int max_index = std::max(max_index_src, max_index_dst); + + for (int max = 0; max <= max_index; max++) { + for (int i = 0; i < max; i++) { + if (i <= max_index_src && max <= max_index_dst) { + char *route_name = bprintf("%s#%s", + (*(As **) (xbt_dynar_get_ptr(path_src, i)))->name_, + (*(As **) (xbt_dynar_get_ptr(path_dst, max)))->name_); + if (bypassRoutes_->find(route_name) != bypassRoutes_->end()) + bypassedRoute = bypassRoutes_->at(route_name); + xbt_free(route_name); + } + if (bypassedRoute) + break; + if (max <= max_index_src && i <= max_index_dst) { + char *route_name = bprintf("%s#%s", + (*(As **) (xbt_dynar_get_ptr(path_src, max)))->name_, + (*(As **) (xbt_dynar_get_ptr(path_dst, i)))->name_); + if (bypassRoutes_->find(route_name) != bypassRoutes_->end()) + bypassedRoute = bypassRoutes_->at(route_name); + xbt_free(route_name); + } + if (bypassedRoute) + break; + } + + if (bypassedRoute) + break; + + if (max <= max_index_src && max <= max_index_dst) { + char *route_name = bprintf("%s#%s", + (*(As **) (xbt_dynar_get_ptr(path_src, max)))->name_, + (*(As **) (xbt_dynar_get_ptr(path_dst, max)))->name_); + + if (bypassRoutes_->find(route_name) != bypassRoutes_->end()) + bypassedRoute = bypassRoutes_->at(route_name); + xbt_free(route_name); + } + if (bypassedRoute) + break; + } + + xbt_dynar_free(&path_src); + xbt_dynar_free(&path_dst); + + return bypassedRoute; + } + + void As::addBypassRoute(sg_platf_route_cbarg_t e_route){ + const char *src = e_route->src; + const char *dst = e_route->dst; + + if(bypassRoutes_ == nullptr) + bypassRoutes_ = new std::map*>(); + + char *route_name = bprintf("%s#%s", src, dst); + + /* Argument validity checks */ + if (e_route->gw_dst) { + XBT_DEBUG("Load bypassASroute from %s@%s to %s@%s", + src, e_route->gw_src->name(), dst, e_route->gw_dst->name()); + xbt_assert(!xbt_dynar_is_empty(e_route->link_list), "Bypass route between %s@%s and %s@%s cannot be empty.", + src, e_route->gw_src->name(), dst, e_route->gw_dst->name()); + xbt_assert(bypassRoutes_->find(route_name) == bypassRoutes_->end(), + "The bypass route between %s@%s and %s@%s already exists.", + src, e_route->gw_src->name(), dst, e_route->gw_dst->name()); + } else { + XBT_DEBUG("Load bypassRoute from %s to %s", src, dst); + xbt_assert(!xbt_dynar_is_empty(e_route->link_list), "Bypass route between %s and %s cannot be empty.", src, dst); + xbt_assert(bypassRoutes_->find(route_name) == bypassRoutes_->end(), "The bypass route between %s and %s already exists.", src, dst); + } + + /* Build the value that will be stored in the dict */ + std::vector *newRoute = new std::vector(); + char *linkName; + unsigned int cpt; + xbt_dynar_foreach(e_route->link_list, cpt, linkName) { + Link *link = Link::byName(linkName); + if (link) + newRoute->push_back(link); + else + THROWF(mismatch_error, 0, "Link '%s' not found", linkName); + } + + /* Store it */ + bypassRoutes_->insert({route_name, newRoute}); + xbt_free(route_name); } }} // namespace simgrid::surf @@ -92,10 +239,10 @@ int ROUTING_PROP_ASR_LEVEL; //Where the properties are stored simgrid::surf::NetCard *sg_netcard_by_name_or_null(const char *name) { sg_host_t h = sg_host_by_name(name); - simgrid::surf::NetCard *net_elm = h==NULL?NULL: h->pimpl_netcard; - if (!net_elm) - net_elm = (simgrid::surf::NetCard*) xbt_lib_get_or_null(as_router_lib, name, ROUTING_ASR_LEVEL); - return net_elm; + simgrid::surf::NetCard *netcard = h==NULL ? NULL: h->pimpl_netcard; + if (!netcard) + netcard = (simgrid::surf::NetCard*) xbt_lib_get_or_null(as_router_lib, name, ROUTING_ASR_LEVEL); + return netcard; } /* Global vars */ @@ -164,7 +311,7 @@ void routing_AS_begin(sg_platf_AS_cbarg_t AS) { XBT_DEBUG("routing_AS_begin"); - xbt_assert(NULL == xbt_lib_get_or_null(as_router_lib, AS->id, ROUTING_ASR_LEVEL), + xbt_assert(nullptr == xbt_lib_get_or_null(as_router_lib, AS->id, ROUTING_ASR_LEVEL), "Refusing to create a second AS called \"%s\".", AS->id); _sg_cfg_init_status = 2; /* HACK: direct access to the global controlling the level of configuration to prevent @@ -212,8 +359,7 @@ void routing_AS_begin(sg_platf_AS_cbarg_t AS) THROWF(arg_error, 0, "All defined components must belong to a AS"); } - xbt_lib_set(as_router_lib, netcard->name(), ROUTING_ASR_LEVEL, - (void *) netcard); + xbt_lib_set(as_router_lib, netcard->name(), ROUTING_ASR_LEVEL, (void *) netcard); XBT_DEBUG("Having set name '%s' id '%d'", new_as->name_, netcard->id()); /* set the new current component of the tree */ @@ -314,8 +460,6 @@ static void elements_father(sg_netcard_t src, sg_netcard_t dst, * \param dst the destination host name * \param *route the route where the links are stored. It is either NULL or a ready to use dynar * \param *latency the latency, if needed - * - * This function is called by "get_route" and "get_latency". It allows to walk recursively through the ASes tree. */ static void _get_route_and_latency(simgrid::surf::NetCard *src, simgrid::surf::NetCard *dst, xbt_dynar_t * links, double *latency) @@ -333,10 +477,13 @@ static void _get_route_and_latency(simgrid::surf::NetCard *src, simgrid::surf::N common_father->name_, src_father->name_, dst_father->name_); /* Check whether a direct bypass is defined. If so, use it and bail out */ - sg_platf_route_cbarg_t bypassed_route = common_father->getBypassRoute(src, dst, latency); - if (bypassed_route) { - xbt_dynar_merge(links, &bypassed_route->link_list); - routing_route_free(bypassed_route); + std::vector *bypassed_route = common_father->getBypassRoute(src, dst); + if (nullptr != bypassed_route) { + for (Link *link : *bypassed_route) { + xbt_dynar_push(*links,&link); + if (latency) + *latency += link->getLatency(); + } return; } @@ -366,14 +513,6 @@ static void _get_route_and_latency(simgrid::surf::NetCard *src, simgrid::surf::N } -AS_t surf_platf_get_root(routing_platf_t platf){ - return platf->root_; -} - -e_surf_network_element_type_t surf_routing_edge_get_rc_type(sg_netcard_t netcard){ - return netcard->getRcType(); -} - namespace simgrid { namespace surf { @@ -430,15 +569,6 @@ xbt_dynar_t RoutingPlatf::getOneLinkRoutes(){ } } -e_surf_network_element_type_t routing_get_network_element_type(const char *name) -{ - simgrid::surf::NetCard *rc = sg_netcard_by_name_or_null(name); - if (rc) - return rc->getRcType(); - - return SURF_NETWORK_ELEMENT_NULL; -} - /** @brief create the root AS */ void routing_model_create( void *loopback) {