Logo AND Algorithmique Numérique Distribuée

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