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 typedef enum {methodA,methodB,methodC} TracingMethod;
49 static TracingMethod currentMethod;
51 static void __TRACE_define_method (char *method)
53 if (!strcmp(method, "a")){
54 currentMethod = methodA;
55 }else if (!strcmp(method, "b")){
56 currentMethod = methodB;
57 }else if (!strcmp(method, "c")){
58 currentMethod = methodC;
60 currentMethod = methodB; //default
65 static void __TRACE_surf_check_variable_set_to_zero (double now, const char *variable, const char *resource)
67 /* check if we have to set it to 0 */
68 if (!xbt_dict_get_or_null (platform_variables, resource)){
69 xbt_dynar_t array = xbt_dynar_new(sizeof(char*), xbt_free);
70 char *var_cpy = xbt_strdup(variable);
71 xbt_dynar_push (array, &var_cpy);
72 if (IS_TRACING_PLATFORM) pajeSetVariable (now, variable, resource, "0");
73 xbt_dict_set (platform_variables, resource, array, xbt_dynar_free_voidp);
75 xbt_dynar_t array = xbt_dict_get (platform_variables, resource);
79 xbt_dynar_foreach (array, i, cat) {
80 if (strcmp(variable, cat)==0){
85 char *var_cpy = xbt_strdup(variable);
86 xbt_dynar_push (array, &var_cpy);
87 if (IS_TRACING_PLATFORM) pajeSetVariable (now, variable, resource, "0");
94 static void __TRACE_surf_resource_utilization_A (double now, double delta, const char *variable, const char *resource, double value)
96 if (!IS_TRACING_PLATFORM) return;
99 snprintf (valuestr, 100, "%f", value);
101 __TRACE_surf_check_variable_set_to_zero (now, variable, resource);
102 pajeAddVariable (now, variable, resource, valuestr);
103 pajeSubVariable (now+delta, variable, resource, valuestr);
108 static void __TRACE_surf_resource_utilization_initialize_B ()
110 method_b_dict = xbt_dict_new();
113 static void __TRACE_surf_resource_utilization_B (double now, double delta, const char *variable, const char *resource, double value)
115 if (!IS_TRACING_PLATFORM) return;
118 char nowstr[100], nowdeltastr[100];
119 char timekey[100], valuekey[100], variablekey[100];
120 char *lastvariable = NULL;
121 char *lasttime = NULL;
122 char *lastvalue = NULL;
123 char *nowdeltastr_cpy = NULL;
124 char *valuestr_cpy = NULL;
125 char *variable_cpy = NULL;
128 * The following code replaces the code above with the objective
129 * to decrease the size of file because of unnecessary add/sub on
130 * variables. It should be re-checked before put in production.
133 snprintf (valuestr, 100, "%f", value);
134 snprintf (nowstr, 100, "%f", now);
135 snprintf (nowdeltastr, 100, "%f", now+delta);
136 snprintf (timekey, 100, "%s%cTime", resource, VARIABLE_SEPARATOR);
137 snprintf (valuekey, 100, "%s%cValue", resource, VARIABLE_SEPARATOR);
138 snprintf (variablekey, 100, "%s%cVariable", resource, VARIABLE_SEPARATOR);
140 lastvariable = xbt_dict_get_or_null (method_b_dict, variablekey);
141 if (lastvariable == NULL){
142 __TRACE_surf_check_variable_set_to_zero (now, variable, resource);
143 pajeAddVariable (now, variable, resource, valuestr);
144 nowdeltastr_cpy = xbt_strdup (nowdeltastr);
145 valuestr_cpy = xbt_strdup (valuestr);
146 variable_cpy = xbt_strdup (variable);
147 xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
148 xbt_dict_set (method_b_dict, valuekey, valuestr_cpy, xbt_free);
149 xbt_dict_set (method_b_dict, variablekey, variable_cpy, xbt_free);
151 lasttime = xbt_dict_get_or_null (method_b_dict, timekey);
152 lastvalue = xbt_dict_get_or_null (method_b_dict, valuekey);
154 /* check if it is the same variable */
155 if (strcmp(lastvariable, variable) == 0){ /* same variable */
156 /* check if lasttime equals now */
157 if (atof(lasttime) == now){ /* lastime == now */
158 /* check if lastvalue equals valuestr */
159 if (atof(lastvalue) == value){ /* lastvalue == value (good, just advance time) */
160 char *nowdeltastr_cpy = xbt_strdup (nowdeltastr);
161 xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
162 }else{ /* value has changed */
163 /* value has changed, subtract previous value, add new one */
164 pajeSubVariable (atof(lasttime), variable, resource, lastvalue);
165 pajeAddVariable (atof(nowstr), variable, resource, valuestr);
166 nowdeltastr_cpy = xbt_strdup (nowdeltastr);
167 valuestr_cpy = xbt_strdup (valuestr);
168 xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
169 xbt_dict_set (method_b_dict, valuekey, valuestr_cpy, xbt_free);
171 }else{ /* lasttime != now */
172 /* the last time is different from new starting time, subtract to lasttime and add from nowstr */
173 pajeSubVariable (atof(lasttime), variable, resource, lastvalue);
174 pajeAddVariable (atof(nowstr), variable, resource, valuestr);
175 nowdeltastr_cpy = xbt_strdup (nowdeltastr);
176 valuestr_cpy = xbt_strdup (valuestr);
177 xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
178 xbt_dict_set (method_b_dict, valuekey, valuestr_cpy, xbt_free);
180 }else{ /* variable has changed */
181 pajeSubVariable (atof(lasttime), lastvariable, resource, lastvalue);
182 __TRACE_surf_check_variable_set_to_zero (now, variable, resource);
183 pajeAddVariable (now, variable, resource, valuestr);
184 nowdeltastr_cpy = xbt_strdup (nowdeltastr);
185 valuestr_cpy = xbt_strdup (valuestr);
186 variable_cpy = xbt_strdup (variable);
187 xbt_dict_set (method_b_dict, timekey, nowdeltastr_cpy, xbt_free);
188 xbt_dict_set (method_b_dict, valuekey, valuestr_cpy, xbt_free);
189 xbt_dict_set (method_b_dict, variablekey, variable_cpy, xbt_free);
195 static void __TRACE_surf_resource_utilization_finalize_B ()
197 xbt_dict_cursor_t cursor = NULL;
198 unsigned int cursor_ar = 0;
199 char *key, *value, *res;
202 char *var_cpy = NULL;
203 xbt_dynar_t resources = NULL;
204 if (!IS_TRACING_PLATFORM) return;
205 if (!xbt_dict_length(method_b_dict)){
208 /* get all resources from method_b_dict */
209 resources = xbt_dynar_new(sizeof(char*), xbt_free);
210 xbt_dict_foreach(method_b_dict, cursor, key, value) {
211 res = strsplit (key, 0, VARIABLE_SEPARATOR);
212 aux = strsplit (key, 1, VARIABLE_SEPARATOR);
213 if (strcmp (aux, "Time") == 0){ //only need to add one of three
214 var_cpy = xbt_strdup (res);
215 xbt_dynar_push (resources, &var_cpy);
221 /* iterate through resources array */
222 xbt_dynar_foreach (resources, cursor_ar, resource) {
223 char timekey[100], valuekey[100], variablekey[100];
226 char *variable = NULL;
227 snprintf (timekey, 100, "%s%cTime", resource, VARIABLE_SEPARATOR);
228 snprintf (valuekey, 100, "%s%cValue", resource, VARIABLE_SEPARATOR);
229 snprintf (variablekey, 100, "%s%cVariable", resource, VARIABLE_SEPARATOR);
231 time = xbt_dict_get_or_null (method_b_dict, timekey);
233 value = xbt_dict_get (method_b_dict, valuekey);
234 variable = xbt_dict_get (method_b_dict, variablekey);
235 pajeSubVariable (atof(time), variable, resource, value);
237 xbt_dict_remove (method_b_dict, timekey);
238 xbt_dict_remove (method_b_dict, valuekey);
239 xbt_dict_remove (method_b_dict, variablekey);
242 xbt_dict_free (&method_b_dict);
246 static void __TRACE_surf_resource_utilization_start_C (smx_action_t action)
249 snprintf (key, 100, "%p", action);
252 if (xbt_dict_get_or_null (method_c_dict, key)){
253 xbt_dict_remove (method_c_dict, key); //should never execute here, but it does
255 xbt_dict_set (method_c_dict, key, xbt_dict_new(), xbt_free);
258 static void __TRACE_surf_resource_utilization_end_C (smx_action_t action)
261 snprintf (key, 100, "%p", action);
263 xbt_dict_t action_dict = xbt_dict_get (method_c_dict, key);
264 double start_time = atof(xbt_dict_get (action_dict, "start"));
265 double end_time = atof(xbt_dict_get (action_dict, "end"));
267 xbt_dict_cursor_t cursor=NULL;
268 char *action_dict_key, *action_dict_value;
269 xbt_dict_foreach(action_dict,cursor,action_dict_key,action_dict_value) {
270 char resource[100], variable[100];
271 if (sscanf (action_dict_key, "%s %s", resource, variable) != 2) continue;
272 __TRACE_surf_check_variable_set_to_zero (start_time, variable, resource);
274 if(end_time-start_time != 0){
275 snprintf (value_str, 100, "%f", atof(action_dict_value)/(end_time-start_time));
276 pajeAddVariable (start_time, variable, resource, value_str);
277 pajeSubVariable (end_time, variable, resource, value_str);
280 xbt_dict_remove (method_c_dict, key);
283 static void __TRACE_surf_resource_utilization_C (smx_action_t action, double now, double delta, const char *variable, const char *resource, double value)
286 snprintf (key, 100, "%p", action);
288 xbt_dict_t action_dict = xbt_dict_get (method_c_dict, key);
290 if (!xbt_dict_get_or_null (action_dict, "start")){
291 char start_time[100];
292 snprintf (start_time, 100, "%f", now);
293 xbt_dict_set (action_dict, "start", xbt_strdup (start_time), xbt_free);
297 snprintf (end_time, 100, "%f", now+delta);
298 xbt_dict_set (action_dict, "end", xbt_strdup (end_time), xbt_free);
300 //accumulate the value resource-variable
302 snprintf (res_var, 300, "%s %s", resource, variable);
303 double current_value_f;
304 char *current_value = xbt_dict_get_or_null (action_dict, res_var);
306 current_value_f = atof (current_value);
307 current_value_f += value*delta;
309 current_value_f = value*delta;
311 char new_current_value[100];
312 snprintf (new_current_value, 100, "%f", current_value_f);
313 xbt_dict_set (action_dict, res_var, xbt_strdup (new_current_value), xbt_free);
316 static void __TRACE_surf_resource_utilization_initialize_C ()
318 method_c_dict = xbt_dict_new();
321 static void __TRACE_surf_resource_utilization_finalize_C ()
323 xbt_dict_free (&method_c_dict);
327 * TRACE_surf_link_set_utilization: entry point from SimGrid
329 void TRACE_surf_link_set_utilization (const char *name, smx_action_t smx_action, double value, double now, double delta)
332 if (!IS_TRACING || !IS_TRACED(smx_action)) return;
334 if (strcmp (name, "__loopback__")==0 ||
335 strcmp (name, "loopback")==0){ //ignore loopback updates
340 snprintf (type, 100, "b%s", smx_action->category);
341 __TRACE_surf_resource_utilization_event (smx_action, now, delta, type, name, value);
346 * TRACE_surf_host_set_utilization: entry point from SimGrid
348 void TRACE_surf_host_set_utilization (const char *name, smx_action_t smx_action, double value, double now, double delta)
351 if (!IS_TRACING || !IS_TRACED(smx_action)) return;
355 snprintf (type, 100, "p%s", smx_action->category);
356 __TRACE_surf_resource_utilization_event (smx_action, now, delta, type, name, value);
361 * __TRACE_surf_resource_utilization_*: entry points from tracing functions
363 void __TRACE_surf_resource_utilization_start (smx_action_t action)
365 if (currentMethod == methodC){
366 __TRACE_surf_resource_utilization_start_C (action);
370 void __TRACE_surf_resource_utilization_end (smx_action_t action)
372 if (currentMethod == methodC){
373 __TRACE_surf_resource_utilization_end_C (action);
377 void __TRACE_surf_resource_utilization_event (smx_action_t action, double now, double delta, const char *variable, const char *resource, double value)
379 if (currentMethod == methodA){
380 __TRACE_surf_resource_utilization_A (now, delta, variable, resource, value);
381 }else if (currentMethod == methodB){
382 __TRACE_surf_resource_utilization_B (now, delta, variable, resource, value);
383 }else if (currentMethod == methodC){
384 __TRACE_surf_resource_utilization_C (action, now, delta, variable, resource, value);
388 void __TRACE_surf_resource_utilization_initialize ()
390 platform_variables = xbt_dict_new();
392 __TRACE_define_method (_TRACE_platform_method());
394 if (currentMethod == methodA){
395 }else if (currentMethod == methodB){
396 __TRACE_surf_resource_utilization_initialize_B();
397 }else if (currentMethod == methodC){
398 __TRACE_surf_resource_utilization_initialize_C();
402 void __TRACE_surf_resource_utilization_finalize ()
404 if (currentMethod == methodA){
405 }else if (currentMethod == methodB){
406 __TRACE_surf_resource_utilization_finalize_B();
407 }else if (currentMethod == methodC){
408 __TRACE_surf_resource_utilization_finalize_C();