From: Jonathan Rouzaud-Cornabas Date: Tue, 12 Feb 2013 13:39:29 +0000 (+0100) Subject: Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid X-Git-Tag: v3_9_90~494^2~18 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/2e9105988280d1e88b5b496d6e2eed4c8d541883?hp=79a0e7d2c82c1d2220c1c82165beef46a4cf67ce Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid --- diff --git a/include/msg/msg.h b/include/msg/msg.h index 330ed564c4..20690c09a7 100644 --- a/include/msg/msg.h +++ b/include/msg/msg.h @@ -195,6 +195,8 @@ XBT_PUBLIC(msg_error_t) MSG_task_destroy(msg_task_t task); XBT_PUBLIC(msg_error_t) MSG_task_receive_from_host(msg_task_t * task, const char *alias, msg_host_t host); +XBT_PUBLIC(msg_error_t) MSG_task_receive_from_host_bounded(msg_task_t * task, const char *alias, + msg_host_t host, double rate); XBT_PUBLIC(msg_error_t) MSG_task_execute(msg_task_t task); XBT_PUBLIC(msg_error_t) MSG_parallel_task_execute(msg_task_t task); @@ -226,6 +228,20 @@ XBT_PUBLIC(msg_error_t) MSG_task_receive(msg_task_t * task, const char *alias); #define MSG_task_recv(t,a) MSG_task_receive(t,a) + + +XBT_PUBLIC(msg_error_t) + MSG_task_receive_ext_bounded(msg_task_t * task, const char *alias, double timeout, + msg_host_t host, double rate); + +XBT_PUBLIC(msg_error_t) + MSG_task_receive_with_timeout_bounded(msg_task_t * task, const char *alias, + double timeout, double rate); + +XBT_PUBLIC(msg_error_t) + MSG_task_receive_bounded(msg_task_t * task, const char *alias,double rate); +#define MSG_task_recv_bounded(t,a,r) MSG_task_receive_bounded(t,a,r) + XBT_PUBLIC(msg_comm_t) MSG_task_isend(msg_task_t task, const char *alias); XBT_PUBLIC(msg_comm_t) MSG_task_isend_bounded(msg_task_t task, const char *alias, double maxrate); XBT_PUBLIC(msg_comm_t) MSG_task_isend_with_matching(msg_task_t task, @@ -236,6 +252,7 @@ XBT_PUBLIC(msg_comm_t) MSG_task_isend_with_matching(msg_task_t task, XBT_PUBLIC(void) MSG_task_dsend(msg_task_t task, const char *alias, void_f_pvoid_t cleanup); XBT_PUBLIC(void) MSG_task_dsend_bounded(msg_task_t task, const char *alias, void_f_pvoid_t cleanup, double maxrate); XBT_PUBLIC(msg_comm_t) MSG_task_irecv(msg_task_t * task, const char *alias); +XBT_PUBLIC(msg_comm_t) MSG_task_irecv_bounded(msg_task_t * task, const char *alias, double rate); XBT_PUBLIC(int) MSG_comm_test(msg_comm_t comm); XBT_PUBLIC(int) MSG_comm_testany(xbt_dynar_t comms); XBT_PUBLIC(void) MSG_comm_destroy(msg_comm_t comm); diff --git a/include/simgrid/simix.h b/include/simgrid/simix.h index a856c0bc37..599746406a 100644 --- a/include/simgrid/simix.h +++ b/include/simgrid/simix.h @@ -409,6 +409,7 @@ XBT_PUBLIC(smx_action_t) simcall_comm_irecv(smx_rdv_t rdv, void *dst_buff, XBT_PUBLIC(void) simcall_comm_destroy(smx_action_t comm); XBT_PUBLIC(smx_action_t) simcall_comm_iprobe(smx_rdv_t rdv, int src, int tag, int (*match_fun)(void *, void *, smx_action_t), void *data); +XBT_PUBLIC(double) simcall_comm_change_rate_first_action(smx_rdv_t rdv, double newrate); XBT_PUBLIC(void) simcall_comm_cancel(smx_action_t comm); /* FIXME: waitany is going to be a vararg function, and should take a timeout */ diff --git a/src/msg/msg_gos.c b/src/msg/msg_gos.c index e37e0d7002..aeb6ad343b 100644 --- a/src/msg/msg_gos.c +++ b/src/msg/msg_gos.c @@ -199,6 +199,26 @@ MSG_task_receive_from_host(msg_task_t * task, const char *alias, return MSG_task_receive_ext(task, alias, -1, host); } +/** msg_task_usage + *\brief Deprecated function that used to receive a task from a mailbox from a specific host + *\brief at a given rate + * + * \param task a memory location for storing a #msg_task_t. + * \param alias name of the mailbox to receive the task from + * \param host a #msg_host_t host from where the task was sent + * \param rate limit the reception to rate bandwidth + * + * \return Returns + * #MSG_OK if the task was successfully received, + * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE otherwise. + */ +msg_error_t +MSG_task_receive_from_host_bounded(msg_task_t * task, const char *alias, + msg_host_t host, double rate) +{ + return MSG_task_receive_ext_bounded(task, alias, -1, host, rate); +} + /** \ingroup msg_task_usage * \brief Receives a task from a mailbox. * @@ -218,6 +238,22 @@ msg_error_t MSG_task_receive(msg_task_t * task, const char *alias) return MSG_task_receive_with_timeout(task, alias, -1); } +/** \ingroup msg_task_usage + * \brief Receives a task from a mailbox at a given rate. + * + * \param task a memory location for storing a #msg_task_t. + * \param alias name of the mailbox to receive the task from + * \param rate limit the reception to rate bandwidth + * + * \return Returns + * #MSG_OK if the task was successfully received, + * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE otherwise. + */ +msg_error_t MSG_task_receive_bounded(msg_task_t * task, const char *alias, double rate) +{ + return MSG_task_receive_with_timeout_bounded(task, alias, -1, rate); +} + /** \ingroup msg_task_usage * \brief Receives a task from a mailbox with a given timeout. * @@ -241,6 +277,25 @@ MSG_task_receive_with_timeout(msg_task_t * task, const char *alias, return MSG_task_receive_ext(task, alias, timeout, NULL); } +/** \ingroup msg_task_usage + * \brief Receives a task from a mailbox with a given timeout and at a given rate. + * + * \param task a memory location for storing a #msg_task_t. + * \param alias name of the mailbox to receive the task from + * \param timeout is the maximum wait time for completion (if -1, this call is the same as #MSG_task_receive) + * \param rate limit the reception to rate bandwidth + * + * \return Returns + * #MSG_OK if the task was successfully received, + * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE, or #MSG_TIMEOUT otherwise. + */ +msg_error_t +MSG_task_receive_with_timeout_bounded(msg_task_t * task, const char *alias, + double timeout,double rate) +{ + return MSG_task_receive_ext_bounded(task, alias, timeout, NULL,rate); +} + /** \ingroup msg_task_usage * \brief Receives a task from a mailbox from a specific host with a given timeout. * @@ -284,6 +339,31 @@ MSG_task_receive_ext(msg_task_t * task, const char *alias, double timeout, return ret; } +/** \ingroup msg_task_usage + * \brief Receives a task from a mailbox from a specific host with a given timeout + * and at a given rate. + * + * \param task a memory location for storing a #msg_task_t. + * \param alias name of the mailbox to receive the task from + * \param timeout is the maximum wait time for completion (provide -1 for no timeout) + * \param host a #msg_host_t host from where the task was sent + * \param rate limit the reception to rate bandwidth + * + * \return Returns + * #MSG_OK if the task was successfully received, +* #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE, or #MSG_TIMEOUT otherwise. + */ +msg_error_t +MSG_task_receive_ext_bounded(msg_task_t * task, const char *alias, double timeout, + msg_host_t host, double rate) +{ + XBT_DEBUG + ("MSG_task_receive_ext: Trying to receive a message on mailbox '%s'", + alias); + return MSG_mailbox_get_task_ext_bounded(MSG_mailbox_get_by_alias(alias), task, + host, timeout, rate); +} + /** \ingroup msg_task_usage * \brief Sends a task on a mailbox. * @@ -528,6 +608,40 @@ msg_comm_t MSG_task_irecv(msg_task_t *task, const char *name) return comm; } +/** \ingroup msg_task_usage + * \brief Starts listening for receiving a task from an asynchronous communication + * at a given rate. + * + * \param task a memory location for storing a #msg_task_t. has to be valid until the end of the communication. + * \param name of the mailbox to receive the task on + * \param rate limit the bandwidth to the given rate + * \return the msg_comm_t communication created + */ +msg_comm_t MSG_task_irecv_bounded(msg_task_t *task, const char *name, double rate) +{ + + + smx_rdv_t rdv = MSG_mailbox_get_by_alias(name); + simcall_comm_change_rate_first_action(rdv,rate); + /* FIXME: these functions are not traceable */ + + /* Sanity check */ + xbt_assert(task, "Null pointer for the task storage"); + + if (*task) + XBT_CRITICAL + ("MSG_task_irecv() was asked to write in a non empty task struct."); + + /* Try to receive it by calling SIMIX network layer */ + msg_comm_t comm = xbt_new0(s_msg_comm_t, 1); + comm->task_sent = NULL; + comm->task_received = task; + comm->status = MSG_OK; + comm->s_comm = simcall_comm_irecv(rdv, task, NULL, NULL, NULL); + + return comm; +} + /** \ingroup msg_task_usage * \brief Checks whether a communication is done, and if yes, finalizes it. * \param comm the communication to test diff --git a/src/msg/msg_mailbox.c b/src/msg/msg_mailbox.c index 1abbf0ee2d..15d9c3ff82 100644 --- a/src/msg/msg_mailbox.c +++ b/src/msg/msg_mailbox.c @@ -44,6 +44,10 @@ MSG_mailbox_get_count_host_waiting_tasks(msg_mailbox_t mailbox, return simcall_rdv_comm_count_by_host(mailbox, host); } +double MSG_set_rate_before_read(msg_mailbox_t mailbox, double newrate) { + return simcall_comm_change_rate_first_action(mailbox,newrate); +} + msg_mailbox_t MSG_mailbox_get_by_alias(const char *alias) { @@ -141,6 +145,30 @@ MSG_mailbox_get_task_ext(msg_mailbox_t mailbox, msg_task_t * task, MSG_RETURN(ret); } + + +/** \ingroup msg_mailbox_management + * \brief Get a task from a mailbox on a given host at a given rate + * + * \param mailbox The mailbox where the task was sent + * \param task a memory location for storing a #msg_task_t. + * \param host a #msg_host_t host from where the task was sent + * \param timeout a timeout + * \param rate a bandwidth rate + + * \return Returns + * #MSG_OK if the task was successfully received, + * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE otherwise. + */ +msg_error_t +MSG_mailbox_get_task_ext_bounded(msg_mailbox_t mailbox, msg_task_t * task, + msg_host_t host, double timeout, double rate) +{ + MSG_set_rate_before_read(mailbox,rate); + MSG_RETURN(MSG_mailbox_get_task_ext(mailbox,task,host,timeout)); +} + + msg_error_t MSG_mailbox_put_with_timeout(msg_mailbox_t mailbox, msg_task_t task, double timeout) diff --git a/src/msg/msg_mailbox.h b/src/msg/msg_mailbox.h index 9f3f37915c..ac387d6dc9 100644 --- a/src/msg/msg_mailbox.h +++ b/src/msg/msg_mailbox.h @@ -40,6 +40,13 @@ void MSG_mailbox_free(void *mailbox); */ void MSG_mailbox_free(void *mailbox); +/* \brief MSG_set_rate_before_read - set a rate before receiving a task + * + * \param mailbox The mailbox to release. + * \param rate The new rate + */ +double MSG_set_rate_before_read(msg_mailbox_t mailbox, double rate); + /* \brief MSG_mailbox_get_by_alias - get a mailbox from its alias. * * The function MSG_mailbox_get_by_alias returns the mailbox associated with diff --git a/src/simix/smx_user.c b/src/simix/smx_user.c index f01364295c..650f46b336 100644 --- a/src/simix/smx_user.c +++ b/src/simix/smx_user.c @@ -735,6 +735,29 @@ smx_action_t simcall_comm_irecv(smx_rdv_t rdv, void *dst_buff, size_t *dst_buff_ } +/** + * \ingroup simix_comm_management + */ +double simcall_comm_change_rate_first_action(smx_rdv_t rdv, double newrate) +{ + xbt_assert(rdv, "No rendez-vous point defined for change_rate_first_action"); + + smx_action_t action; + xbt_fifo_item_t item; + + item = xbt_fifo_get_first_item(rdv->comm_fifo); + if (item != NULL) { + action = (smx_action_t) xbt_fifo_get_item_content(item); + if (action->comm.rate > newrate) { + action->comm.rate = newrate; + return newrate; + } else + return action->comm.rate; + } else + return -1.0; +} + + /** * \ingroup simix_comm_management */ diff --git a/src/surf/instr_routing.c b/src/surf/instr_routing.c index c5fc21227f..285a03b1bd 100644 --- a/src/surf/instr_routing.c +++ b/src/surf/instr_routing.c @@ -160,60 +160,24 @@ static void recursiveGraphExtraction (AS_t rc, container_t container, xbt_dict_t } } - //let's get routes - xbt_dict_cursor_t cursor1 = NULL, cursor2 = NULL; - container_t child1, child2; - const char *child1_name, *child2_name; - xbt_dict_foreach(container->children, cursor1, child1_name, child1) { - //if child1 is not a link, a smpi node, a msg process, a msg vm or a msg task - if (child1->kind == INSTR_LINK || child1->kind == INSTR_SMPI || child1->kind == INSTR_MSG_PROCESS || child1->kind == INSTR_MSG_VM || child1->kind == INSTR_MSG_TASK) continue; - - xbt_dict_foreach(container->children, cursor2, child2_name, child2) { - //if child2 is not a link, a smpi node, a msg process, a msg vm or a msg task - if (child2->kind == INSTR_LINK || child2->kind == INSTR_SMPI || child2->kind == INSTR_MSG_PROCESS || child2->kind == INSTR_MSG_VM || child2->kind == INSTR_MSG_TASK) continue; - - //if child1 is not child2 - if (strcmp (child1_name, child2_name) == 0) continue; - - //get the route - sg_platf_route_cbarg_t route = xbt_new0(s_sg_platf_route_cbarg_t,1); - route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t),NULL); - rc->get_route_and_latency(rc, child1->net_elm, child2->net_elm, - route, NULL); - - //user might want to extract a graph using routes with only one link - //see --cfg=tracing/onelink_only:1 or --help-tracing for details - if (TRACE_onelink_only() && xbt_dynar_length (route->link_list) > 1){ - generic_free_route(route); - continue; - } + { + xbt_graph_t graph = xbt_graph_new_graph (0, NULL); + xbt_dict_t nodes = xbt_dict_new_homogeneous(NULL); + xbt_dict_t edges = xbt_dict_new_homogeneous(NULL); + xbt_edge_t edge = NULL; - //traverse the route connecting the containers - unsigned int cpt; - void *link; - container_t current, previous; - if (route->gw_src){ - previous = PJ_container_get(route->gw_src->name); - }else{ - previous = child1; - } + xbt_dict_cursor_t cursor = NULL; + char *edge_name; - xbt_dynar_foreach (route->link_list, cpt, link) { - //FIXME (TODO): Should have a cleaner way to get the link name - char *link_name = ((link_CM02_t)link)->lmm_resource.generic_resource.name; - current = PJ_container_get(link_name); - linkContainers(previous, current, filter); - previous = current; - } - if (route->gw_dst){ - current = PJ_container_get(route->gw_dst->name); - }else{ - current = child2; - } - linkContainers(previous, current, filter); - generic_free_route(route); + rc->get_graph(graph,nodes,edges,rc); + xbt_dict_foreach(edges,cursor,edge_name,edge) { + linkContainers(PJ_container_get(edge->src->data), PJ_container_get(edge->dst->data), filter); } + xbt_dict_free (&nodes); + xbt_dict_free (&edges); + xbt_graph_free_graph(graph,xbt_free, xbt_free, NULL); } + } /* @@ -498,41 +462,6 @@ int instr_platform_traced () #define GRAPHICATOR_SUPPORT_FUNCTIONS -static xbt_node_t new_xbt_graph_node (xbt_graph_t graph, const char *name, xbt_dict_t nodes) -{ - xbt_node_t ret = xbt_dict_get_or_null (nodes, name); - if (ret) return ret; - - ret = xbt_graph_new_node (graph, xbt_strdup(name)); - xbt_dict_set (nodes, name, ret, NULL); - return ret; -} - -static xbt_edge_t new_xbt_graph_edge (xbt_graph_t graph, xbt_node_t s, xbt_node_t d, xbt_dict_t edges) -{ - xbt_edge_t ret; - - const char *sn = instr_node_name (s); - const char *dn = instr_node_name (d); - int len = strlen(sn)+strlen(dn)+1; - char *name = (char*)xbt_malloc(len * sizeof(char)); - - - snprintf (name, len, "%s%s", sn, dn); - ret = xbt_dict_get_or_null (edges, name); - if (ret == NULL){ - snprintf (name, len, "%s%s", dn, sn); - ret = xbt_dict_get_or_null (edges, name); - } - - if (ret == NULL){ - ret = xbt_graph_new_edge(graph, s, d, NULL); - xbt_dict_set (edges, name, ret, NULL); - } - free (name); - return ret; -} - static void recursiveXBTGraphExtraction (xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges, AS_t rc, container_t container) { @@ -547,58 +476,7 @@ static void recursiveXBTGraphExtraction (xbt_graph_t graph, xbt_dict_t nodes, xb } } - //let's get routes - xbt_dict_cursor_t cursor1 = NULL, cursor2 = NULL; - container_t child1, child2; - const char *child1_name, *child2_name; - xbt_dict_foreach(container->children, cursor1, child1_name, child1) { - //if child1 is not a link, a smpi node, a msg process, a msg vm or a msg task - if (child1->kind == INSTR_LINK || child1->kind == INSTR_SMPI || child1->kind == INSTR_MSG_PROCESS || child1->kind == INSTR_MSG_VM || child1->kind == INSTR_MSG_TASK) continue; - - xbt_dict_foreach(container->children, cursor2, child2_name, child2) { - //if child2 is not a link, a smpi node, a msg process or a msg task - if (child2->kind == INSTR_LINK || child2->kind == INSTR_SMPI || child2->kind == INSTR_MSG_PROCESS || child2->kind == INSTR_MSG_VM || child2->kind == INSTR_MSG_TASK) continue; - - //if child1 is not child2 - if (strcmp (child1_name, child2_name) == 0) continue; - - //get the route - sg_platf_route_cbarg_t route = xbt_new0(s_sg_platf_route_cbarg_t,1); - route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t),NULL); - rc->get_route_and_latency(rc, child1->net_elm, child2->net_elm, - route, NULL); - - //user might want to extract a graph using routes with only one link - //see --cfg=tracing/onelink_only:1 or --help-tracing for details - if (TRACE_onelink_only() && xbt_dynar_length (route->link_list) > 1) continue; - - //traverse the route connecting the containers - unsigned int cpt; - void *link; - xbt_node_t current, previous; - if (route->gw_src){ - previous = new_xbt_graph_node(graph, route->gw_src->name, nodes); - }else{ - previous = new_xbt_graph_node(graph, child1_name, nodes); - } - - xbt_dynar_foreach (route->link_list, cpt, link) { - char *link_name = ((link_CM02_t)link)->lmm_resource.generic_resource.name; - current = new_xbt_graph_node(graph, link_name, nodes); - new_xbt_graph_edge (graph, previous, current, edges); - //previous -> current - previous = current; - } - if (route->gw_dst){ - current = new_xbt_graph_node(graph, route->gw_dst->name, nodes); - }else{ - current = new_xbt_graph_node(graph, child2_name, nodes); - } - new_xbt_graph_edge (graph, previous, current, edges); - generic_free_route(route); - } - } - + rc->get_graph(graph,nodes,edges,rc); } xbt_graph_t instr_routing_platform_graph (void) diff --git a/src/surf/surf_private.h b/src/surf/surf_private.h index 4732aa3b7e..c01d50b7eb 100644 --- a/src/surf/surf_private.h +++ b/src/surf/surf_private.h @@ -153,6 +153,7 @@ typedef struct s_as { void (*get_route_and_latency) (AS_t as, sg_routing_edge_t src, sg_routing_edge_t dst, sg_platf_route_cbarg_t into, double *latency); xbt_dynar_t(*get_onelink_routes) (AS_t as); + void (*get_graph) (xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges, AS_t rc); sg_platf_route_cbarg_t(*get_bypass_route) (AS_t as, sg_routing_edge_t src, sg_routing_edge_t dst, double *lat); void (*finalize) (AS_t as); @@ -192,6 +193,7 @@ XBT_PUBLIC(void) generic_free_route(sg_platf_route_cbarg_t route); // FIXME rena XBT_PUBLIC(void) routing_get_route_and_latency(sg_routing_edge_t src, sg_routing_edge_t dst, xbt_dynar_t * route, double *latency); +XBT_PUBLIC(void) generic_get_graph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges, AS_t rc); /** * Resource protected methods */ diff --git a/src/surf/surf_routing.c b/src/surf/surf_routing.c index cf77d3191d..8e25069cc7 100644 --- a/src/surf/surf_routing.c +++ b/src/surf/surf_routing.c @@ -920,6 +920,7 @@ static void routing_parse_cluster(sg_platf_cluster_cbarg_t cluster) bprintf("%s%s_router%s", cluster->prefix, cluster->id, cluster->suffix); sg_platf_new_router(&router); + ((as_cluster_t)current_routing)->router = xbt_lib_get_or_null(as_router_lib, router.id, ROUTING_ASR_LEVEL); free(newid); //Make the backbone diff --git a/src/surf/surf_routing_cluster.c b/src/surf/surf_routing_cluster.c index 37f2e326e7..ab45c3f4bb 100644 --- a/src/surf/surf_routing_cluster.c +++ b/src/surf/surf_routing_cluster.c @@ -4,6 +4,7 @@ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "surf_routing_private.h" +#include "xbt/graph.h" /* Global vars */ @@ -15,40 +16,215 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_cluster, surf, "Routing part of surf" /* Business methods */ static void cluster_get_route_and_latency(AS_t as, - sg_routing_edge_t src, sg_routing_edge_t dst, - sg_platf_route_cbarg_t route, double *lat) { + sg_routing_edge_t src, + sg_routing_edge_t dst, + sg_platf_route_cbarg_t route, + double *lat) +{ - s_surf_parsing_link_up_down_t info; - XBT_DEBUG("cluster_get_route_and_latency from '%s'[%d] to '%s'[%d]", - src->name,src->id, - dst->name,dst->id); - - if(src->rc_type != SURF_NETWORK_ELEMENT_ROUTER){ // No specific link for router - info = xbt_dynar_get_as(as->link_up_down_list,src->id,s_surf_parsing_link_up_down_t); - if(info.link_up) { // link up - xbt_dynar_push_as(route->link_list,void*,info.link_up); - if (lat) - *lat += surf_network_model->extension.network.get_link_latency(info.link_up); - } + s_surf_parsing_link_up_down_t info; + XBT_DEBUG("cluster_get_route_and_latency from '%s'[%d] to '%s'[%d]", + src->name, src->id, dst->name, dst->id); + + if (src->rc_type != SURF_NETWORK_ELEMENT_ROUTER) { // No specific link for router + info = + xbt_dynar_get_as(as->link_up_down_list, src->id, + s_surf_parsing_link_up_down_t); + if (info.link_up) { // link up + xbt_dynar_push_as(route->link_list, void *, info.link_up); + if (lat) + *lat += + surf_network_model->extension.network.get_link_latency(info. + link_up); } + } + + if (((as_cluster_t) as)->backbone) { + xbt_dynar_push_as(route->link_list, void *, ((as_cluster_t) as)->backbone); + if (lat) + *lat += + surf_network_model->extension.network. + get_link_latency(((as_cluster_t) as)->backbone); + } - if ( ((as_cluster_t)as)->backbone ) { - xbt_dynar_push_as(route->link_list,void*, ((as_cluster_t)as)->backbone) ; + if (dst->rc_type != SURF_NETWORK_ELEMENT_ROUTER) { // No specific link for router + info = + xbt_dynar_get_as(as->link_up_down_list, dst->id, + s_surf_parsing_link_up_down_t); + if (info.link_down) { // link down + xbt_dynar_push_as(route->link_list, void *, info.link_down); if (lat) - *lat += surf_network_model->extension.network.get_link_latency(((as_cluster_t)as)->backbone); + *lat += + surf_network_model->extension.network.get_link_latency(info. + link_down); } + } +} + +static void cluster_get_graph(xbt_graph_t graph, xbt_dict_t nodes, + xbt_dict_t edges, AS_t rc) +{ + int isrc; + int table_size = xbt_dynar_length(rc->index_network_elm); + + sg_routing_edge_t src, dst; + xbt_node_t current, previous, backboneNode,routerNode; + s_surf_parsing_link_up_down_t info; + + xbt_assert(((as_cluster_t) rc)->router,"Malformed cluster"); + + /* create the router */ + char *link_name = + ((sg_routing_edge_t) ((as_cluster_t) rc)->router)->name; + routerNode = new_xbt_graph_node(graph, link_name, nodes); + + if(((as_cluster_t) rc)->backbone) { + char *link_nameR = + ((surf_resource_t) ((as_cluster_t) rc)->backbone)->name; + backboneNode = new_xbt_graph_node(graph, link_nameR, nodes); + + new_xbt_graph_edge(graph, routerNode, backboneNode, edges); + } + + for (isrc = 0; isrc < table_size; isrc++) { + src = xbt_dynar_get_as(rc->index_network_elm, isrc, sg_routing_edge_t); + + if (src->rc_type != SURF_NETWORK_ELEMENT_ROUTER) { + previous = new_xbt_graph_node(graph, src->name, nodes); + + info = xbt_dynar_get_as(rc->link_up_down_list, src->id, + s_surf_parsing_link_up_down_t); + + if (info.link_up) { // link up + + char *link_name = ((surf_resource_t) info.link_up)->name; + current = new_xbt_graph_node(graph, link_name, nodes); + new_xbt_graph_edge(graph, previous, current, edges); + + if (((as_cluster_t) rc)->backbone) { + new_xbt_graph_edge(graph, current, backboneNode, edges); + } else { + new_xbt_graph_edge(graph, current, routerNode, edges); + } + + } + + if (info.link_down) { // link down + char *link_name = ((surf_resource_t) info.link_down)->name; + current = new_xbt_graph_node(graph, link_name, nodes); + new_xbt_graph_edge(graph, previous, current, edges); - if(dst->rc_type != SURF_NETWORK_ELEMENT_ROUTER){ // No specific link for router - info = xbt_dynar_get_as(as->link_up_down_list,dst->id,s_surf_parsing_link_up_down_t); - if(info.link_down) { // link down - xbt_dynar_push_as(route->link_list,void*,info.link_down); - if (lat) - *lat += surf_network_model->extension.network.get_link_latency(info.link_down); + if (((as_cluster_t) rc)->backbone) { + new_xbt_graph_edge(graph, current, backboneNode, edges); + } else { + new_xbt_graph_edge(graph, current, routerNode, edges); + } + + } + } + } + +/* + if (((as_cluster_t) rc)->backbone) { + char *link_name = + ((surf_resource_t) ((as_cluster_t) rc)->backbone)->name; + + current = new_xbt_graph_node(graph, link_name, nodes); + new_xbt_graph_edge(graph, previous, current, edges); + previous = current; + + revCurrent = new_xbt_graph_node(graph, link_name, nodes); + new_xbt_graph_edge(graph, revCurrent, revPrevious, edges); + revPrevious = revCurrent; + } else { + info = xbt_dynar_get_as(rc->link_up_down_list, dst->id, + s_surf_parsing_link_up_down_t); + + if (info.link_up) { // link up + char *link_name = ((surf_resource_t) info.link_up)->name; + current = new_xbt_graph_node(graph, link_name, nodes); + new_xbt_graph_edge(graph, previous, current, edges); + previous = current; + } else if (info.link_down) { // link down + char *link_name = ((surf_resource_t) info.link_down)->name; + revCurrent = new_xbt_graph_node(graph, link_name, nodes); + new_xbt_graph_edge(graph, revCurrent, revPrevious, edges); + revPrevious = revCurrent; + } + } + + } + }*/ +/* + if(rc->) + for (isrc = 0; isrc < table_size; isrc++) { + src = xbt_dynar_get_as(rc->index_network_elm, isrc, sg_routing_edge_t); + + previous = new_xbt_graph_node(graph, src->name, nodes); + revPrevious = new_xbt_graph_node(graph, src->name, nodes); + + for (idst = isrc + 1; idst < table_size; idst++) { + dst = xbt_dynar_get_as(rc->index_network_elm, idst, sg_routing_edge_t); + + s_surf_parsing_link_up_down_t info; + + if (src->rc_type != SURF_NETWORK_ELEMENT_ROUTER) { // No specific link for router + info = + xbt_dynar_get_as(rc->link_up_down_list, src->id, + s_surf_parsing_link_up_down_t); + + if (info.link_up) { // link up + char *link_name = ((surf_resource_t) info.link_up)->name; + current = new_xbt_graph_node(graph, link_name, nodes); + new_xbt_graph_edge(graph, previous, current, edges); + previous = current; + } else if (info.link_down) { // link down + char *link_name = ((surf_resource_t) info.link_down)->name; + revCurrent = new_xbt_graph_node(graph, link_name, nodes); + new_xbt_graph_edge(graph, revCurrent, revPrevious, edges); + revPrevious = revCurrent; } + } + + + + if (((as_cluster_t) rc)->backbone) { + char *link_name = + ((surf_resource_t) ((as_cluster_t) rc)->backbone)->name; + + current = new_xbt_graph_node(graph, link_name, nodes); + new_xbt_graph_edge(graph, previous, current, edges); + previous = current; + + revCurrent = new_xbt_graph_node(graph, link_name, nodes); + new_xbt_graph_edge(graph, revCurrent, revPrevious, edges); + revPrevious = revCurrent; + } + + if (dst->rc_type != SURF_NETWORK_ELEMENT_ROUTER) { // No specific link for router + info = + xbt_dynar_get_as(rc->link_up_down_list, dst->id, + s_surf_parsing_link_up_down_t); + + if (info.link_up) { // link up + char *link_name = ((surf_resource_t) info.link_up)->name; + current = new_xbt_graph_node(graph, link_name, nodes); + new_xbt_graph_edge(graph, previous, current, edges); + previous = current; + } else if (info.link_down) { // link down + char *link_name = ((surf_resource_t) info.link_down)->name; + revCurrent = new_xbt_graph_node(graph, link_name, nodes); + new_xbt_graph_edge(graph, revCurrent, revPrevious, edges); + revPrevious = revCurrent; + } + } + } + }*/ } -static void model_cluster_finalize(AS_t as) { +static void model_cluster_finalize(AS_t as) +{ model_none_finalize(as); } @@ -70,6 +246,7 @@ AS_t model_cluster_create(void) AS_t result = model_none_create_sized(sizeof(s_as_cluster_t)); result->get_route_and_latency = cluster_get_route_and_latency; result->finalize = model_cluster_finalize; + result->get_graph = cluster_get_graph; result->parse_AS = cluster_parse_AS; result->parse_PU = cluster_parse_PU; diff --git a/src/surf/surf_routing_dijkstra.c b/src/surf/surf_routing_dijkstra.c index 7d7eac4d63..4b0d4c96b1 100644 --- a/src/surf/surf_routing_dijkstra.c +++ b/src/surf/surf_routing_dijkstra.c @@ -156,8 +156,7 @@ static void add_loopback_dijkstra(as_dijkstra_t as) { if (!found) { sg_platf_route_cbarg_t e_route = xbt_new0(s_sg_platf_route_cbarg_t, 1); e_route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL); - xbt_dynar_push(e_route->link_list, - &routing_platf->loopback); + xbt_dynar_push(e_route->link_list, &routing_platf->loopback); xbt_graph_new_edge(as->route_graph, node, node, e_route); } } @@ -420,6 +419,7 @@ AS_t model_dijkstra_both_create(int cached) new_component->generic_routing.get_route_and_latency = dijkstra_get_route_and_latency; new_component->generic_routing.get_onelink_routes = dijkstra_get_onelink_routes; + new_component->generic_routing.get_graph = generic_get_graph; new_component->generic_routing.finalize = dijkstra_finalize; new_component->cached = cached; diff --git a/src/surf/surf_routing_floyd.c b/src/surf/surf_routing_floyd.c index 5bce7d4548..0f08c52a98 100644 --- a/src/surf/surf_routing_floyd.c +++ b/src/surf/surf_routing_floyd.c @@ -146,6 +146,7 @@ AS_t model_floyd_create(void) new_component->generic_routing.get_route_and_latency = floyd_get_route_and_latency; new_component->generic_routing.get_onelink_routes = floyd_get_onelink_routes; + new_component->generic_routing.get_graph = generic_get_graph; new_component->generic_routing.finalize = floyd_finalize; return (AS_t)new_component; } diff --git a/src/surf/surf_routing_full.c b/src/surf/surf_routing_full.c index 71cdfc643c..0fb34221c7 100644 --- a/src/surf/surf_routing_full.c +++ b/src/surf/surf_routing_full.c @@ -115,6 +115,8 @@ AS_t model_full_create(void) new_component->generic_routing.parse_ASroute = model_full_set_route; new_component->generic_routing.get_route_and_latency = full_get_route_and_latency; + new_component->generic_routing.get_graph = generic_get_graph; + new_component->generic_routing.get_onelink_routes = full_get_onelink_routes; new_component->generic_routing.finalize = full_finalize; diff --git a/src/surf/surf_routing_generic.c b/src/surf/surf_routing_generic.c index 177c0922e6..e6192c641e 100644 --- a/src/surf/surf_routing_generic.c +++ b/src/surf/surf_routing_generic.c @@ -9,6 +9,7 @@ #include "surf_routing_private.h" #include "surf/surf_routing.h" #include "surf/surfxml_parse_values.h" +#include "xbt/graph.h" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_routing_generic, surf_route, "Generic implementation of the surf routing"); @@ -91,11 +92,109 @@ xbt_dynar_t generic_get_onelink_routes(AS_t rc) { // FIXME: kill that stub return NULL; } -sg_platf_route_cbarg_t generic_get_bypassroute(AS_t rc, sg_routing_edge_t src, sg_routing_edge_t dst, double *lat) +static const char *instr_node_name(xbt_node_t node) +{ + void *data = xbt_graph_node_get_data(node); + char *str = (char *) data; + return str; +} + +xbt_node_t new_xbt_graph_node(xbt_graph_t graph, const char *name, + xbt_dict_t nodes) +{ + xbt_node_t ret = xbt_dict_get_or_null(nodes, name); + if (ret) + return ret; + + ret = xbt_graph_new_node(graph, xbt_strdup(name)); + xbt_dict_set(nodes, name, ret, NULL); + return ret; +} + +xbt_edge_t new_xbt_graph_edge(xbt_graph_t graph, xbt_node_t s, xbt_node_t d, + xbt_dict_t edges) +{ + xbt_edge_t ret; + + const char *sn = instr_node_name(s); + const char *dn = instr_node_name(d); + int len = strlen(sn) + strlen(dn) + 1; + char *name = (char *) xbt_malloc(len * sizeof(char)); + + + snprintf(name, len, "%s%s", sn, dn); + ret = xbt_dict_get_or_null(edges, name); + if (ret == NULL) { + snprintf(name, len, "%s%s", dn, sn); + ret = xbt_dict_get_or_null(edges, name); + } + + if (ret == NULL) { + ret = xbt_graph_new_edge(graph, s, d, NULL); + xbt_dict_set(edges, name, ret, NULL); + } + free(name); + return ret; +} + +void generic_get_graph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges, + AS_t rc) +{ + int src, dst; + int table_size = xbt_dynar_length(rc->index_network_elm); + + sg_platf_route_cbarg_t route = xbt_new0(s_sg_platf_route_cbarg_t, 1); + route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL); + + for (src = 0; src < table_size; src++) { + sg_routing_edge_t my_src = + xbt_dynar_get_as(rc->index_network_elm, src, sg_routing_edge_t); + for (dst = 0; dst < table_size; dst++) { + if (src == dst) + continue; + sg_routing_edge_t my_dst = + xbt_dynar_get_as(rc->index_network_elm, dst, sg_routing_edge_t); + + rc->get_route_and_latency(rc, my_src, my_dst, route, NULL); + + if (route) { + unsigned int cpt; + void *link; + + xbt_node_t current, previous; + + if (route->gw_src) { + previous = new_xbt_graph_node(graph, route->gw_src->name, nodes); + } else { + previous = new_xbt_graph_node(graph, my_src->name, nodes); + } + + xbt_dynar_foreach(route->link_list, cpt, link) { + char *link_name = ((surf_resource_t) link)->name; + current = new_xbt_graph_node(graph, link_name, nodes); + new_xbt_graph_edge(graph, previous, current, edges); + previous = current; + } + + if (route->gw_dst) { + current = new_xbt_graph_node(graph, route->gw_dst->name, nodes); + } else { + current = new_xbt_graph_node(graph, my_dst->name, nodes); + } + new_xbt_graph_edge(graph, previous, current, edges); + + } + } + } +} + +sg_platf_route_cbarg_t generic_get_bypassroute(AS_t rc, sg_routing_edge_t src, + sg_routing_edge_t dst, + double *lat) { // 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(no_bypassroute_declared) + XBT_DEBUG("generic_get_bypassroute from %s to %s", src->name, dst->name); + if (no_bypassroute_declared) return NULL; sg_platf_route_cbarg_t e_route_bypass = NULL; diff --git a/src/surf/surf_routing_none.c b/src/surf/surf_routing_none.c index 1f403c8f42..46d667bdd8 100644 --- a/src/surf/surf_routing_none.c +++ b/src/surf/surf_routing_none.c @@ -18,6 +18,11 @@ static void none_get_route_and_latency(AS_t rc, sg_routing_edge_t src, sg_routin *lat = 0.0; } +static void none_get_graph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges, AS_t rc) +{ + XBT_INFO("No routing no graph"); +} + static sg_platf_route_cbarg_t none_get_bypass_route(AS_t rc, sg_routing_edge_t src, sg_routing_edge_t dst, double *lat) { @@ -53,6 +58,7 @@ AS_t model_none_create_sized(size_t childsize) { new_component->get_onelink_routes = none_get_onelink_routes; new_component->get_bypass_route = none_get_bypass_route; new_component->finalize = model_none_finalize; + new_component->get_graph = none_get_graph; new_component->routing_sons = xbt_dict_new_homogeneous(NULL); new_component->index_network_elm = xbt_dynar_new(sizeof(char*),NULL); diff --git a/src/surf/surf_routing_private.h b/src/surf/surf_routing_private.h index cdc5fb4e34..c1369d03d9 100644 --- a/src/surf/surf_routing_private.h +++ b/src/surf/surf_routing_private.h @@ -57,7 +57,6 @@ generic_processing_units_exist(AS_t rc, char *element); void generic_src_dst_check(AS_t rc, sg_routing_edge_t src, sg_routing_edge_t dst); - /* ************************************************************************** */ /* *************************** FLOYD ROUTING ******************************** */ AS_t model_floyd_create(void); /* create structures for floyd routing model */ @@ -73,6 +72,7 @@ AS_t model_rulebased_create(void); /* create structures for rulebased routi typedef struct { s_as_t generic_routing; void *backbone; + sg_routing_edge_t router; } s_as_cluster_t, *as_cluster_t; AS_t model_cluster_create(void); /* create structures for cluster routing model */ @@ -98,6 +98,10 @@ AS_t model_full_create(void); /* create structures for full routing model */ void model_full_end(AS_t as); /* finalize the creation of full routing model */ void model_full_set_route( /* Set the route and ASroute between src and dst */ AS_t rc, sg_platf_route_cbarg_t route); +/* ************************************************************************** */ +/* ************************* GRAPH EXPORTING FUNCTIONS ********************** */ +xbt_node_t new_xbt_graph_node (xbt_graph_t graph, const char *name, xbt_dict_t nodes); +xbt_edge_t new_xbt_graph_edge (xbt_graph_t graph, xbt_node_t s, xbt_node_t d, xbt_dict_t edges); #endif /* _SURF_SURF_ROUTING_PRIVATE_H */ diff --git a/src/surf/surf_routing_rulebased.c b/src/surf/surf_routing_rulebased.c index 53d87be2ae..2c69fc9d81 100644 --- a/src/surf/surf_routing_rulebased.c +++ b/src/surf/surf_routing_rulebased.c @@ -64,14 +64,14 @@ static void rule_route_extended_free(void *e) static int model_rulebased_parse_PU(AS_t rc, sg_routing_edge_t elm) { AS_rulebased_t routing = (AS_rulebased_t) rc; - xbt_dynar_push(routing->generic_routing.index_network_elm,(void *)elm); + xbt_dynar_push(routing->generic_routing.index_network_elm,&elm); return -1; } static int model_rulebased_parse_AS(AS_t rc, sg_routing_edge_t elm) { AS_rulebased_t routing = (AS_rulebased_t) rc; - xbt_dynar_push(routing->generic_routing.index_network_elm,(void *)elm); + xbt_dynar_push(routing->generic_routing.index_network_elm,&elm); return -1; } @@ -394,6 +394,7 @@ AS_t model_rulebased_create(void) { new_component->generic_routing.get_onelink_routes = rulebased_get_onelink_routes; new_component->generic_routing.get_route_and_latency = rulebased_get_route_and_latency; new_component->generic_routing.get_bypass_route = rulebased_get_bypass_route; + new_component->generic_routing.get_graph = generic_get_graph; new_component->generic_routing.finalize = rulebased_finalize; /* initialization of internal structures */ new_component->list_route = xbt_dynar_new(sizeof(rule_route_t), &rule_route_free); diff --git a/src/surf/surf_routing_vivaldi.c b/src/surf/surf_routing_vivaldi.c index 2079a80a2b..ed8a80cc3c 100644 --- a/src/surf/surf_routing_vivaldi.c +++ b/src/surf/surf_routing_vivaldi.c @@ -105,5 +105,6 @@ AS_t model_vivaldi_create(void) AS_t new_component = model_rulebased_create(); new_component->get_route_and_latency = vivaldi_get_route_and_latency; new_component->parse_PU = vivaldi_parse_PU; + new_component->get_graph = generic_get_graph; return new_component; }