1 /* Copyright (c) 2010. The SimGrid Team.
2 * All rights reserved. */
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. */
7 #include "instr/private.h"
11 #define VARIABLE_SEPARATOR '#'
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 */
17 static xbt_dict_t method_b_dict;
20 static xbt_dict_t method_c_dict;
22 /* auxiliary function for resource utilization tracing */
23 static char *strsplit (char *input, int field, char del) //caller should free the returned string
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++){
31 if (current_field == field){
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);
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, double delta, const char *variable, const char *resource, double value) = NULL;
52 static void (*TRACE_method_end)(smx_action_t action) = NULL;
55 static void __TRACE_surf_check_variable_set_to_zero (double now, const char *variable, const char *resource)
57 /* check if we have to set it to 0 */
58 if (!xbt_dict_get_or_null (platform_variables, resource)){
59 xbt_dynar_t array = xbt_dynar_new(sizeof(char*), xbt_free);
60 char *var_cpy = xbt_strdup(variable);
61 xbt_dynar_push (array, &var_cpy);
62 if (IS_TRACING_PLATFORM) pajeSetVariable (now, variable, resource, "0");
63 xbt_dict_set (platform_variables, resource, array, xbt_dynar_free_voidp);
65 xbt_dynar_t array = xbt_dict_get (platform_variables, resource);
69 xbt_dynar_foreach (array, i, cat) {
70 if (strcmp(variable, cat)==0){
75 char *var_cpy = xbt_strdup(variable);
76 xbt_dynar_push (array, &var_cpy);
77 if (IS_TRACING_PLATFORM) pajeSetVariable (now, variable, resource, "0");
85 static void __TRACE_A_alloc (void) {}
86 static void __TRACE_A_release (void) {}
87 static void __TRACE_A_start (smx_action_t action) {}
88 static void __TRACE_A_event (smx_action_t action, double now, double delta, const char *variable, const char *resource, double value)
90 if (!IS_TRACING_PLATFORM) return;
93 snprintf (valuestr, 100, "%f", value);
95 __TRACE_surf_check_variable_set_to_zero (now, variable, resource);
96 pajeAddVariable (now, variable, resource, valuestr);
97 pajeSubVariable (now+delta, variable, resource, valuestr);
99 static void __TRACE_A_end (smx_action_t action) {}
104 static void __TRACE_B_alloc (void)
106 method_b_dict = xbt_dict_new();
109 static void __TRACE_B_release (void)
111 xbt_dict_cursor_t cursor = NULL;
112 unsigned int cursor_ar = 0;
113 char *key, *value, *res;
116 char *var_cpy = NULL;
117 xbt_dynar_t resources = NULL;
118 if (!IS_TRACING_PLATFORM) return;
119 if (!xbt_dict_length(method_b_dict)){
122 /* get all resources from method_b_dict */
123 resources = xbt_dynar_new(sizeof(char*), xbt_free);
124 xbt_dict_foreach(method_b_dict, cursor, key, value) {
125 res = strsplit (key, 0, VARIABLE_SEPARATOR);
126 aux = strsplit (key, 1, VARIABLE_SEPARATOR);
127 if (strcmp (aux, "Time") == 0){ //only need to add one of three
128 var_cpy = xbt_strdup (res);
129 xbt_dynar_push (resources, &var_cpy);
135 /* iterate through resources array */
136 xbt_dynar_foreach (resources, cursor_ar, resource) {
137 char timekey[100], valuekey[100], variablekey[100];
140 char *variable = NULL;
141 snprintf (timekey, 100, "%s%cTime", resource, VARIABLE_SEPARATOR);
142 snprintf (valuekey, 100, "%s%cValue", resource, VARIABLE_SEPARATOR);
143 snprintf (variablekey, 100, "%s%cVariable", resource, VARIABLE_SEPARATOR);
145 time = xbt_dict_get_or_null (method_b_dict, timekey);
147 value = xbt_dict_get (method_b_dict, valuekey);
148 variable = xbt_dict_get (method_b_dict, variablekey);
149 pajeSubVariable (atof(time), variable, resource, value);
151 xbt_dict_remove (method_b_dict, timekey);
152 xbt_dict_remove (method_b_dict, valuekey);
153 xbt_dict_remove (method_b_dict, variablekey);
156 xbt_dict_free (&method_b_dict);
159 static void __TRACE_B_start (smx_action_t action) {}
160 static void __TRACE_B_event (smx_action_t action, double now, double delta, const char *variable, const char *resource, double value)
163 if (!IS_TRACING_PLATFORM) return;
166 char nowstr[100], nowdeltastr[100];
167 char timekey[100], valuekey[100], variablekey[100];
168 char *lastvariable = NULL;
169 char *lasttime = NULL;
170 char *lastvalue = NULL;
171 char *nowdeltastr_cpy = NULL;
172 char *valuestr_cpy = NULL;
173 char *variable_cpy = NULL;
176 * The following code replaces the code above with the objective
177 * to decrease the size of file because of unnecessary add/sub on
178 * variables. It should be re-checked before put in production.
181 snprintf (valuestr, 100, "%f", value);
182 snprintf (nowstr, 100, "%f", now);
183 snprintf (nowdeltastr, 100, "%f", now+delta);
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);
188 lastvariable = xbt_dict_get_or_null (method_b_dict, variablekey);
189 if (lastvariable == NULL){
190 __TRACE_surf_check_variable_set_to_zero (now, variable, resource);
191 pajeAddVariable (now, variable, resource, valuestr);
192 nowdeltastr_cpy = xbt_strdup (nowdeltastr);
193 valuestr_cpy = xbt_strdup (valuestr);
194 variable_cpy = xbt_strdup (variable);
195 xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
196 xbt_dict_set (method_b_dict, valuekey, valuestr_cpy, xbt_free);
197 xbt_dict_set (method_b_dict, variablekey, variable_cpy, xbt_free);
199 lasttime = xbt_dict_get_or_null (method_b_dict, timekey);
200 lastvalue = xbt_dict_get_or_null (method_b_dict, valuekey);
202 /* check if it is the same variable */
203 if (strcmp(lastvariable, variable) == 0){ /* same variable */
204 /* check if lasttime equals now */
205 if (atof(lasttime) == now){ /* lastime == now */
206 /* check if lastvalue equals valuestr */
207 if (atof(lastvalue) == value){ /* lastvalue == value (good, just advance time) */
208 char *nowdeltastr_cpy = xbt_strdup (nowdeltastr);
209 xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
210 }else{ /* value has changed */
211 /* value has changed, subtract previous value, add new one */
212 pajeSubVariable (atof(lasttime), variable, resource, lastvalue);
213 pajeAddVariable (atof(nowstr), variable, resource, valuestr);
214 nowdeltastr_cpy = xbt_strdup (nowdeltastr);
215 valuestr_cpy = xbt_strdup (valuestr);
216 xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
217 xbt_dict_set (method_b_dict, valuekey, valuestr_cpy, xbt_free);
219 }else{ /* lasttime != now */
220 /* the last time is different from new starting time, subtract to lasttime and add from nowstr */
221 pajeSubVariable (atof(lasttime), variable, resource, lastvalue);
222 pajeAddVariable (atof(nowstr), variable, resource, valuestr);
223 nowdeltastr_cpy = xbt_strdup (nowdeltastr);
224 valuestr_cpy = xbt_strdup (valuestr);
225 xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
226 xbt_dict_set (method_b_dict, valuekey, valuestr_cpy, xbt_free);
228 }else{ /* variable has changed */
229 pajeSubVariable (atof(lasttime), lastvariable, resource, lastvalue);
230 __TRACE_surf_check_variable_set_to_zero (now, variable, resource);
231 pajeAddVariable (now, variable, resource, valuestr);
232 nowdeltastr_cpy = xbt_strdup (nowdeltastr);
233 valuestr_cpy = xbt_strdup (valuestr);
234 variable_cpy = xbt_strdup (variable);
235 xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
236 xbt_dict_set (method_b_dict, valuekey, valuestr_cpy, xbt_free);
237 xbt_dict_set (method_b_dict, variablekey, variable_cpy, xbt_free);
242 static void __TRACE_B_end (smx_action_t action) {}
246 static void __TRACE_C_alloc (void)
248 method_c_dict = xbt_dict_new();
251 static void __TRACE_C_release (void)
253 xbt_dict_free (&method_c_dict);
256 static void __TRACE_C_start (smx_action_t action)
259 snprintf (key, 100, "%p", action);
262 if (xbt_dict_get_or_null (method_c_dict, key)){
263 xbt_dict_remove (method_c_dict, key); //should never execute here, but it does
265 xbt_dict_set (method_c_dict, key, xbt_dict_new(), xbt_free);
268 static void __TRACE_C_event (smx_action_t action, double now, double delta, const char *variable, const char *resource, double value)
271 snprintf (key, 100, "%p", action);
273 xbt_dict_t action_dict = xbt_dict_get (method_c_dict, key);
275 if (!xbt_dict_get_or_null (action_dict, "start")){
276 char start_time[100];
277 snprintf (start_time, 100, "%f", now);
278 xbt_dict_set (action_dict, "start", xbt_strdup (start_time), xbt_free);
282 snprintf (end_time, 100, "%f", now+delta);
283 xbt_dict_set (action_dict, "end", xbt_strdup (end_time), xbt_free);
285 //accumulate the value resource-variable
287 snprintf (res_var, 300, "%s %s", resource, variable);
288 double current_value_f;
289 char *current_value = xbt_dict_get_or_null (action_dict, res_var);
291 current_value_f = atof (current_value);
292 current_value_f += value*delta;
294 current_value_f = value*delta;
296 char new_current_value[100];
297 snprintf (new_current_value, 100, "%f", current_value_f);
298 xbt_dict_set (action_dict, res_var, xbt_strdup (new_current_value), xbt_free);
301 static void __TRACE_C_end (smx_action_t action)
304 snprintf (key, 100, "%p", action);
306 xbt_dict_t action_dict = xbt_dict_get (method_c_dict, key);
307 double start_time = atof(xbt_dict_get (action_dict, "start"));
308 double end_time = atof(xbt_dict_get (action_dict, "end"));
310 xbt_dict_cursor_t cursor=NULL;
311 char *action_dict_key, *action_dict_value;
312 xbt_dict_foreach(action_dict,cursor,action_dict_key,action_dict_value) {
313 char resource[100], variable[100];
314 if (sscanf (action_dict_key, "%s %s", resource, variable) != 2) continue;
315 __TRACE_surf_check_variable_set_to_zero (start_time, variable, resource);
317 if(end_time-start_time != 0){
318 snprintf (value_str, 100, "%f", atof(action_dict_value)/(end_time-start_time));
319 pajeAddVariable (start_time, variable, resource, value_str);
320 pajeSubVariable (end_time, variable, resource, value_str);
323 xbt_dict_remove (method_c_dict, key);
326 #define RESOURCE_UTILIZATION_INTERFACE
328 * TRACE_surf_link_set_utilization: entry point from SimGrid
330 void TRACE_surf_link_set_utilization (void *link, smx_action_t smx_action, surf_action_t surf_action, double value, double now, double delta)
332 if (!IS_TRACING) return;
334 //only trace link utilization if link is known by tracing mechanism
335 if (!TRACE_surf_link_is_traced (link)) return;
338 //trace uncategorized link utilization
340 snprintf (resource, 100, "%p", link);
341 TRACE_surf_resource_utilization_event (smx_action, now, delta, "bandwidth_used", resource, value);
343 //trace categorized utilization
344 if (!IS_TRACED(surf_action)) return;
346 snprintf (type, 100, "b%s", surf_action->category);
347 TRACE_surf_resource_utilization_event (smx_action, now, delta, type, resource, value);
352 * TRACE_surf_host_set_utilization: entry point from SimGrid
354 void TRACE_surf_host_set_utilization (const char *name, smx_action_t smx_action, surf_action_t surf_action, double value, double now, double delta)
356 if (!IS_TRACING) return;
359 //trace uncategorized host utilization
360 TRACE_surf_resource_utilization_event (smx_action, now, delta, "power_used", name, value);
362 //trace categorized utilization
363 if (!IS_TRACED(surf_action)) return;
365 snprintf (type, 100, "p%s", surf_action->category);
366 TRACE_surf_resource_utilization_event (smx_action, now, delta, type, name, value);
371 * __TRACE_surf_resource_utilization_*: entry points from tracing functions
373 void TRACE_surf_resource_utilization_start (smx_action_t action)
375 if (!IS_TRACING) return;
376 TRACE_method_start (action);
379 void TRACE_surf_resource_utilization_event (smx_action_t action, double now, double delta, const char *variable, const char *resource, double value)
381 if (!IS_TRACING) return;
382 TRACE_method_event (action, now, delta, variable, resource, value);
385 void TRACE_surf_resource_utilization_end (smx_action_t action)
387 if (!IS_TRACING) return;
388 TRACE_method_end (action);
391 void TRACE_surf_resource_utilization_release ()
393 if (!IS_TRACING) return;
394 TRACE_method_release ();
397 static void __TRACE_define_method (char *method)
399 if (!strcmp(method, "a")){
400 TRACE_method_alloc = __TRACE_A_alloc;
401 TRACE_method_release = __TRACE_A_release;
402 TRACE_method_start = __TRACE_A_start;
403 TRACE_method_event = __TRACE_A_event;
404 TRACE_method_end = __TRACE_A_end;
405 }else if (!strcmp(method, "c")){
406 TRACE_method_alloc = __TRACE_C_alloc;
407 TRACE_method_release = __TRACE_C_release;
408 TRACE_method_start = __TRACE_C_start;
409 TRACE_method_event = __TRACE_C_event;
410 TRACE_method_end = __TRACE_C_end;
411 }else{ //default is B
412 TRACE_method_alloc = __TRACE_B_alloc;
413 TRACE_method_release = __TRACE_B_release;
414 TRACE_method_start = __TRACE_B_start;
415 TRACE_method_event = __TRACE_B_event;
416 TRACE_method_end = __TRACE_B_end;
420 void TRACE_surf_resource_utilization_alloc ()
422 platform_variables = xbt_dict_new();
423 __TRACE_define_method (TRACE_get_platform_method());
424 TRACE_method_alloc ();