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 if (!IS_TRACING_PLATFORM)
138 xbt_dict_cursor_t cursor = NULL;
139 xbt_dict_foreach(method_b_dict, cursor, key, time) {
140 char resource[INSTR_DEFAULT_STR_SIZE];
141 char variable[INSTR_DEFAULT_STR_SIZE];
142 char what[INSTR_DEFAULT_STR_SIZE];
143 sscanf (key, "%s %s %s", resource, variable, what);
144 if (strcmp(what, "time")==0){
145 char key_value[INSTR_DEFAULT_STR_SIZE];
146 snprintf (key_value, INSTR_DEFAULT_STR_SIZE, "%s %s value", resource, variable);
147 char *value = xbt_dict_get_or_null (method_b_dict, key_value);
148 pajeSubVariable(atof(time), variable, resource, value);
151 xbt_dict_free(&method_b_dict);
154 static void __TRACE_B_start(smx_action_t action)
158 static void __TRACE_B_event(smx_action_t action, double now, double delta,
159 const char *variable, const char *resource,
162 if (!IS_TRACING_PLATFORM)
165 char key_time[INSTR_DEFAULT_STR_SIZE];
166 char key_value[INSTR_DEFAULT_STR_SIZE];
167 char nowstr[INSTR_DEFAULT_STR_SIZE];
168 char valuestr[INSTR_DEFAULT_STR_SIZE];
169 char nowdeltastr[INSTR_DEFAULT_STR_SIZE];
171 snprintf (key_time, INSTR_DEFAULT_STR_SIZE, "%s %s time", resource, variable);
172 snprintf (key_value, INSTR_DEFAULT_STR_SIZE, "%s %s value", resource, variable);
173 snprintf (nowstr, INSTR_DEFAULT_STR_SIZE, "%f", now);
174 snprintf (valuestr, INSTR_DEFAULT_STR_SIZE, "%f", value);
175 snprintf (nowdeltastr, INSTR_DEFAULT_STR_SIZE, "%f", now+delta);
177 char *lasttimestr = xbt_dict_get_or_null(method_b_dict, key_time);
178 char *lastvaluestr = xbt_dict_get_or_null(method_b_dict, key_value);
179 if (lasttimestr == NULL){
180 __TRACE_surf_check_variable_set_to_zero(now, variable, resource);
181 pajeAddVariable(now, variable, resource, valuestr);
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);
185 double lasttime = atof (lasttimestr);
186 double lastvalue = atof (lastvaluestr);
188 if (lastvalue == value){
189 double dif = fabs(now - lasttime);
191 //perfect, just go on
193 //time changed, have to update
194 pajeSubVariable(lasttime, variable, resource, lastvaluestr);
195 pajeAddVariable(now, variable, resource, valuestr);
198 //value changed, have to update
199 pajeSubVariable(lasttime, variable, resource, lastvaluestr);
200 pajeAddVariable(now, variable, resource, valuestr);
202 xbt_dict_set(method_b_dict, key_time, xbt_strdup(nowdeltastr), xbt_free);
203 xbt_dict_set(method_b_dict, key_value, xbt_strdup(valuestr), xbt_free);
208 static void __TRACE_B_end(smx_action_t action)
214 static void __TRACE_C_alloc(void)
216 method_c_dict = xbt_dict_new();
219 static void __TRACE_C_release(void)
221 xbt_dict_free(&method_c_dict);
224 static void __TRACE_C_start(smx_action_t action)
227 snprintf(key, 100, "%p", action);
230 if (xbt_dict_get_or_null(method_c_dict, key)) {
231 xbt_dict_remove(method_c_dict, key); //should never execute here, but it does
233 xbt_dict_set(method_c_dict, key, xbt_dict_new(), xbt_free);
236 static void __TRACE_C_event(smx_action_t action, double now, double delta,
237 const char *variable, const char *resource,
241 snprintf(key, 100, "%p", action);
243 xbt_dict_t action_dict = xbt_dict_get(method_c_dict, key);
245 if (!xbt_dict_get_or_null(action_dict, "start")) {
246 char start_time[100];
247 snprintf(start_time, 100, "%f", now);
248 xbt_dict_set(action_dict, "start", xbt_strdup(start_time), xbt_free);
252 snprintf(end_time, 100, "%f", now + delta);
253 xbt_dict_set(action_dict, "end", xbt_strdup(end_time), xbt_free);
255 //accumulate the value resource-variable
257 snprintf(res_var, 300, "%s %s", resource, variable);
258 double current_value_f;
259 char *current_value = xbt_dict_get_or_null(action_dict, res_var);
261 current_value_f = atof(current_value);
262 current_value_f += value * delta;
264 current_value_f = value * delta;
266 char new_current_value[100];
267 snprintf(new_current_value, 100, "%f", current_value_f);
268 xbt_dict_set(action_dict, res_var, xbt_strdup(new_current_value),
272 static void __TRACE_C_end(smx_action_t action)
275 snprintf(key, 100, "%p", action);
277 xbt_dict_t action_dict = xbt_dict_get(method_c_dict, key);
278 double start_time = atof(xbt_dict_get(action_dict, "start"));
279 double end_time = atof(xbt_dict_get(action_dict, "end"));
281 xbt_dict_cursor_t cursor = NULL;
282 char *action_dict_key, *action_dict_value;
283 xbt_dict_foreach(action_dict, cursor, action_dict_key, action_dict_value) {
284 char resource[100], variable[100];
285 if (sscanf(action_dict_key, "%s %s", resource, variable) != 2)
287 __TRACE_surf_check_variable_set_to_zero(start_time, variable,
290 if (end_time - start_time != 0) {
291 snprintf(value_str, 100, "%f",
292 atof(action_dict_value) / (end_time - start_time));
293 pajeAddVariable(start_time, variable, resource, value_str);
294 pajeSubVariable(end_time, variable, resource, value_str);
297 xbt_dict_remove(method_c_dict, key);
300 #define RESOURCE_UTILIZATION_INTERFACE
302 * TRACE_surf_link_set_utilization: entry point from SimGrid
304 void TRACE_surf_link_set_utilization(void *link, smx_action_t smx_action,
305 surf_action_t surf_action,
306 double value, double now,
313 //only trace link utilization if link is known by tracing mechanism
314 if (!TRACE_surf_link_is_traced(link))
320 snprintf(resource, 100, "%p", link);
322 //trace uncategorized link utilization
323 if (TRACE_uncategorized()){
324 TRACE_surf_resource_utilization_event(smx_action, now, delta,
325 "bandwidth_used", resource, value);
328 //trace categorized utilization
329 if (!IS_TRACED(surf_action))
332 snprintf(type, 100, "b%s", surf_action->category);
333 TRACE_surf_resource_utilization_event(smx_action, now, delta, type,
339 * TRACE_surf_host_set_utilization: entry point from SimGrid
341 void TRACE_surf_host_set_utilization(const char *name,
342 smx_action_t smx_action,
343 surf_action_t surf_action,
344 double value, double now,
352 //trace uncategorized host utilization
353 if (TRACE_uncategorized()){
354 TRACE_surf_resource_utilization_event(smx_action, now, delta,
355 "power_used", name, value);
358 //trace categorized utilization
359 if (!IS_TRACED(surf_action))
362 snprintf(type, 100, "p%s", surf_action->category);
363 TRACE_surf_resource_utilization_event(smx_action, now, delta, type, name,
369 * __TRACE_surf_resource_utilization_*: entry points from tracing functions
371 void TRACE_surf_resource_utilization_start(smx_action_t action)
375 TRACE_method_start(action);
378 void TRACE_surf_resource_utilization_event(smx_action_t action, double now,
380 const char *variable,
381 const char *resource,
386 TRACE_method_event(action, now, delta, variable, resource, value);
389 void TRACE_surf_resource_utilization_end(smx_action_t action)
393 TRACE_method_end(action);
396 void TRACE_surf_resource_utilization_release()
400 TRACE_method_release();
403 static void __TRACE_define_method(char *method)
405 if (!strcmp(method, "a")) {
406 TRACE_method_alloc = __TRACE_A_alloc;
407 TRACE_method_release = __TRACE_A_release;
408 TRACE_method_start = __TRACE_A_start;
409 TRACE_method_event = __TRACE_A_event;
410 TRACE_method_end = __TRACE_A_end;
411 } else if (!strcmp(method, "c")) {
412 TRACE_method_alloc = __TRACE_C_alloc;
413 TRACE_method_release = __TRACE_C_release;
414 TRACE_method_start = __TRACE_C_start;
415 TRACE_method_event = __TRACE_C_event;
416 TRACE_method_end = __TRACE_C_end;
417 } else { //default is B
418 TRACE_method_alloc = __TRACE_B_alloc;
419 TRACE_method_release = __TRACE_B_release;
420 TRACE_method_start = __TRACE_B_start;
421 TRACE_method_event = __TRACE_B_event;
422 TRACE_method_end = __TRACE_B_end;
426 void TRACE_surf_resource_utilization_alloc()
428 platform_variables = xbt_dict_new();
429 __TRACE_define_method(TRACE_get_platform_method());
430 TRACE_method_alloc();