Logo AND Algorithmique Numérique Distribuée

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