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 last_platform_variables; /* to control the amount of add/sub variables events:
15 dict with key {RESOURCE_NAME}#Time or {RESOURCE_NAME}#Value of dict with variables types == string */
18 static xbt_dict_t method_c_dict;
20 /* auxiliary function for resource utilization tracing */
21 static char *strsplit (char *input, int field, char del) //caller should free the returned string
24 int length = strlen(input), i;
25 int s = 0, e = length+1;
26 int current_field = 0;
27 for (i = 0; i < length; i++){
29 if (current_field == field){
38 //copy string from s to e (with length equal to e-s) and return
39 ret = malloc ((e-s+2)*sizeof(char));
40 strncpy (ret, input+s, e-s+1);
45 //resource utilization tracing method
46 typedef enum {methodA,methodB,methodC} TracingMethod;
47 static TracingMethod currentMethod;
49 static void __TRACE_define_method (char *method)
51 if (!strcmp(method, "a")){
52 currentMethod = methodA;
53 }else if (!strcmp(method, "b")){
54 currentMethod = methodB;
55 }else if (!strcmp(method, "c")){
56 currentMethod = methodC;
58 currentMethod = methodB; //default
63 static void __TRACE_surf_resource_utilization_A (double now, double delta, const char *variable, const char *resource, double value)
65 if (!IS_TRACING_PLATFORM) return;
68 snprintf (valuestr, 100, "%f", value);
70 __TRACE_surf_check_variable_set_to_zero (now, variable, resource);
71 pajeAddVariable (now, variable, resource, valuestr);
72 pajeSubVariable (now+delta, variable, resource, valuestr);
77 static void __TRACE_surf_resource_utilization_initialize_B ()
79 last_platform_variables = xbt_dict_new();
82 static void __TRACE_surf_resource_utilization_B (double now, double delta, const char *variable, const char *resource, double value)
84 if (!IS_TRACING_PLATFORM) return;
87 char nowstr[100], nowdeltastr[100];
88 char timekey[100], valuekey[100], variablekey[100];
89 char *lastvariable = NULL;
90 char *lasttime = NULL;
91 char *lastvalue = NULL;
92 char *nowdeltastr_cpy = NULL;
93 char *valuestr_cpy = NULL;
94 char *variable_cpy = NULL;
97 * The following code replaces the code above with the objective
98 * to decrease the size of file because of unnecessary add/sub on
99 * variables. It should be re-checked before put in production.
102 snprintf (valuestr, 100, "%f", value);
103 snprintf (nowstr, 100, "%f", now);
104 snprintf (nowdeltastr, 100, "%f", now+delta);
105 snprintf (timekey, 100, "%s%cTime", resource, VARIABLE_SEPARATOR);
106 snprintf (valuekey, 100, "%s%cValue", resource, VARIABLE_SEPARATOR);
107 snprintf (variablekey, 100, "%s%cVariable", resource, VARIABLE_SEPARATOR);
109 lastvariable = xbt_dict_get_or_null (last_platform_variables, variablekey);
110 if (lastvariable == NULL){
111 __TRACE_surf_check_variable_set_to_zero (now, variable, resource);
112 pajeAddVariable (now, variable, resource, valuestr);
113 nowdeltastr_cpy = xbt_strdup (nowdeltastr);
114 valuestr_cpy = xbt_strdup (valuestr);
115 variable_cpy = xbt_strdup (variable);
116 xbt_dict_set (last_platform_variables, timekey, nowdeltastr_cpy, xbt_free);
117 xbt_dict_set (last_platform_variables, valuekey, valuestr_cpy, xbt_free);
118 xbt_dict_set (last_platform_variables, variablekey, variable_cpy, xbt_free);
120 lasttime = xbt_dict_get_or_null (last_platform_variables, timekey);
121 lastvalue = xbt_dict_get_or_null (last_platform_variables, valuekey);
123 /* check if it is the same variable */
124 if (strcmp(lastvariable, variable) == 0){ /* same variable */
125 /* check if lasttime equals now */
126 if (atof(lasttime) == now){ /* lastime == now */
127 /* check if lastvalue equals valuestr */
128 if (atof(lastvalue) == value){ /* lastvalue == value (good, just advance time) */
129 char *nowdeltastr_cpy = xbt_strdup (nowdeltastr);
130 xbt_dict_set (last_platform_variables, timekey, nowdeltastr_cpy, xbt_free);
131 }else{ /* value has changed */
132 /* value has changed, subtract previous value, add new one */
133 pajeSubVariable (atof(lasttime), variable, resource, lastvalue);
134 pajeAddVariable (atof(nowstr), variable, resource, valuestr);
135 nowdeltastr_cpy = xbt_strdup (nowdeltastr);
136 valuestr_cpy = xbt_strdup (valuestr);
137 xbt_dict_set (last_platform_variables, timekey, nowdeltastr_cpy, xbt_free);
138 xbt_dict_set (last_platform_variables, valuekey, valuestr_cpy, xbt_free);
140 }else{ /* lasttime != now */
141 /* the last time is different from new starting time, subtract to lasttime and add from nowstr */
142 pajeSubVariable (atof(lasttime), variable, resource, lastvalue);
143 pajeAddVariable (atof(nowstr), variable, resource, valuestr);
144 nowdeltastr_cpy = xbt_strdup (nowdeltastr);
145 valuestr_cpy = xbt_strdup (valuestr);
146 xbt_dict_set (last_platform_variables, timekey, nowdeltastr_cpy, xbt_free);
147 xbt_dict_set (last_platform_variables, valuekey, valuestr_cpy, xbt_free);
149 }else{ /* variable has changed */
150 pajeSubVariable (atof(lasttime), lastvariable, resource, lastvalue);
151 __TRACE_surf_check_variable_set_to_zero (now, variable, resource);
152 pajeAddVariable (now, variable, resource, valuestr);
153 nowdeltastr_cpy = xbt_strdup (nowdeltastr);
154 valuestr_cpy = xbt_strdup (valuestr);
155 variable_cpy = xbt_strdup (variable);
156 xbt_dict_set (last_platform_variables, timekey, nowdeltastr_cpy, xbt_free);
157 xbt_dict_set (last_platform_variables, valuekey, valuestr_cpy, xbt_free);
158 xbt_dict_set (last_platform_variables, variablekey, variable_cpy, xbt_free);
164 static void __TRACE_surf_resource_utilization_finalize_B ()
166 xbt_dict_cursor_t cursor = NULL;
167 unsigned int cursor_ar = 0;
168 char *key, *value, *res;
171 char *var_cpy = NULL;
172 xbt_dynar_t resources = NULL;
173 if (!IS_TRACING_PLATFORM) return;
174 if (!xbt_dict_length(last_platform_variables)){
177 /* get all resources from last_platform_variables */
178 resources = xbt_dynar_new(sizeof(char*), xbt_free);
179 xbt_dict_foreach(last_platform_variables, cursor, key, value) {
180 res = strsplit (key, 0, VARIABLE_SEPARATOR);
181 aux = strsplit (key, 1, VARIABLE_SEPARATOR);
182 if (strcmp (aux, "Time") == 0){ //only need to add one of three
183 var_cpy = xbt_strdup (res);
184 xbt_dynar_push (resources, &var_cpy);
190 /* iterate through resources array */
191 xbt_dynar_foreach (resources, cursor_ar, resource) {
192 char timekey[100], valuekey[100], variablekey[100];
195 char *variable = NULL;
196 snprintf (timekey, 100, "%s%cTime", resource, VARIABLE_SEPARATOR);
197 snprintf (valuekey, 100, "%s%cValue", resource, VARIABLE_SEPARATOR);
198 snprintf (variablekey, 100, "%s%cVariable", resource, VARIABLE_SEPARATOR);
200 time = xbt_dict_get_or_null (last_platform_variables, timekey);
202 value = xbt_dict_get (last_platform_variables, valuekey);
203 variable = xbt_dict_get (last_platform_variables, variablekey);
204 pajeSubVariable (atof(time), variable, resource, value);
206 xbt_dict_remove (last_platform_variables, timekey);
207 xbt_dict_remove (last_platform_variables, valuekey);
208 xbt_dict_remove (last_platform_variables, variablekey);
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);
225 //fprintf (stderr, "start %p\n", action);
228 if (xbt_dict_get_or_null (start_time, key)){
229 xbt_dict_remove (start_time, key);
234 static void __TRACE_surf_resource_utilization_end_C (smx_action_t action)
237 snprintf (key, 100, "%p", action);
239 xbt_dict_t action_dict = xbt_dict_get (method_c_dict, key);
240 // fprintf (stderr, "end %p (%f - %f)\n", action, atof(xbt_dict_get_or_null(action_dict, "start")),
241 // atof(xbt_dict_get_or_null(action_dict, "end")));
243 double start_time = atof(xbt_dict_get (action_dict, "start"));
244 double end_time = atof(xbt_dict_get (action_dict, "end"));
246 xbt_dict_cursor_t cursor=NULL;
247 char *action_dict_key, *action_dict_value;
248 xbt_dict_foreach(action_dict,cursor,action_dict_key,action_dict_value) {
249 char resource[100], variable[100];
250 if (sscanf (action_dict_key, "%s %s", resource, variable) != 2) continue;
251 __TRACE_surf_check_variable_set_to_zero (start_time, variable, resource);
253 if(end_time-start_time != 0){
254 snprintf (value_str, 100, "%f", atof(action_dict_value)/(end_time-start_time));
255 pajeAddVariable (start_time, variable, resource, value_str);
256 pajeSubVariable (end_time, variable, resource, value_str);
259 //fprintf(stderr, "\t%p (key=%s) %s %s = %s\n",action, action_dict_key, resource, variable, action_dict_value);
260 //fprintf(stderr, "\t%f %f\n", start_time, end_time);
262 //fprintf (stderr, "\n");
264 xbt_dict_remove (method_c_dict, key);
267 if (xbt_dict_get_or_null (start_time_dict, key)){
268 xbt_dict_remove (start_time_dict, key);
270 if (xbt_dict_get_or_null (end_time_dict, key)){
271 xbt_dict_remove (end_time_dict, key);
277 static void __TRACE_surf_resource_utilization_C (smx_action_t action, double now, double delta, const char *variable, const char *resource, double value)
280 snprintf (key, 100, "%p", action);
282 xbt_dict_t action_dict = xbt_dict_get (method_c_dict, key);
284 if (!xbt_dict_get_or_null (action_dict, "start")){
285 char start_time[100];
286 snprintf (start_time, 100, "%f", now);
287 xbt_dict_set (action_dict, "start", xbt_strdup (start_time), xbt_free);
291 snprintf (end_time, 100, "%f", now+delta);
292 xbt_dict_set (action_dict, "end", xbt_strdup (end_time), xbt_free);
294 //accumulate the value resource-variable
296 snprintf (res_var, 300, "%s %s", resource, variable);
297 double current_value_f;
298 char *current_value = xbt_dict_get_or_null (action_dict, res_var);
300 current_value_f = atof (current_value);
301 current_value_f += value*delta;
303 current_value_f = value*delta;
305 char new_current_value[100];
306 snprintf (new_current_value, 100, "%f", current_value_f);
307 xbt_dict_set (action_dict, res_var, xbt_strdup (new_current_value), xbt_free);
309 //fprintf (stderr, "event act=%p, now=%f, delta=%f, %s - %s %f\n", action, now, delta, resource, variable, value);
312 static void __TRACE_surf_resource_utilization_initialize_C ()
314 //start_time_dict = xbt_dict_new();
315 //end_time_dict = xbt_dict_new();
316 method_c_dict = xbt_dict_new();
319 static void __TRACE_surf_resource_utilization_finalize_C ()
321 xbt_dict_free (&method_c_dict);
325 * TRACE_surf_link_set_utilization: entry point from SimGrid
327 void TRACE_surf_link_set_utilization (const char *name, smx_action_t smx_action, double value, double now, double delta)
330 if (!IS_TRACING || !IS_TRACED(smx_action)) return;
332 if (strcmp (name, "__loopback__")==0 ||
333 strcmp (name, "loopback")==0){ //ignore loopback updates
337 if (value == 0) return;
339 //if (!xbt_dict_get_or_null (created_links, name)){
340 // TRACE_surf_link_missing ();
344 snprintf (type, 100, "b%s", smx_action->category);
345 __TRACE_surf_resource_utilization_event (smx_action, now, delta, type, name, value);
346 //fprintf (stderr, "%p - (%f - %f = %f) %s %f metric = %f\n", smx_action, now, now+delta, delta, name, value, value*delta);
347 // __TRACE_surf_update_action_state_resource (now, delta, type, name, 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, double value, double now, double delta)
357 if (!IS_TRACING || !IS_TRACED(smx_action)) return;
362 snprintf (type, 100, "p%s", smx_action->category);
363 __TRACE_surf_resource_utilization_event (smx_action, now, delta, type, name, value);
364 //fprintf (stderr, "%p - (%f - %f = %f) %s %f metric = %f\n", smx_action, now, now+delta, delta, name, value, value*delta);
365 // __TRACE_surf_update_action_state_resource (now, delta, type, name, value);
370 * __TRACE_surf_resource_utilization_*: entry points from tracing functions
372 void __TRACE_surf_resource_utilization_start (smx_action_t action)
374 if (currentMethod == methodC){
375 __TRACE_surf_resource_utilization_start_C (action);
379 void __TRACE_surf_resource_utilization_end (smx_action_t action)
381 if (currentMethod == methodC){
382 __TRACE_surf_resource_utilization_end_C (action);
386 void __TRACE_surf_resource_utilization_event (smx_action_t action, double now, double delta, const char *variable, const char *resource, double value)
388 if (currentMethod == methodA){
389 __TRACE_surf_resource_utilization_A (now, delta, variable, resource, value);
390 }else if (currentMethod == methodB){
391 __TRACE_surf_resource_utilization_B (now, delta, variable, resource, value);
392 }else if (currentMethod == methodC){
393 __TRACE_surf_resource_utilization_C (action, now, delta, variable, resource, value);
397 void __TRACE_surf_resource_utilization_initialize ()
399 __TRACE_define_method (_TRACE_platform_method());
401 if (currentMethod == methodA){
402 }else if (currentMethod == methodB){
403 __TRACE_surf_resource_utilization_initialize_B();
404 }else if (currentMethod == methodC){
405 __TRACE_surf_resource_utilization_initialize_C();
409 void __TRACE_surf_resource_utilization_finalize ()
411 if (currentMethod == methodA){
412 }else if (currentMethod == methodB){
413 __TRACE_surf_resource_utilization_finalize_B();
414 }else if (currentMethod == methodC){
415 __TRACE_surf_resource_utilization_finalize_C();