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 '#'
14 static xbt_dict_t method_b_dict;
17 static xbt_dict_t method_c_dict;
19 /* auxiliary function for resource utilization tracing */
20 static char *strsplit (char *input, int field, char del) //caller should free the returned string
23 int length = strlen(input), i;
24 int s = 0, e = length+1;
25 int current_field = 0;
26 for (i = 0; i < length; i++){
28 if (current_field == field){
37 //copy string from s to e (with length equal to e-s) and return
38 ret = malloc ((e-s+2)*sizeof(char));
39 strncpy (ret, input+s, e-s+1);
44 //resource utilization tracing method
45 typedef enum {methodA,methodB,methodC} TracingMethod;
46 static TracingMethod currentMethod;
48 static void __TRACE_define_method (char *method)
50 if (!strcmp(method, "a")){
51 currentMethod = methodA;
52 }else if (!strcmp(method, "b")){
53 currentMethod = methodB;
54 }else if (!strcmp(method, "c")){
55 currentMethod = methodC;
57 currentMethod = methodB; //default
62 static void __TRACE_surf_resource_utilization_A (double now, double delta, const char *variable, const char *resource, double value)
64 if (!IS_TRACING_PLATFORM) return;
67 snprintf (valuestr, 100, "%f", value);
69 __TRACE_surf_check_variable_set_to_zero (now, variable, resource);
70 pajeAddVariable (now, variable, resource, valuestr);
71 pajeSubVariable (now+delta, variable, resource, valuestr);
76 static void __TRACE_surf_resource_utilization_initialize_B ()
78 method_b_dict = xbt_dict_new();
81 static void __TRACE_surf_resource_utilization_B (double now, double delta, const char *variable, const char *resource, double value)
83 if (!IS_TRACING_PLATFORM) return;
86 char nowstr[100], nowdeltastr[100];
87 char timekey[100], valuekey[100], variablekey[100];
88 char *lastvariable = NULL;
89 char *lasttime = NULL;
90 char *lastvalue = NULL;
91 char *nowdeltastr_cpy = NULL;
92 char *valuestr_cpy = NULL;
93 char *variable_cpy = NULL;
96 * The following code replaces the code above with the objective
97 * to decrease the size of file because of unnecessary add/sub on
98 * variables. It should be re-checked before put in production.
101 snprintf (valuestr, 100, "%f", value);
102 snprintf (nowstr, 100, "%f", now);
103 snprintf (nowdeltastr, 100, "%f", now+delta);
104 snprintf (timekey, 100, "%s%cTime", resource, VARIABLE_SEPARATOR);
105 snprintf (valuekey, 100, "%s%cValue", resource, VARIABLE_SEPARATOR);
106 snprintf (variablekey, 100, "%s%cVariable", resource, VARIABLE_SEPARATOR);
108 lastvariable = xbt_dict_get_or_null (method_b_dict, variablekey);
109 if (lastvariable == NULL){
110 __TRACE_surf_check_variable_set_to_zero (now, variable, resource);
111 pajeAddVariable (now, variable, resource, valuestr);
112 nowdeltastr_cpy = xbt_strdup (nowdeltastr);
113 valuestr_cpy = xbt_strdup (valuestr);
114 variable_cpy = xbt_strdup (variable);
115 xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
116 xbt_dict_set (method_b_dict, valuekey, valuestr_cpy, xbt_free);
117 xbt_dict_set (method_b_dict, variablekey, variable_cpy, xbt_free);
119 lasttime = xbt_dict_get_or_null (method_b_dict, timekey);
120 lastvalue = xbt_dict_get_or_null (method_b_dict, valuekey);
122 /* check if it is the same variable */
123 if (strcmp(lastvariable, variable) == 0){ /* same variable */
124 /* check if lasttime equals now */
125 if (atof(lasttime) == now){ /* lastime == now */
126 /* check if lastvalue equals valuestr */
127 if (atof(lastvalue) == value){ /* lastvalue == value (good, just advance time) */
128 char *nowdeltastr_cpy = xbt_strdup (nowdeltastr);
129 xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
130 }else{ /* value has changed */
131 /* value has changed, subtract previous value, add new one */
132 pajeSubVariable (atof(lasttime), variable, resource, lastvalue);
133 pajeAddVariable (atof(nowstr), variable, resource, valuestr);
134 nowdeltastr_cpy = xbt_strdup (nowdeltastr);
135 valuestr_cpy = xbt_strdup (valuestr);
136 xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
137 xbt_dict_set (method_b_dict, valuekey, valuestr_cpy, xbt_free);
139 }else{ /* lasttime != now */
140 /* the last time is different from new starting time, subtract to lasttime and add from nowstr */
141 pajeSubVariable (atof(lasttime), variable, resource, lastvalue);
142 pajeAddVariable (atof(nowstr), variable, resource, valuestr);
143 nowdeltastr_cpy = xbt_strdup (nowdeltastr);
144 valuestr_cpy = xbt_strdup (valuestr);
145 xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
146 xbt_dict_set (method_b_dict, valuekey, valuestr_cpy, xbt_free);
148 }else{ /* variable has changed */
149 pajeSubVariable (atof(lasttime), lastvariable, resource, lastvalue);
150 __TRACE_surf_check_variable_set_to_zero (now, variable, resource);
151 pajeAddVariable (now, variable, resource, valuestr);
152 nowdeltastr_cpy = xbt_strdup (nowdeltastr);
153 valuestr_cpy = xbt_strdup (valuestr);
154 variable_cpy = xbt_strdup (variable);
155 xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
156 xbt_dict_set (method_b_dict, valuekey, valuestr_cpy, xbt_free);
157 xbt_dict_set (method_b_dict, variablekey, variable_cpy, xbt_free);
163 static void __TRACE_surf_resource_utilization_finalize_B ()
165 xbt_dict_cursor_t cursor = NULL;
166 unsigned int cursor_ar = 0;
167 char *key, *value, *res;
170 char *var_cpy = NULL;
171 xbt_dynar_t resources = NULL;
172 if (!IS_TRACING_PLATFORM) return;
173 if (!xbt_dict_length(method_b_dict)){
176 /* get all resources from method_b_dict */
177 resources = xbt_dynar_new(sizeof(char*), xbt_free);
178 xbt_dict_foreach(method_b_dict, cursor, key, value) {
179 res = strsplit (key, 0, VARIABLE_SEPARATOR);
180 aux = strsplit (key, 1, VARIABLE_SEPARATOR);
181 if (strcmp (aux, "Time") == 0){ //only need to add one of three
182 var_cpy = xbt_strdup (res);
183 xbt_dynar_push (resources, &var_cpy);
189 /* iterate through resources array */
190 xbt_dynar_foreach (resources, cursor_ar, resource) {
191 char timekey[100], valuekey[100], variablekey[100];
194 char *variable = NULL;
195 snprintf (timekey, 100, "%s%cTime", resource, VARIABLE_SEPARATOR);
196 snprintf (valuekey, 100, "%s%cValue", resource, VARIABLE_SEPARATOR);
197 snprintf (variablekey, 100, "%s%cVariable", resource, VARIABLE_SEPARATOR);
199 time = xbt_dict_get_or_null (method_b_dict, timekey);
201 value = xbt_dict_get (method_b_dict, valuekey);
202 variable = xbt_dict_get (method_b_dict, variablekey);
203 pajeSubVariable (atof(time), variable, resource, value);
205 xbt_dict_remove (method_b_dict, timekey);
206 xbt_dict_remove (method_b_dict, valuekey);
207 xbt_dict_remove (method_b_dict, variablekey);
210 xbt_dict_free (&method_b_dict);
214 static void __TRACE_surf_resource_utilization_start_C (smx_action_t action)
217 snprintf (key, 100, "%p", action);
220 if (xbt_dict_get_or_null (method_c_dict, key)){
221 xbt_dict_remove (method_c_dict, key); //should never execute here, but it does
223 xbt_dict_set (method_c_dict, key, xbt_dict_new(), xbt_free);
226 static void __TRACE_surf_resource_utilization_end_C (smx_action_t action)
229 snprintf (key, 100, "%p", action);
231 xbt_dict_t action_dict = xbt_dict_get (method_c_dict, key);
232 double start_time = atof(xbt_dict_get (action_dict, "start"));
233 double end_time = atof(xbt_dict_get (action_dict, "end"));
235 xbt_dict_cursor_t cursor=NULL;
236 char *action_dict_key, *action_dict_value;
237 xbt_dict_foreach(action_dict,cursor,action_dict_key,action_dict_value) {
238 char resource[100], variable[100];
239 if (sscanf (action_dict_key, "%s %s", resource, variable) != 2) continue;
240 __TRACE_surf_check_variable_set_to_zero (start_time, variable, resource);
242 if(end_time-start_time != 0){
243 snprintf (value_str, 100, "%f", atof(action_dict_value)/(end_time-start_time));
244 pajeAddVariable (start_time, variable, resource, value_str);
245 pajeSubVariable (end_time, variable, resource, value_str);
248 xbt_dict_remove (method_c_dict, key);
251 static void __TRACE_surf_resource_utilization_C (smx_action_t action, double now, double delta, const char *variable, const char *resource, double value)
254 snprintf (key, 100, "%p", action);
256 xbt_dict_t action_dict = xbt_dict_get (method_c_dict, key);
258 if (!xbt_dict_get_or_null (action_dict, "start")){
259 char start_time[100];
260 snprintf (start_time, 100, "%f", now);
261 xbt_dict_set (action_dict, "start", xbt_strdup (start_time), xbt_free);
265 snprintf (end_time, 100, "%f", now+delta);
266 xbt_dict_set (action_dict, "end", xbt_strdup (end_time), xbt_free);
268 //accumulate the value resource-variable
270 snprintf (res_var, 300, "%s %s", resource, variable);
271 double current_value_f;
272 char *current_value = xbt_dict_get_or_null (action_dict, res_var);
274 current_value_f = atof (current_value);
275 current_value_f += value*delta;
277 current_value_f = value*delta;
279 char new_current_value[100];
280 snprintf (new_current_value, 100, "%f", current_value_f);
281 xbt_dict_set (action_dict, res_var, xbt_strdup (new_current_value), xbt_free);
284 static void __TRACE_surf_resource_utilization_initialize_C ()
286 method_c_dict = xbt_dict_new();
289 static void __TRACE_surf_resource_utilization_finalize_C ()
291 xbt_dict_free (&method_c_dict);
295 * TRACE_surf_link_set_utilization: entry point from SimGrid
297 void TRACE_surf_link_set_utilization (const char *name, smx_action_t smx_action, double value, double now, double delta)
300 if (!IS_TRACING || !IS_TRACED(smx_action)) return;
302 if (strcmp (name, "__loopback__")==0 ||
303 strcmp (name, "loopback")==0){ //ignore loopback updates
308 snprintf (type, 100, "b%s", smx_action->category);
309 __TRACE_surf_resource_utilization_event (smx_action, now, delta, type, name, value);
314 * TRACE_surf_host_set_utilization: entry point from SimGrid
316 void TRACE_surf_host_set_utilization (const char *name, smx_action_t smx_action, double value, double now, double delta)
319 if (!IS_TRACING || !IS_TRACED(smx_action)) return;
323 snprintf (type, 100, "p%s", smx_action->category);
324 __TRACE_surf_resource_utilization_event (smx_action, now, delta, type, name, value);
329 * __TRACE_surf_resource_utilization_*: entry points from tracing functions
331 void __TRACE_surf_resource_utilization_start (smx_action_t action)
333 if (currentMethod == methodC){
334 __TRACE_surf_resource_utilization_start_C (action);
338 void __TRACE_surf_resource_utilization_end (smx_action_t action)
340 if (currentMethod == methodC){
341 __TRACE_surf_resource_utilization_end_C (action);
345 void __TRACE_surf_resource_utilization_event (smx_action_t action, double now, double delta, const char *variable, const char *resource, double value)
347 if (currentMethod == methodA){
348 __TRACE_surf_resource_utilization_A (now, delta, variable, resource, value);
349 }else if (currentMethod == methodB){
350 __TRACE_surf_resource_utilization_B (now, delta, variable, resource, value);
351 }else if (currentMethod == methodC){
352 __TRACE_surf_resource_utilization_C (action, now, delta, variable, resource, value);
356 void __TRACE_surf_resource_utilization_initialize ()
358 __TRACE_define_method (_TRACE_platform_method());
360 if (currentMethod == methodA){
361 }else if (currentMethod == methodB){
362 __TRACE_surf_resource_utilization_initialize_B();
363 }else if (currentMethod == methodC){
364 __TRACE_surf_resource_utilization_initialize_C();
368 void __TRACE_surf_resource_utilization_finalize ()
370 if (currentMethod == methodA){
371 }else if (currentMethod == methodB){
372 __TRACE_surf_resource_utilization_finalize_B();
373 }else if (currentMethod == methodC){
374 __TRACE_surf_resource_utilization_finalize_C();