Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
8e7e92d40118f0b65dad076ee3a14717b6a0732d
[simgrid.git] / src / instr / instr_resource_utilization.c
1 /* Copyright (c) 2010. The SimGrid Team.
2  * All rights reserved.                                                     */
3
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. */
6
7 #include "instr/instr_private.h"
8
9 #ifdef HAVE_TRACING
10
11 //to check if variables were previously set to 0, otherwise paje won't simulate them
12 static xbt_dict_t platform_variables;   /* host or link name -> array of categories */
13
14 //B
15 static xbt_dict_t method_b_dict;
16
17 //C
18 static xbt_dict_t method_c_dict;
19
20 //resource utilization tracing method
21 static void (*TRACE_method_alloc) (void) = NULL;
22 static void (*TRACE_method_release) (void) = NULL;
23 static void (*TRACE_method_start) (smx_action_t action) = NULL;
24 static void (*TRACE_method_event) (smx_action_t action, double now,
25                                    double delta, const char *variable,
26                                    const char *resource, double value) =
27     NULL;
28 static void (*TRACE_method_end) (smx_action_t action) = NULL;
29
30 //used by all methods
31 static void __TRACE_surf_check_variable_set_to_zero(double now,
32                                                     const char *variable,
33                                                     const char *resource)
34 {
35   /* check if we have to set it to 0 */
36   if (!xbt_dict_get_or_null(platform_variables, resource)) {
37     xbt_dynar_t array = xbt_dynar_new(sizeof(char *), xbt_free);
38     char *var_cpy = xbt_strdup(variable);
39     xbt_dynar_push(array, &var_cpy);
40     if (IS_TRACING_PLATFORM)
41       pajeSetVariable(now, variable, resource, "0");
42     xbt_dict_set(platform_variables, resource, array,
43                  xbt_dynar_free_voidp);
44   } else {
45     xbt_dynar_t array = xbt_dict_get(platform_variables, resource);
46     unsigned int i;
47     char *cat;
48     int flag = 0;
49     xbt_dynar_foreach(array, i, cat) {
50       if (strcmp(variable, cat) == 0) {
51         flag = 1;
52       }
53     }
54     if (flag == 0) {
55       char *var_cpy = xbt_strdup(variable);
56       xbt_dynar_push(array, &var_cpy);
57       if (IS_TRACING_PLATFORM)
58         pajeSetVariable(now, variable, resource, "0");
59     }
60   }
61   /* end of check */
62 }
63
64 #define A_METHOD
65 //A
66 static void __TRACE_A_alloc(void)
67 {
68 }
69
70 static void __TRACE_A_release(void)
71 {
72 }
73
74 static void __TRACE_A_start(smx_action_t action)
75 {
76 }
77
78 static void __TRACE_A_event(smx_action_t action, double now, double delta,
79                             const char *variable, const char *resource,
80                             double value)
81 {
82   if (!IS_TRACING_PLATFORM)
83     return;
84
85   char valuestr[100];
86   snprintf(valuestr, 100, "%f", value);
87
88   __TRACE_surf_check_variable_set_to_zero(now, variable, resource);
89   pajeAddVariable(now, variable, resource, valuestr);
90   pajeSubVariable(now + delta, variable, resource, valuestr);
91 }
92
93 static void __TRACE_A_end(smx_action_t action)
94 {
95 }
96
97 #define B_METHOD
98 //B
99
100 static void __TRACE_B_alloc(void)
101 {
102   method_b_dict = xbt_dict_new();
103 }
104
105 static void __TRACE_B_release(void)
106 {
107   if (!IS_TRACING_PLATFORM)
108     return;
109
110   char *key, *time;
111   xbt_dict_cursor_t cursor = NULL;
112   xbt_dict_foreach(method_b_dict, cursor, key, time) {
113     char resource[INSTR_DEFAULT_STR_SIZE];
114     char variable[INSTR_DEFAULT_STR_SIZE];
115     char what[INSTR_DEFAULT_STR_SIZE];
116     sscanf (key, "%s %s %s", resource, variable, what);
117     if (strcmp(what, "time")==0){
118       char key_value[INSTR_DEFAULT_STR_SIZE];
119       snprintf (key_value, INSTR_DEFAULT_STR_SIZE, "%s %s value", resource, variable);
120       char *value = xbt_dict_get_or_null (method_b_dict, key_value);
121       pajeSubVariable(atof(time), variable, resource, value);
122     }
123   }
124   xbt_dict_free(&method_b_dict);
125 }
126
127 static void __TRACE_B_start(smx_action_t action)
128 {
129 }
130
131 static void __TRACE_B_event(smx_action_t action, double now, double delta,
132                             const char *variable, const char *resource,
133                             double value)
134 {
135   if (!IS_TRACING_PLATFORM)
136     return;
137
138   char key_time[INSTR_DEFAULT_STR_SIZE];
139   char key_value[INSTR_DEFAULT_STR_SIZE];
140   char nowstr[INSTR_DEFAULT_STR_SIZE];
141   char valuestr[INSTR_DEFAULT_STR_SIZE];
142   char nowdeltastr[INSTR_DEFAULT_STR_SIZE];
143
144   snprintf (key_time, INSTR_DEFAULT_STR_SIZE, "%s %s time", resource, variable);
145   snprintf (key_value, INSTR_DEFAULT_STR_SIZE, "%s %s value", resource, variable);
146   snprintf (nowstr, INSTR_DEFAULT_STR_SIZE, "%f", now);
147   snprintf (valuestr, INSTR_DEFAULT_STR_SIZE, "%f", value);
148   snprintf (nowdeltastr, INSTR_DEFAULT_STR_SIZE, "%f", now+delta);
149
150   char *lasttimestr = xbt_dict_get_or_null(method_b_dict, key_time);
151   char *lastvaluestr = xbt_dict_get_or_null(method_b_dict, key_value);
152   if (lasttimestr == NULL){
153     __TRACE_surf_check_variable_set_to_zero(now, variable, resource);
154     pajeAddVariable(now, variable, resource, valuestr);
155     xbt_dict_set(method_b_dict, key_time, xbt_strdup(nowdeltastr), xbt_free);
156     xbt_dict_set(method_b_dict, key_value, xbt_strdup(valuestr), xbt_free);
157   }else{
158     double lasttime = atof (lasttimestr);
159     double lastvalue = atof (lastvaluestr);
160
161     if (lastvalue == value){
162       double dif = fabs(now - lasttime);
163       if (dif < 0.000001){
164         //perfect, just go on
165       }else{
166         //time changed, have to update
167         pajeSubVariable(lasttime, variable, resource, lastvaluestr);
168         pajeAddVariable(now, variable, resource, valuestr);
169       }
170     }else{
171       //value changed, have to update
172       pajeSubVariable(lasttime, variable, resource, lastvaluestr);
173       pajeAddVariable(now, variable, resource, valuestr);
174     }
175     xbt_dict_set(method_b_dict, key_time, xbt_strdup(nowdeltastr), xbt_free);
176     xbt_dict_set(method_b_dict, key_value, xbt_strdup(valuestr), xbt_free);
177   }
178   return;
179 }
180
181 static void __TRACE_B_end(smx_action_t action)
182 {
183 }
184
185 #define C_METHOD
186 //C
187 static void __TRACE_C_alloc(void)
188 {
189   method_c_dict = xbt_dict_new();
190 }
191
192 static void __TRACE_C_release(void)
193 {
194   xbt_dict_free(&method_c_dict);
195 }
196
197 static void __TRACE_C_start(smx_action_t action)
198 {
199   char key[100];
200   snprintf(key, 100, "%p", action);
201
202   //check if exists
203   if (xbt_dict_get_or_null(method_c_dict, key)) {
204     xbt_dict_remove(method_c_dict, key);        //should never execute here, but it does
205   }
206   xbt_dict_set(method_c_dict, key, xbt_dict_new(), xbt_free);
207 }
208
209 static void __TRACE_C_event(smx_action_t action, double now, double delta,
210                             const char *variable, const char *resource,
211                             double value)
212 {
213   char key[100];
214   snprintf(key, 100, "%p", action);
215
216   xbt_dict_t action_dict = xbt_dict_get(method_c_dict, key);
217   //setting start time
218   if (!xbt_dict_get_or_null(action_dict, "start")) {
219     char start_time[100];
220     snprintf(start_time, 100, "%f", now);
221     xbt_dict_set(action_dict, "start", xbt_strdup(start_time), xbt_free);
222   }
223   //updating end time
224   char end_time[100];
225   snprintf(end_time, 100, "%f", now + delta);
226   xbt_dict_set(action_dict, "end", xbt_strdup(end_time), xbt_free);
227
228   //accumulate the value resource-variable
229   char res_var[300];
230   snprintf(res_var, 300, "%s %s", resource, variable);
231   double current_value_f;
232   char *current_value = xbt_dict_get_or_null(action_dict, res_var);
233   if (current_value) {
234     current_value_f = atof(current_value);
235     current_value_f += value * delta;
236   } else {
237     current_value_f = value * delta;
238   }
239   char new_current_value[100];
240   snprintf(new_current_value, 100, "%f", current_value_f);
241   xbt_dict_set(action_dict, res_var, xbt_strdup(new_current_value),
242                xbt_free);
243 }
244
245 static void __TRACE_C_end(smx_action_t action)
246 {
247   char key[100];
248   snprintf(key, 100, "%p", action);
249
250   xbt_dict_t action_dict = xbt_dict_get(method_c_dict, key);
251   double start_time = atof(xbt_dict_get(action_dict, "start"));
252   double end_time = atof(xbt_dict_get(action_dict, "end"));
253
254   xbt_dict_cursor_t cursor = NULL;
255   char *action_dict_key, *action_dict_value;
256   xbt_dict_foreach(action_dict, cursor, action_dict_key, action_dict_value) {
257     char resource[100], variable[100];
258     if (sscanf(action_dict_key, "%s %s", resource, variable) != 2)
259       continue;
260     __TRACE_surf_check_variable_set_to_zero(start_time, variable,
261                                             resource);
262     char value_str[100];
263     if (end_time - start_time != 0) {
264       snprintf(value_str, 100, "%f",
265                atof(action_dict_value) / (end_time - start_time));
266       pajeAddVariable(start_time, variable, resource, value_str);
267       pajeSubVariable(end_time, variable, resource, value_str);
268     }
269   }
270   xbt_dict_remove(method_c_dict, key);
271 }
272
273 #define RESOURCE_UTILIZATION_INTERFACE
274 /*
275  * TRACE_surf_link_set_utilization: entry point from SimGrid
276  */
277 void TRACE_surf_link_set_utilization(void *link, smx_action_t smx_action,
278                                      surf_action_t surf_action,
279                                      double value, double now,
280                                      double delta)
281 {
282   if (!IS_TRACING)
283     return;
284   if (!value)
285     return;
286   //only trace link utilization if link is known by tracing mechanism
287   if (!TRACE_surf_link_is_traced(link))
288     return;
289   if (!value)
290     return;
291
292   char resource[100];
293   snprintf(resource, 100, "%p", link);
294
295   //trace uncategorized link utilization
296   if (TRACE_uncategorized()){
297     TRACE_surf_resource_utilization_event(smx_action, now, delta,
298                                         "bandwidth_used", resource, value);
299   }
300
301   //trace categorized utilization
302   if (!IS_TRACED(surf_action))
303     return;
304   char type[100];
305   snprintf(type, 100, "b%s", surf_action->category);
306   TRACE_surf_resource_utilization_event(smx_action, now, delta, type,
307                                         resource, value);
308   return;
309 }
310
311 /*
312  * TRACE_surf_host_set_utilization: entry point from SimGrid
313  */
314 void TRACE_surf_host_set_utilization(const char *name,
315                                      smx_action_t smx_action,
316                                      surf_action_t surf_action,
317                                      double value, double now,
318                                      double delta)
319 {
320   if (!IS_TRACING)
321     return;
322   if (!value)
323     return;
324
325   //trace uncategorized host utilization
326   if (TRACE_uncategorized()){
327     TRACE_surf_resource_utilization_event(smx_action, now, delta,
328                                         "power_used", name, value);
329   }
330
331   //trace categorized utilization
332   if (!IS_TRACED(surf_action))
333     return;
334   char type[100];
335   snprintf(type, 100, "p%s", surf_action->category);
336   TRACE_surf_resource_utilization_event(smx_action, now, delta, type, name,
337                                         value);
338   return;
339 }
340
341 /*
342  * __TRACE_surf_resource_utilization_*: entry points from tracing functions
343  */
344 void TRACE_surf_resource_utilization_start(smx_action_t action)
345 {
346   if (!IS_TRACING)
347     return;
348   TRACE_method_start(action);
349 }
350
351 void TRACE_surf_resource_utilization_event(smx_action_t action, double now,
352                                            double delta,
353                                            const char *variable,
354                                            const char *resource,
355                                            double value)
356 {
357   if (!IS_TRACING)
358     return;
359   TRACE_method_event(action, now, delta, variable, resource, value);
360 }
361
362 void TRACE_surf_resource_utilization_end(smx_action_t action)
363 {
364   if (!IS_TRACING)
365     return;
366   TRACE_method_end(action);
367 }
368
369 void TRACE_surf_resource_utilization_release()
370 {
371   if (!IS_TRACING)
372     return;
373   TRACE_method_release();
374 }
375
376 static void __TRACE_define_method(char *method)
377 {
378   if (!strcmp(method, "a")) {
379     TRACE_method_alloc = __TRACE_A_alloc;
380     TRACE_method_release = __TRACE_A_release;
381     TRACE_method_start = __TRACE_A_start;
382     TRACE_method_event = __TRACE_A_event;
383     TRACE_method_end = __TRACE_A_end;
384   } else if (!strcmp(method, "c")) {
385     TRACE_method_alloc = __TRACE_C_alloc;
386     TRACE_method_release = __TRACE_C_release;
387     TRACE_method_start = __TRACE_C_start;
388     TRACE_method_event = __TRACE_C_event;
389     TRACE_method_end = __TRACE_C_end;
390   } else {                      //default is B
391     TRACE_method_alloc = __TRACE_B_alloc;
392     TRACE_method_release = __TRACE_B_release;
393     TRACE_method_start = __TRACE_B_start;
394     TRACE_method_event = __TRACE_B_event;
395     TRACE_method_end = __TRACE_B_end;
396   }
397 }
398
399 void TRACE_surf_resource_utilization_alloc()
400 {
401   platform_variables = xbt_dict_new();
402   __TRACE_define_method(TRACE_get_platform_method());
403   TRACE_method_alloc();
404 }
405 #endif /* HAVE_TRACING */