Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
pre version hierarchical routing, fix memory leak
[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 //B
14 static xbt_dict_t method_b_dict;
15
16 //C
17 static xbt_dict_t method_c_dict;
18
19 /* auxiliary function for resource utilization tracing */
20 static char *strsplit (char *input, int field, char del) //caller should free the returned string
21 {
22   char *ret = NULL;
23   int length = strlen(input), i;
24   int s = 0, e = length+1;
25   int current_field = 0;
26   for (i = 0; i < length; i++){
27      if (input[i] == del){
28        if (current_field == field){
29          e = i-1;
30          break;
31        }else{
32          s = i+1;
33          current_field++;
34        }
35      }
36   }
37   //copy string from s to e (with length equal to e-s) and return
38   ret = malloc ((e-s+2)*sizeof(char));
39   strncpy (ret, input+s, e-s+1);
40   ret[e-s+1] = '\0';
41   return ret;
42 }
43
44 //resource utilization tracing method
45 typedef enum {methodA,methodB,methodC} TracingMethod;
46 static TracingMethod currentMethod;
47
48 static void __TRACE_define_method (char *method)
49 {
50   if (!strcmp(method, "a")){
51     currentMethod = methodA;
52   }else if (!strcmp(method, "b")){
53     currentMethod = methodB;
54   }else if (!strcmp(method, "c")){
55     currentMethod = methodC;
56   }else{
57     currentMethod = methodB; //default
58   }
59 }
60
61 //A
62 static void __TRACE_surf_resource_utilization_A (double now, double delta, const char *variable, const char *resource, double value)
63 {
64   if (!IS_TRACING_PLATFORM) return;
65
66   char valuestr[100];
67   snprintf (valuestr, 100, "%f", value);
68
69   __TRACE_surf_check_variable_set_to_zero (now, variable, resource);
70   pajeAddVariable (now, variable, resource, valuestr);
71   pajeSubVariable (now+delta, variable, resource, valuestr);
72   return;
73 }
74
75 //B
76 static void __TRACE_surf_resource_utilization_initialize_B ()
77 {
78   method_b_dict =  xbt_dict_new();
79 }
80
81 static void __TRACE_surf_resource_utilization_B (double now, double delta, const char *variable, const char *resource, double value)
82 {
83   if (!IS_TRACING_PLATFORM) return;
84
85   char valuestr[100];
86   char nowstr[100], nowdeltastr[100];
87   char timekey[100], valuekey[100], variablekey[100];
88   char *lastvariable = NULL;
89   char *lasttime = NULL;
90   char *lastvalue = NULL;
91   char *nowdeltastr_cpy = NULL;
92   char *valuestr_cpy = NULL;
93   char *variable_cpy = NULL;
94
95   /*
96    * The following code replaces the code above with the objective
97    * to decrease the size of file because of unnecessary add/sub on
98    * variables. It should be re-checked before put in production.
99    */
100
101   snprintf (valuestr, 100, "%f", value);
102   snprintf (nowstr, 100, "%f", now);
103   snprintf (nowdeltastr, 100, "%f", now+delta);
104   snprintf (timekey, 100, "%s%cTime", resource, VARIABLE_SEPARATOR);
105   snprintf (valuekey, 100, "%s%cValue", resource, VARIABLE_SEPARATOR);
106   snprintf (variablekey, 100, "%s%cVariable", resource, VARIABLE_SEPARATOR);
107
108   lastvariable = xbt_dict_get_or_null (method_b_dict, variablekey);
109   if (lastvariable == NULL){
110     __TRACE_surf_check_variable_set_to_zero (now, variable, resource);
111     pajeAddVariable (now, variable, resource, valuestr);
112     nowdeltastr_cpy = xbt_strdup (nowdeltastr);
113     valuestr_cpy = xbt_strdup (valuestr);
114     variable_cpy = xbt_strdup (variable);
115     xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
116     xbt_dict_set (method_b_dict, valuekey, valuestr_cpy, xbt_free);
117     xbt_dict_set (method_b_dict, variablekey, variable_cpy, xbt_free);
118   }else{
119     lasttime = xbt_dict_get_or_null (method_b_dict, timekey);
120     lastvalue = xbt_dict_get_or_null (method_b_dict, valuekey);
121
122     /* check if it is the same variable */
123     if (strcmp(lastvariable, variable) == 0){ /* same variable */
124       /* check if lasttime equals now */
125       if (atof(lasttime) == now){ /* lastime == now */
126         /* check if lastvalue equals valuestr */
127         if (atof(lastvalue) == value){ /* lastvalue == value (good, just advance time) */
128           char *nowdeltastr_cpy = xbt_strdup (nowdeltastr);
129           xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
130         }else{ /* value has changed */
131           /* value has changed, subtract previous value, add new one */
132           pajeSubVariable (atof(lasttime), variable, resource, lastvalue);
133           pajeAddVariable (atof(nowstr), variable, resource, valuestr);
134           nowdeltastr_cpy = xbt_strdup (nowdeltastr);
135           valuestr_cpy = xbt_strdup (valuestr);
136           xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
137           xbt_dict_set (method_b_dict, valuekey, valuestr_cpy, xbt_free);
138         }
139       }else{ /* lasttime != now */
140         /* the last time is different from new starting time, subtract to lasttime and add from nowstr */
141         pajeSubVariable (atof(lasttime), variable, resource, lastvalue);
142         pajeAddVariable (atof(nowstr), variable, resource, valuestr);
143         nowdeltastr_cpy = xbt_strdup (nowdeltastr);
144         valuestr_cpy = xbt_strdup (valuestr);
145         xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
146         xbt_dict_set (method_b_dict, valuekey, valuestr_cpy, xbt_free);
147       }
148     }else{ /* variable has changed */
149       pajeSubVariable (atof(lasttime), lastvariable, resource, lastvalue);
150       __TRACE_surf_check_variable_set_to_zero (now, variable, resource);
151       pajeAddVariable (now, variable, resource, valuestr);
152       nowdeltastr_cpy = xbt_strdup (nowdeltastr);
153       valuestr_cpy = xbt_strdup (valuestr);
154       variable_cpy = xbt_strdup (variable);
155       xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
156       xbt_dict_set (method_b_dict, valuekey, valuestr_cpy, xbt_free);
157       xbt_dict_set (method_b_dict, variablekey, variable_cpy, xbt_free);
158     }
159   }
160   return;
161 }
162
163 static void __TRACE_surf_resource_utilization_finalize_B ()
164 {
165   xbt_dict_cursor_t cursor = NULL;
166   unsigned int cursor_ar = 0;
167     char *key, *value, *res;
168     char *resource;
169     char *aux = NULL;
170     char *var_cpy = NULL;
171     xbt_dynar_t resources = NULL;
172   if (!IS_TRACING_PLATFORM) return;
173   if (!xbt_dict_length(method_b_dict)){
174     return;
175   }else{
176     /* get all resources from method_b_dict */
177     resources = xbt_dynar_new(sizeof(char*), xbt_free);
178     xbt_dict_foreach(method_b_dict, cursor, key, value) {
179       res = strsplit (key, 0, VARIABLE_SEPARATOR);
180       aux = strsplit (key, 1, VARIABLE_SEPARATOR);
181       if (strcmp (aux, "Time") == 0){ //only need to add one of three
182         var_cpy = xbt_strdup (res);
183         xbt_dynar_push (resources, &var_cpy);
184       }
185       free (aux);
186       free (res);
187     }
188
189     /* iterate through resources array */
190     xbt_dynar_foreach (resources, cursor_ar, resource) {
191       char timekey[100], valuekey[100], variablekey[100];
192       char *time = NULL;
193       char *value = NULL;
194       char *variable = NULL;
195       snprintf (timekey, 100, "%s%cTime", resource, VARIABLE_SEPARATOR);
196       snprintf (valuekey, 100, "%s%cValue", resource, VARIABLE_SEPARATOR);
197       snprintf (variablekey, 100, "%s%cVariable", resource, VARIABLE_SEPARATOR);
198
199       time = xbt_dict_get_or_null (method_b_dict, timekey);
200       if (!time) continue;
201       value = xbt_dict_get (method_b_dict, valuekey);
202       variable = xbt_dict_get (method_b_dict, variablekey);
203       pajeSubVariable (atof(time), variable, resource, value);
204
205       xbt_dict_remove (method_b_dict, timekey);
206       xbt_dict_remove (method_b_dict, valuekey);
207       xbt_dict_remove (method_b_dict, variablekey);
208     }
209   }
210   xbt_dict_free (&method_b_dict);
211 }
212
213 //C
214 static void __TRACE_surf_resource_utilization_start_C (smx_action_t action)
215 {
216   char key[100];
217   snprintf (key, 100, "%p", action);
218
219   //check if exists
220   if (xbt_dict_get_or_null (method_c_dict, key)){
221     xbt_dict_remove (method_c_dict, key); //should never execute here, but it does
222   }
223   xbt_dict_set (method_c_dict, key, xbt_dict_new(), xbt_free);
224 }
225
226 static void __TRACE_surf_resource_utilization_end_C (smx_action_t action)
227 {
228   char key[100];
229   snprintf (key, 100, "%p", action);
230
231   xbt_dict_t action_dict = xbt_dict_get (method_c_dict, key);
232   double start_time = atof(xbt_dict_get (action_dict, "start"));
233   double end_time = atof(xbt_dict_get (action_dict, "end"));
234
235   xbt_dict_cursor_t cursor=NULL;
236   char *action_dict_key, *action_dict_value;
237   xbt_dict_foreach(action_dict,cursor,action_dict_key,action_dict_value) {
238     char resource[100], variable[100];
239     if (sscanf (action_dict_key, "%s %s", resource, variable) != 2) continue;
240     __TRACE_surf_check_variable_set_to_zero (start_time, variable, resource);
241     char value_str[100];
242     if(end_time-start_time != 0){
243       snprintf (value_str, 100, "%f", atof(action_dict_value)/(end_time-start_time));
244       pajeAddVariable (start_time, variable, resource, value_str);
245       pajeSubVariable (end_time, variable, resource, value_str);
246     }
247   }
248   xbt_dict_remove (method_c_dict, key);
249 }
250
251 static void __TRACE_surf_resource_utilization_C (smx_action_t action, double now, double delta, const char *variable, const char *resource, double value)
252 {
253   char key[100];
254   snprintf (key, 100, "%p", action);
255
256   xbt_dict_t action_dict = xbt_dict_get (method_c_dict, key);
257   //setting start time
258   if (!xbt_dict_get_or_null (action_dict, "start")){
259     char start_time[100];
260     snprintf (start_time, 100, "%f", now);
261     xbt_dict_set (action_dict, "start", xbt_strdup (start_time), xbt_free);
262   }
263   //updating end time
264   char end_time[100];
265   snprintf (end_time, 100, "%f", now+delta);
266   xbt_dict_set (action_dict, "end", xbt_strdup (end_time), xbt_free);
267
268   //accumulate the value resource-variable
269   char res_var[300];
270   snprintf (res_var, 300, "%s %s", resource, variable);
271   double current_value_f;
272   char *current_value = xbt_dict_get_or_null (action_dict, res_var);
273   if (current_value){
274     current_value_f = atof (current_value);
275     current_value_f += value*delta;
276   }else{
277     current_value_f = value*delta;
278   }
279   char new_current_value[100];
280   snprintf (new_current_value, 100, "%f", current_value_f);
281   xbt_dict_set (action_dict, res_var, xbt_strdup (new_current_value), xbt_free);
282 }
283
284 static void __TRACE_surf_resource_utilization_initialize_C ()
285 {
286   method_c_dict = xbt_dict_new();
287 }
288
289 static void __TRACE_surf_resource_utilization_finalize_C ()
290 {
291   xbt_dict_free (&method_c_dict);
292 }
293
294 /*
295  * TRACE_surf_link_set_utilization: entry point from SimGrid
296  */
297 void TRACE_surf_link_set_utilization (const char *name, smx_action_t smx_action, double value, double now, double delta)
298 {
299   char type[100];
300   if (!IS_TRACING || !IS_TRACED(smx_action)) return;
301
302   if (strcmp (name, "__loopback__")==0 ||
303       strcmp (name, "loopback")==0){ //ignore loopback updates
304     return;
305   }
306   if (!value) return;
307
308   snprintf (type, 100, "b%s", smx_action->category);
309   __TRACE_surf_resource_utilization_event (smx_action, now, delta, type, name, value);
310   return;
311 }
312
313 /*
314  * TRACE_surf_host_set_utilization: entry point from SimGrid
315  */
316 void TRACE_surf_host_set_utilization (const char *name, smx_action_t smx_action, double value, double now, double delta)
317 {
318   char type[100];
319   if (!IS_TRACING || !IS_TRACED(smx_action)) return;
320
321   if (!value) return;
322
323   snprintf (type, 100, "p%s", smx_action->category);
324   __TRACE_surf_resource_utilization_event (smx_action, now, delta, type, name, value);
325   return;
326 }
327
328 /*
329  * __TRACE_surf_resource_utilization_*: entry points from tracing functions
330  */
331 void __TRACE_surf_resource_utilization_start (smx_action_t action)
332 {
333   if (currentMethod == methodC){
334     __TRACE_surf_resource_utilization_start_C (action);
335   }
336 }
337
338 void __TRACE_surf_resource_utilization_end (smx_action_t action)
339 {
340   if (currentMethod == methodC){
341     __TRACE_surf_resource_utilization_end_C (action);
342   }
343 }
344
345 void __TRACE_surf_resource_utilization_event (smx_action_t action, double now, double delta, const char *variable, const char *resource, double value)
346 {
347   if (currentMethod == methodA){
348     __TRACE_surf_resource_utilization_A (now, delta, variable, resource, value);
349   }else if (currentMethod == methodB){
350     __TRACE_surf_resource_utilization_B (now, delta, variable, resource, value);
351   }else if (currentMethod == methodC){
352     __TRACE_surf_resource_utilization_C (action, now, delta, variable, resource, value);
353   }
354 }
355
356 void __TRACE_surf_resource_utilization_initialize ()
357 {
358   __TRACE_define_method (_TRACE_platform_method());
359
360   if (currentMethod == methodA){
361   }else if (currentMethod == methodB){
362     __TRACE_surf_resource_utilization_initialize_B();
363   }else if (currentMethod == methodC){
364     __TRACE_surf_resource_utilization_initialize_C();
365   }
366 }
367
368 void __TRACE_surf_resource_utilization_finalize ()
369 {
370   if (currentMethod == methodA){
371   }else if (currentMethod == methodB){
372     __TRACE_surf_resource_utilization_finalize_B();
373   }else if (currentMethod == methodC){
374     __TRACE_surf_resource_utilization_finalize_C();
375   }
376 }
377 #endif