Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
c46d31213cf48d689e547f3926e9c689a4292e61
[simgrid.git] / src / surf / surf_routing.c
1 /* Copyright (c) 2009 The SimGrid team. All rights reserved.                */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include "surf_private.h"
7 #include "xbt/dynar.h"
8 #include "xbt/str.h"
9
10 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route,surf,"Routing part of surf");// FIXME: connect this under windows
11
12 typedef struct {
13   s_routing_t generic_routing;
14   xbt_dynar_t *routing_table;
15   void *loopback;
16   size_t size_of_link;
17 }s_routing_full_t,*routing_full_t;
18
19 routing_t used_routing = NULL;
20 /* ************************************************************************** */
21 /* *************************** FULL ROUTING ********************************* */
22
23 #define ROUTE_FULL(i,j) ((routing_full_t)used_routing)->routing_table[(i)+(j)*(used_routing)->host_count]
24
25 /*
26  * Parsing
27  */
28 static void routing_full_parse_Shost(void) {
29   int *val = xbt_malloc(sizeof(int));
30   DEBUG2("Seen host %s (#%d)",A_surfxml_host_id,used_routing->host_count);
31   *val = used_routing->host_count++;
32   xbt_dict_set(used_routing->host_id,A_surfxml_host_id,val,xbt_free);
33 }
34 static int src_id = -1;
35 static int dst_id = -1;
36 static void routing_full_parse_Sroute_set_endpoints(void)
37 {
38   src_id = *(int*)xbt_dict_get(used_routing->host_id,A_surfxml_route_src);
39   dst_id = *(int*)xbt_dict_get(used_routing->host_id,A_surfxml_route_dst);
40   DEBUG4("Route %s %d -> %s %d",A_surfxml_route_src,src_id,A_surfxml_route_dst,dst_id);
41   route_action = A_surfxml_route_action;
42 }
43 static void routing_full_parse_Eroute(void)
44 {
45   char *name;
46   if (src_id != -1 && dst_id != -1) {
47     name = bprintf("%x#%x", src_id, dst_id);
48     manage_route(route_table, name, route_action, 0);
49     free(name);
50   }
51 }
52
53
54 static void routing_full_parse_end(void) {
55   routing_full_t routing = (routing_full_t) used_routing;
56   int nb_link = 0;
57   unsigned int cpt = 0;
58   xbt_dict_cursor_t cursor = NULL;
59   char *key, *data, *end;
60   const char *sep = "#";
61   xbt_dynar_t links, keys;
62   char *link_name = NULL;
63   int i,j;
64
65   int host_count = routing->generic_routing.host_count;
66
67   /* Create the routing table */
68   routing->routing_table = xbt_new0(xbt_dynar_t, host_count * host_count);
69   for (i=0;i<host_count;i++)
70     for (j=0;j<host_count;j++)
71       ROUTE_FULL(i,j) = xbt_dynar_new(routing->size_of_link,NULL);
72
73   /* Put the routes in position */
74   xbt_dict_foreach(route_table, cursor, key, data) {
75     nb_link = 0;
76     links = (xbt_dynar_t) data;
77     keys = xbt_str_split_str(key, sep);
78
79     src_id = strtol(xbt_dynar_get_as(keys, 0, char *), &end, 16);
80     dst_id = strtol(xbt_dynar_get_as(keys, 1, char *), &end, 16);
81     xbt_dynar_free(&keys);
82
83     DEBUG4("Handle %d %d (from %d hosts): %ld links",
84         src_id,dst_id,routing->generic_routing.host_count,xbt_dynar_length(links));
85     xbt_dynar_foreach(links, cpt, link_name) {
86       void* link = xbt_dict_get_or_null(surf_network_model->resource_set, link_name);
87       if (link)
88         xbt_dynar_push(ROUTE_FULL(src_id,dst_id),&link);
89       else
90         THROW1(mismatch_error,0,"Link %s not found", link_name);
91     }
92   }
93
94   /* Add the loopback if needed */
95   for (i = 0; i < host_count; i++)
96     if (!xbt_dynar_length(ROUTE_FULL(i, i)))
97       xbt_dynar_push(ROUTE_FULL(i,i),&routing->loopback);
98
99   /* Shrink the dynar routes (save unused slots) */
100   for (i=0;i<host_count;i++)
101     for (j=0;j<host_count;j++)
102       xbt_dynar_shrink(ROUTE_FULL(i,j),0);
103 }
104
105 /*
106  * Business methods
107  */
108 static xbt_dynar_t routing_full_get_route(int src,int dst) {
109   return ROUTE_FULL(src,dst);
110 }
111
112 static void routing_full_finalize(void) {
113   routing_full_t routing = (routing_full_t)used_routing;
114   int i,j;
115
116   if (routing) {
117     for (i = 0; i < used_routing->host_count; i++)
118       for (j = 0; j < used_routing->host_count; j++)
119         xbt_dynar_free(&ROUTE_FULL(i, j));
120     free(routing->routing_table);
121     xbt_dict_free(&used_routing->host_id);
122     free(routing);
123     routing=NULL;
124   }
125 }
126
127 routing_t routing_model_full_create(size_t size_of_link,void *loopback) {
128   /* initialize our structure */
129   routing_full_t res = xbt_new0(s_routing_full_t,1);
130   res->generic_routing.name = "Full";
131   res->generic_routing.host_count = 0;
132   res->generic_routing.get_route = routing_full_get_route;
133   res->generic_routing.finalize = routing_full_finalize;
134   res->size_of_link = size_of_link;
135   res->loopback = loopback;
136
137   /* Set it in position */
138   used_routing = (routing_t) res;
139
140   /* Setup the parsing callbacks we need */
141   used_routing->host_id = xbt_dict_new();
142   surfxml_add_callback(STag_surfxml_host_cb_list, &routing_full_parse_Shost);
143   surfxml_add_callback(ETag_surfxml_platform_cb_list, &routing_full_parse_end);
144   surfxml_add_callback(STag_surfxml_route_cb_list,
145                        &routing_full_parse_Sroute_set_endpoints);
146   surfxml_add_callback(ETag_surfxml_route_cb_list, &routing_full_parse_Eroute);
147
148   return used_routing;
149 }