Logo AND Algorithmique Numérique Distribuée

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