Logo AND Algorithmique Numérique Distribuée

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