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++) {
30 if (input[i] == del) {
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);
43 ret[e - s + 1] = '\0';
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,
52 double delta, const char *variable,
53 const char *resource, double value) =
55 static void (*TRACE_method_end) (smx_action_t action) = NULL;
58 static void __TRACE_surf_check_variable_set_to_zero(double now,
62 /* check if we have to set it to 0 */
63 if (!xbt_dict_get_or_null(platform_variables, resource)) {
64 xbt_dynar_t array = xbt_dynar_new(sizeof(char *), xbt_free);
65 char *var_cpy = xbt_strdup(variable);
66 xbt_dynar_push(array, &var_cpy);
67 if (IS_TRACING_PLATFORM)
68 pajeSetVariable(now, variable, resource, "0");
69 xbt_dict_set(platform_variables, resource, array,
70 xbt_dynar_free_voidp);
72 xbt_dynar_t array = xbt_dict_get(platform_variables, resource);
76 xbt_dynar_foreach(array, i, cat) {
77 if (strcmp(variable, cat) == 0) {
82 char *var_cpy = xbt_strdup(variable);
83 xbt_dynar_push(array, &var_cpy);
84 if (IS_TRACING_PLATFORM)
85 pajeSetVariable(now, variable, resource, "0");
93 static void __TRACE_A_alloc(void)
97 static void __TRACE_A_release(void)
101 static void __TRACE_A_start(smx_action_t action)
105 static void __TRACE_A_event(smx_action_t action, double now, double delta,
106 const char *variable, const char *resource,
109 if (!IS_TRACING_PLATFORM)
113 snprintf(valuestr, 100, "%f", value);
115 __TRACE_surf_check_variable_set_to_zero(now, variable, resource);
116 pajeAddVariable(now, variable, resource, valuestr);
117 pajeSubVariable(now + delta, variable, resource, valuestr);
120 static void __TRACE_A_end(smx_action_t action)
127 static void __TRACE_B_alloc(void)
129 method_b_dict = xbt_dict_new();
132 static void __TRACE_B_release(void)
134 xbt_dict_cursor_t cursor = NULL;
135 unsigned int cursor_ar = 0;
136 char *key, *value, *res;
139 char *var_cpy = NULL;
140 xbt_dynar_t resources = NULL;
141 if (!IS_TRACING_PLATFORM)
143 if (!xbt_dict_length(method_b_dict)) {
146 /* get all resources from method_b_dict */
147 resources = xbt_dynar_new(sizeof(char *), xbt_free);
148 xbt_dict_foreach(method_b_dict, cursor, key, value) {
149 res = strsplit(key, 0, VARIABLE_SEPARATOR);
150 aux = strsplit(key, 1, VARIABLE_SEPARATOR);
151 if (strcmp(aux, "Time") == 0) { //only need to add one of three
152 var_cpy = xbt_strdup(res);
153 xbt_dynar_push(resources, &var_cpy);
159 /* iterate through resources array */
160 xbt_dynar_foreach(resources, cursor_ar, resource) {
161 char timekey[100], valuekey[100], variablekey[100];
164 char *variable = NULL;
165 snprintf(timekey, 100, "%s%cTime", resource, VARIABLE_SEPARATOR);
166 snprintf(valuekey, 100, "%s%cValue", resource, VARIABLE_SEPARATOR);
167 snprintf(variablekey, 100, "%s%cVariable", resource,
170 time = xbt_dict_get_or_null(method_b_dict, timekey);
173 value = xbt_dict_get(method_b_dict, valuekey);
174 variable = xbt_dict_get(method_b_dict, variablekey);
175 pajeSubVariable(atof(time), variable, resource, value);
177 xbt_dict_remove(method_b_dict, timekey);
178 xbt_dict_remove(method_b_dict, valuekey);
179 xbt_dict_remove(method_b_dict, variablekey);
182 xbt_dict_free(&method_b_dict);
185 static void __TRACE_B_start(smx_action_t action)
189 static void __TRACE_B_event(smx_action_t action, double now, double delta,
190 const char *variable, const char *resource,
194 if (!IS_TRACING_PLATFORM)
198 char nowstr[100], nowdeltastr[100];
199 char timekey[100], valuekey[100], variablekey[100];
200 char *lastvariable = NULL;
201 char *lasttime = NULL;
202 char *lastvalue = NULL;
203 char *nowdeltastr_cpy = NULL;
204 char *valuestr_cpy = NULL;
205 char *variable_cpy = NULL;
208 * The following code replaces the code above with the objective
209 * to decrease the size of file because of unnecessary add/sub on
210 * variables. It should be re-checked before put in production.
213 snprintf(valuestr, 100, "%f", value);
214 snprintf(nowstr, 100, "%f", now);
215 snprintf(nowdeltastr, 100, "%f", now + delta);
216 snprintf(timekey, 100, "%s%cTime", resource, VARIABLE_SEPARATOR);
217 snprintf(valuekey, 100, "%s%cValue", resource, VARIABLE_SEPARATOR);
218 snprintf(variablekey, 100, "%s%cVariable", resource, VARIABLE_SEPARATOR);
220 lastvariable = xbt_dict_get_or_null(method_b_dict, variablekey);
221 if (lastvariable == NULL) {
222 __TRACE_surf_check_variable_set_to_zero(now, variable, resource);
223 pajeAddVariable(now, variable, resource, valuestr);
224 nowdeltastr_cpy = xbt_strdup(nowdeltastr);
225 valuestr_cpy = xbt_strdup(valuestr);
226 variable_cpy = xbt_strdup(variable);
227 xbt_dict_set(method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
228 xbt_dict_set(method_b_dict, valuekey, valuestr_cpy, xbt_free);
229 xbt_dict_set(method_b_dict, variablekey, variable_cpy, xbt_free);
231 lasttime = xbt_dict_get_or_null(method_b_dict, timekey);
232 lastvalue = xbt_dict_get_or_null(method_b_dict, valuekey);
234 /* check if it is the same variable */
235 if (strcmp(lastvariable, variable) == 0) { /* same variable */
236 /* check if lasttime equals now */
237 if (atof(lasttime) == now) { /* lastime == now */
238 /* check if lastvalue equals valuestr */
239 if (atof(lastvalue) == value) { /* lastvalue == value (good, just advance time) */
240 char *nowdeltastr_cpy = xbt_strdup(nowdeltastr);
241 xbt_dict_set(method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
242 } else { /* value has changed */
243 /* value has changed, subtract previous value, add new one */
244 pajeSubVariable(atof(lasttime), variable, resource, lastvalue);
245 pajeAddVariable(atof(nowstr), variable, resource, valuestr);
246 nowdeltastr_cpy = xbt_strdup(nowdeltastr);
247 valuestr_cpy = xbt_strdup(valuestr);
248 xbt_dict_set(method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
249 xbt_dict_set(method_b_dict, valuekey, valuestr_cpy, xbt_free);
251 } else { /* lasttime != now */
252 /* the last time is different from new starting time, subtract to lasttime and add from nowstr */
253 pajeSubVariable(atof(lasttime), variable, resource, lastvalue);
254 pajeAddVariable(atof(nowstr), variable, resource, valuestr);
255 nowdeltastr_cpy = xbt_strdup(nowdeltastr);
256 valuestr_cpy = xbt_strdup(valuestr);
257 xbt_dict_set(method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
258 xbt_dict_set(method_b_dict, valuekey, valuestr_cpy, xbt_free);
260 } else { /* variable has changed */
261 pajeSubVariable(atof(lasttime), lastvariable, resource, lastvalue);
262 __TRACE_surf_check_variable_set_to_zero(now, variable, resource);
263 pajeAddVariable(now, variable, resource, valuestr);
264 nowdeltastr_cpy = xbt_strdup(nowdeltastr);
265 valuestr_cpy = xbt_strdup(valuestr);
266 variable_cpy = xbt_strdup(variable);
267 xbt_dict_set(method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
268 xbt_dict_set(method_b_dict, valuekey, valuestr_cpy, xbt_free);
269 xbt_dict_set(method_b_dict, variablekey, variable_cpy, xbt_free);
275 static void __TRACE_B_end(smx_action_t action)
281 static void __TRACE_C_alloc(void)
283 method_c_dict = xbt_dict_new();
286 static void __TRACE_C_release(void)
288 xbt_dict_free(&method_c_dict);
291 static void __TRACE_C_start(smx_action_t action)
294 snprintf(key, 100, "%p", action);
297 if (xbt_dict_get_or_null(method_c_dict, key)) {
298 xbt_dict_remove(method_c_dict, key); //should never execute here, but it does
300 xbt_dict_set(method_c_dict, key, xbt_dict_new(), xbt_free);
303 static void __TRACE_C_event(smx_action_t action, double now, double delta,
304 const char *variable, const char *resource,
308 snprintf(key, 100, "%p", action);
310 xbt_dict_t action_dict = xbt_dict_get(method_c_dict, key);
312 if (!xbt_dict_get_or_null(action_dict, "start")) {
313 char start_time[100];
314 snprintf(start_time, 100, "%f", now);
315 xbt_dict_set(action_dict, "start", xbt_strdup(start_time), xbt_free);
319 snprintf(end_time, 100, "%f", now + delta);
320 xbt_dict_set(action_dict, "end", xbt_strdup(end_time), xbt_free);
322 //accumulate the value resource-variable
324 snprintf(res_var, 300, "%s %s", resource, variable);
325 double current_value_f;
326 char *current_value = xbt_dict_get_or_null(action_dict, res_var);
328 current_value_f = atof(current_value);
329 current_value_f += value * delta;
331 current_value_f = value * delta;
333 char new_current_value[100];
334 snprintf(new_current_value, 100, "%f", current_value_f);
335 xbt_dict_set(action_dict, res_var, xbt_strdup(new_current_value),
339 static void __TRACE_C_end(smx_action_t action)
342 snprintf(key, 100, "%p", action);
344 xbt_dict_t action_dict = xbt_dict_get(method_c_dict, key);
345 double start_time = atof(xbt_dict_get(action_dict, "start"));
346 double end_time = atof(xbt_dict_get(action_dict, "end"));
348 xbt_dict_cursor_t cursor = NULL;
349 char *action_dict_key, *action_dict_value;
350 xbt_dict_foreach(action_dict, cursor, action_dict_key, action_dict_value) {
351 char resource[100], variable[100];
352 if (sscanf(action_dict_key, "%s %s", resource, variable) != 2)
354 __TRACE_surf_check_variable_set_to_zero(start_time, variable,
357 if (end_time - start_time != 0) {
358 snprintf(value_str, 100, "%f",
359 atof(action_dict_value) / (end_time - start_time));
360 pajeAddVariable(start_time, variable, resource, value_str);
361 pajeSubVariable(end_time, variable, resource, value_str);
364 xbt_dict_remove(method_c_dict, key);
367 #define RESOURCE_UTILIZATION_INTERFACE
369 * TRACE_surf_link_set_utilization: entry point from SimGrid
371 void TRACE_surf_link_set_utilization(void *link, smx_action_t smx_action,
372 surf_action_t surf_action,
373 double value, double now,
380 //only trace link utilization if link is known by tracing mechanism
381 if (!TRACE_surf_link_is_traced(link))
386 //trace uncategorized link utilization
388 snprintf(resource, 100, "%p", link);
389 TRACE_surf_resource_utilization_event(smx_action, now, delta,
390 "bandwidth_used", resource, value);
392 //trace categorized utilization
393 if (!IS_TRACED(surf_action))
396 snprintf(type, 100, "b%s", surf_action->category);
397 TRACE_surf_resource_utilization_event(smx_action, now, delta, type,
403 * TRACE_surf_host_set_utilization: entry point from SimGrid
405 void TRACE_surf_host_set_utilization(const char *name,
406 smx_action_t smx_action,
407 surf_action_t surf_action,
408 double value, double now,
416 //trace uncategorized host utilization
417 if (TRACE_uncategorized()){
418 TRACE_surf_resource_utilization_event(smx_action, now, delta,
419 "power_used", name, value);
422 //trace categorized utilization
423 if (!IS_TRACED(surf_action))
426 snprintf(type, 100, "p%s", surf_action->category);
427 TRACE_surf_resource_utilization_event(smx_action, now, delta, type, name,
433 * __TRACE_surf_resource_utilization_*: entry points from tracing functions
435 void TRACE_surf_resource_utilization_start(smx_action_t action)
439 TRACE_method_start(action);
442 void TRACE_surf_resource_utilization_event(smx_action_t action, double now,
444 const char *variable,
445 const char *resource,
450 TRACE_method_event(action, now, delta, variable, resource, value);
453 void TRACE_surf_resource_utilization_end(smx_action_t action)
457 TRACE_method_end(action);
460 void TRACE_surf_resource_utilization_release()
464 TRACE_method_release();
467 static void __TRACE_define_method(char *method)
469 if (!strcmp(method, "a")) {
470 TRACE_method_alloc = __TRACE_A_alloc;
471 TRACE_method_release = __TRACE_A_release;
472 TRACE_method_start = __TRACE_A_start;
473 TRACE_method_event = __TRACE_A_event;
474 TRACE_method_end = __TRACE_A_end;
475 } else if (!strcmp(method, "c")) {
476 TRACE_method_alloc = __TRACE_C_alloc;
477 TRACE_method_release = __TRACE_C_release;
478 TRACE_method_start = __TRACE_C_start;
479 TRACE_method_event = __TRACE_C_event;
480 TRACE_method_end = __TRACE_C_end;
481 } else { //default is B
482 TRACE_method_alloc = __TRACE_B_alloc;
483 TRACE_method_release = __TRACE_B_release;
484 TRACE_method_start = __TRACE_B_start;
485 TRACE_method_event = __TRACE_B_event;
486 TRACE_method_end = __TRACE_B_end;
490 void TRACE_surf_resource_utilization_alloc()
492 platform_variables = xbt_dict_new();
493 __TRACE_define_method(TRACE_get_platform_method());
494 TRACE_method_alloc();