Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Change some function names
[simgrid.git] / src / simdag / sd_workstation.c
1 #include "private.h"
2 #include "simdag/simdag.h"
3 #include "xbt/dict.h"
4 #include "xbt/sysdep.h"
5 #include "surf/surf.h"
6
7 /* Creates a workstation and registers it in SD.
8  */
9 SD_workstation_t __SD_workstation_create(void *surf_workstation, void *data) {
10   SD_CHECK_INIT_DONE();
11   xbt_assert0(surf_workstation != NULL, "surf_workstation is NULL !");
12
13   SD_workstation_t workstation = xbt_new0(s_SD_workstation_t, 1);
14   workstation->surf_workstation = surf_workstation;
15   workstation->data = data; /* user data */
16   
17   const char *name = SD_workstation_get_name(workstation);
18   xbt_dict_set(sd_global->workstations, name, workstation, __SD_workstation_destroy); /* add the workstation to the dictionary */
19   sd_global->workstation_count++;
20
21   return workstation;
22 }
23
24 /**
25  * \brief Returns a workstation given its name
26  *
27  * If there is no such workstation, the function returns \c NULL.
28  *
29  * \param name workstation name
30  * \return the workstation, or \c NULL if there is no such workstation
31  */
32 SD_workstation_t SD_workstation_get_by_name(const char *name) {
33   SD_CHECK_INIT_DONE();
34
35   xbt_assert0(name != NULL, "Invalid parameter");
36
37   return xbt_dict_get_or_null(sd_global->workstations, name);
38 }
39
40 /**
41  * \brief Returns the workstation list
42  *
43  * Use SD_workstation_get_number() to know the array size.
44  *
45  * \return an array of \ref SD_workstation_t containing all workstations
46  * \see SD_workstation_get_number()
47  */
48 const SD_workstation_t*  SD_workstation_get_list(void) {
49   SD_CHECK_INIT_DONE();
50   xbt_assert0(SD_workstation_get_number() > 0, "There is no workstation!");
51
52   SD_workstation_t *array = sd_global->workstation_list;
53   xbt_dict_cursor_t cursor;
54   char *key;
55   void *data;
56   int i;
57
58   if (array == NULL) { /* this is the first time the function is called */
59     array = xbt_new0(SD_workstation_t, sd_global->workstation_count);
60   
61     i = 0;
62     xbt_dict_foreach(sd_global->workstations, cursor, key, data) {
63       array[i++] = (SD_workstation_t) data;
64     }
65   }
66   return array;
67 }
68
69 /**
70  * \brief Returns the number of workstations
71  *
72  * \return the number of existing workstations
73  * \see SD_workstation_get_list()
74  */
75 int SD_workstation_get_number(void) {
76   SD_CHECK_INIT_DONE();
77   return sd_global->workstation_count;
78 }
79
80 /**
81  * \brief Returns the user data of a workstation
82  *
83  * \param workstation a workstation
84  * \return the user data associated with this workstation (can be \c NULL)
85  * \see SD_workstation_set_data()
86  */
87 void* SD_workstation_get_data(SD_workstation_t workstation) {
88   SD_CHECK_INIT_DONE();
89   xbt_assert0(workstation != NULL, "Invalid parameter");
90   return workstation->data;
91 }
92
93 /**
94  * \brief Sets the user data of a workstation
95  *
96  * The new data can be \c NULL. The old data should have been freed first
97  * if it was not \c NULL.
98  *
99  * \param workstation a workstation
100  * \param data the new data you want to associate with this workstation
101  * \see SD_workstation_get_data()
102  */
103 void SD_workstation_set_data(SD_workstation_t workstation, void *data) {
104   SD_CHECK_INIT_DONE();
105   xbt_assert0(workstation != NULL, "Invalid parameter");
106   workstation->data = data;
107 }
108
109 /**
110  * \brief Returns the name of a workstation
111  *
112  * \param workstation a workstation
113  * \return the name of this workstation (cannot be \c NULL)
114  */
115 const char* SD_workstation_get_name(SD_workstation_t workstation) {
116   SD_CHECK_INIT_DONE();
117   xbt_assert0(workstation != NULL, "Invalid parameter");
118   return surf_workstation_resource->common_public->get_resource_name(workstation->surf_workstation);
119 }
120
121 /**
122  * \brief Returns the route between two workstations
123  *
124  * Use SD_route_get_size() to know the array size. Don't forget to free the array after use.
125  *
126  * \param src a workstation
127  * \param dst another workstation
128  * \return a new array of \ref SD_link_t representating the route between these two workstations
129  * \see SD_route_get_size(), SD_link_t
130  */
131 SD_link_t* SD_route_get_list(SD_workstation_t src, SD_workstation_t dst) {
132   SD_CHECK_INIT_DONE();
133
134   void *surf_src = src->surf_workstation;
135   void *surf_dst = dst->surf_workstation;
136
137   const void **surf_route = surf_workstation_resource->extension_public->get_route(surf_src, surf_dst);
138   int route_size = surf_workstation_resource->extension_public->get_route_size(surf_src, surf_dst);
139
140   SD_link_t* route = xbt_new0(SD_link_t, route_size);
141   const char *link_name;
142   int i;
143   for (i = 0; i < route_size; i++) {
144     link_name = surf_workstation_resource->extension_public->get_link_name(surf_route[i]);
145     route[i] = xbt_dict_get(sd_global->links, link_name);
146   }
147
148   return route;
149 }
150
151 /**
152  * \brief Returns the number of links on the route between two workstations
153  *
154  * \param src a workstation
155  * \param dst another workstation
156  * \return the number of links on the route between these two workstations
157  * \see SD_route_get_list()
158  */
159 int SD_route_get_size(SD_workstation_t src, SD_workstation_t dst) {
160   SD_CHECK_INIT_DONE();
161   return surf_workstation_resource->extension_public->
162     get_route_size(src->surf_workstation, dst->surf_workstation);
163 }
164
165 /**
166  * \brief Returns the total power of a workstation
167  *
168  * \param workstation a workstation
169  * \return the total power of this workstation
170  * \see SD_workstation_get_available_power()
171  */
172 double SD_workstation_get_power(SD_workstation_t workstation) {
173   SD_CHECK_INIT_DONE();
174   xbt_assert0(workstation != NULL, "Invalid parameter");
175   return surf_workstation_resource->extension_public->get_speed(workstation->surf_workstation, 1.0);
176 }
177
178 /**
179  * \brief Returns the proportion of available power in a workstation
180  *
181  * \param workstation a workstation
182  * \return the proportion of power currently available in this workstation (normally a number between 0 and 1)
183  * \see SD_workstation_get_power()
184  */
185 double SD_workstation_get_available_power(SD_workstation_t workstation) {
186   SD_CHECK_INIT_DONE();
187   xbt_assert0(workstation != NULL, "Invalid parameter");
188   return surf_workstation_resource->extension_public->get_available_speed(workstation->surf_workstation);
189 }
190
191 /**
192  * \brief Returns an approximative estimated time for the given computation amount on a workstation
193  *
194  * \param workstation a workstation
195  * \param computation_amount the computation amount you want to evaluate (in flops)
196  * \return an approximative astimated computation time for the given computation amount on this workstation (in seconds)
197  */
198 double SD_workstation_get_computation_time(SD_workstation_t workstation, double computation_amount) {
199   SD_CHECK_INIT_DONE();
200   xbt_assert0(workstation != NULL, "Invalid parameter");
201   xbt_assert0(computation_amount >= 0, "computation_amount must be greater than or equal to zero");
202   return computation_amount / SD_workstation_get_power(workstation);
203 }
204
205 /**
206  * \brief Returns the latency of the route between two workstations, i.e. the sum of all link latencies
207  * between the workstations.
208  *
209  * \param src the first workstation
210  * \param dst the second workstation
211  * \return the latency of the route between the two workstations (in seconds)
212  * \see SD_route_get_current_bandwidth()
213  */
214 double SD_route_get_current_latency(SD_workstation_t src, SD_workstation_t dst) {
215   SD_CHECK_INIT_DONE();
216   xbt_assert0(src != NULL && dst != NULL, "Invalid parameter");
217   SD_link_t *links = SD_route_get_list(src, dst);
218   int nb_links = SD_route_get_size(src, dst);
219   double latency = 0.0;
220   int i;
221   
222   for (i = 0; i < nb_links; i++) {
223     latency += SD_link_get_current_latency(links[i]);
224   }
225
226   free(links);
227   return latency;
228 }
229
230 /**
231  * \brief Returns the bandwidth of the route between two workstations, i.e. the minimum link bandwidth of all
232  * between the workstations.
233  *
234  * \param src the first workstation
235  * \param dst the second workstation
236  * \return the bandwidth of the route between the two workstations (in bytes/second)
237  * \see SD_route_get_current_latency()
238  */
239 double SD_route_get_current_bandwidth(SD_workstation_t src, SD_workstation_t dst) {
240   SD_CHECK_INIT_DONE();
241   xbt_assert0(src != NULL && dst != NULL, "Invalid parameter");
242   SD_link_t *links = SD_route_get_list(src, dst);
243   int nb_links = SD_route_get_size(src, dst);
244   double bandwidth, min_bandwidth = -1.0;
245   int i;
246   
247   for (i = 0; i < nb_links; i++) {
248     bandwidth = SD_link_get_current_bandwidth(links[i]);
249     if (bandwidth < min_bandwidth || min_bandwidth == -1.0)
250       min_bandwidth = bandwidth;
251   }
252
253   free(links);
254   return min_bandwidth;
255 }
256
257 /**
258  * \brief Returns an approximative estimated time for the given
259  * communication amount between two workstations
260  *
261  * \param src the first workstation
262  * \param dst the second workstation
263  * \param communication_amount the communication amount you want to evaluate (in bytes)
264  * \return an approximative astimated computation time for the given communication amount
265  * between the workstations (in seconds)
266  */
267 double SD_route_get_communication_time(SD_workstation_t src, SD_workstation_t dst,
268                                                    double communication_amount) {
269   /* total time = latency + transmission time of the slowest link
270      transmission time of a link = communication amount / link bandwidth */
271   SD_CHECK_INIT_DONE();
272   xbt_assert0(src != NULL && dst != NULL, "Invalid parameter");
273   xbt_assert0(communication_amount >= 0, "communication_amount must be greater than or equal to zero");
274
275   SD_link_t *links;
276   int nb_links;
277   double bandwidth, min_bandwidth;
278   double latency;
279   int i;
280   
281   if (communication_amount == 0.0)
282     return 0.0;
283
284   links = SD_route_get_list(src, dst);
285   nb_links = SD_route_get_size(src, dst);
286   min_bandwidth = -1.0;
287   latency = 0;
288
289   for (i = 0; i < nb_links; i++) {
290     latency += SD_link_get_current_latency(links[i]);
291     bandwidth = SD_link_get_current_bandwidth(links[i]);
292     if (bandwidth < min_bandwidth || min_bandwidth == -1.0)
293       min_bandwidth = bandwidth;
294   }
295
296   return latency + (communication_amount / min_bandwidth);
297 }
298
299 /* Destroys a workstation.
300  */
301 void __SD_workstation_destroy(void *workstation) {
302   SD_CHECK_INIT_DONE();
303   xbt_assert0(workstation != NULL, "Invalid parameter");
304   /* workstation->surf_workstation is freed by surf_exit and workstation->data is freed by the user */
305   xbt_free(workstation);
306 }