Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
try to get rid of smpi tracing segmentation faults on some platforms.
[simgrid.git] / src / instr / instr_interface.cpp
1 /* Copyright (c) 2010-2015. The SimGrid Team.
2  * All rights reserved.                                                     */
3
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. */
6
7 #include "simgrid_config.h"
8 #include "src/surf/network_interface.hpp"
9 #include "src/instr/instr_private.h"
10 #include "surf/surf.h"
11 #include "src/surf/surf_private.h"
12
13 typedef enum {
14   INSTR_US_DECLARE,
15   INSTR_US_SET,
16   INSTR_US_ADD,
17   INSTR_US_SUB
18 } InstrUserVariable;
19
20 XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_api, instr, "API");
21
22 xbt_dict_t created_categories = NULL;
23 xbt_dict_t declared_marks = NULL;
24 xbt_dict_t user_host_variables = NULL;
25 xbt_dict_t user_vm_variables = NULL;
26 xbt_dict_t user_link_variables = NULL;
27 extern xbt_dict_t trivaNodeTypes;
28 extern xbt_dict_t trivaEdgeTypes;
29
30 static xbt_dynar_t instr_dict_to_dynar (xbt_dict_t filter)
31 {
32   if (!TRACE_is_enabled()) return NULL;
33   if (!TRACE_needs_platform()) return NULL;
34
35   xbt_dynar_t ret = xbt_dynar_new (sizeof(char*), &xbt_free_ref);
36   xbt_dict_cursor_t cursor = NULL;
37   char *name, *value;
38   xbt_dict_foreach(filter, cursor, name, value) {
39     xbt_dynar_push_as (ret, char*, xbt_strdup(name));
40   }
41   return ret;
42 }
43
44 /** \ingroup TRACE_category
45  *  \brief Declare a new category with a random color.
46  *
47  *  This function should be used to define a user category. The category can be used to differentiate the tasks that
48  *  are created during the simulation (for example, tasks from server1, server2, or request tasks, computation tasks,
49  *  communication tasks). All resource utilization (host power and link bandwidth) will be classified according to the
50  *  task category. Tasks that do not belong to a category are not traced. The color for the category that is being
51  *  declared is random. This function has no effect if a category with the same name has been already declared.
52  *
53  * See \ref tracing for details on how to trace the (categorized) resource utilization.
54  *
55  *  \param category The name of the new tracing category to be created.
56  *
57  *  \see TRACE_category_with_color, MSG_task_set_category, SD_task_set_category
58  */
59 void TRACE_category(const char *category)
60 {
61   TRACE_category_with_color (category, NULL);
62 }
63
64 /** \ingroup TRACE_category
65  *  \brief Declare a new category with a color.
66  *
67  *  Same as #TRACE_category, but let user specify a color encoded as a RGB-like string with three floats from 0 to 1.
68  *  So, to specify a red color, pass "1 0 0" as color parameter. A light-gray color can be specified using "0.7 0.7 0.7"
69  *   as color. This function has no effect if a category with the same name has been already declared.
70  *
71  * See \ref tracing for details on how to trace the (categorized) resource utilization.
72  *
73  *  \param category The name of the new tracing category to be created.
74  *  \param color The color of the category (see \ref tracing to
75  *  know how to correctly specify the color)
76  *
77  *  \see MSG_task_set_category, SD_task_set_category
78  */
79 void TRACE_category_with_color (const char *category, const char *color)
80 {
81   /* safe switch */
82   if (!TRACE_is_enabled()) return;
83
84   if (!(TRACE_categorized() && category != NULL)) return;
85
86   /* if platform is not traced, we can't deal with categories */
87   if (!TRACE_needs_platform()) return;
88
89   //check if category is already created
90   char *created = (char*)xbt_dict_get_or_null(created_categories, category);
91   if (created) return;
92   xbt_dict_set (created_categories, category, xbt_strdup("1"), NULL);
93
94   //define final_color
95   char final_color[INSTR_DEFAULT_STR_SIZE];
96   if (!color){
97     //generate a random color
98     double red = drand48();
99     double green = drand48();
100     double blue = drand48();
101     snprintf (final_color, INSTR_DEFAULT_STR_SIZE, "%f %f %f", red, green, blue);
102   }else{
103     snprintf (final_color, INSTR_DEFAULT_STR_SIZE, "%s", color);
104   }
105
106   XBT_DEBUG("CAT,declare %s, \"%s\" \"%s\"", category, color, final_color);
107
108   //define the type of this category on top of hosts and links
109   instr_new_variable_type (category, final_color);
110 }
111
112 /** \ingroup TRACE_category
113  *  \brief Get declared categories
114  *
115  * This function should be used to get categories that were already declared with #TRACE_category or with
116  * #TRACE_category_with_color.
117  *
118  * See \ref tracing for details on how to trace the (categorized) resource utilization.
119  *
120  * \return A dynar with the declared categories, must be freed with xbt_dynar_free.
121  *
122  *  \see MSG_task_set_category, SD_task_set_category
123  */
124 xbt_dynar_t TRACE_get_categories (void)
125 {
126   if (!TRACE_is_enabled()) return NULL;
127   if (!TRACE_categorized()) return NULL;
128
129   return instr_dict_to_dynar (created_categories);
130 }
131
132 /** \ingroup TRACE_mark
133  * \brief Declare a new type for tracing mark.
134  *
135  * This function declares a new Paje event type in the trace file that can be used by simulators to declare
136  * application-level marks. This function is independent of which API is used in SimGrid.
137  *
138  * \param mark_type The name of the new type.
139  *
140  * \see TRACE_mark
141  */
142 void TRACE_declare_mark(const char *mark_type)
143 {
144   /* safe switch */
145   if (!TRACE_is_enabled()) return;
146
147   /* if platform is not traced, we don't allow marks */
148   if (!TRACE_needs_platform()) return;
149
150   if (!mark_type) THROWF (tracing_error, 1, "mark_type is NULL");
151
152   //check if mark_type is already declared
153   char *created = (char*)xbt_dict_get_or_null(declared_marks, mark_type);
154   if (created) {
155     THROWF (tracing_error, 1, "mark_type with name (%s) is already declared", mark_type);
156   }
157
158   XBT_DEBUG("MARK,declare %s", mark_type);
159   PJ_type_event_new(mark_type, PJ_type_get_root());
160   xbt_dict_set (declared_marks, mark_type, xbt_strdup("1"), NULL);
161 }
162
163 /** \ingroup TRACE_mark
164  * \brief Declare a new colored value for a previously declared mark type.
165  *
166  * This function declares a new colored value for a Paje event type in the trace file that can be used by simulators to
167  * declare application-level marks. This function is independent of which API is used in SimGrid. The color needs to be
168  * a string with three numbers separated by spaces in the range [0,1].
169  * A light-gray color can be specified using "0.7 0.7 0.7" as color. If a NULL color is provided, the color used will
170  * be white ("1 1 1").
171  *
172  * \param mark_type The name of the new type.
173  * \param mark_value The name of the new value for this type.
174  * \param mark_color The color of the new value for this type.
175  *
176  * \see TRACE_mark
177  */
178 void TRACE_declare_mark_value_with_color (const char *mark_type, const char *mark_value, const char *mark_color)
179 {
180   /* safe switch */
181   if (!TRACE_is_enabled()) return;
182
183   /* if platform is not traced, we don't allow marks */
184   if (!TRACE_needs_platform()) return;
185
186   if (!mark_type) THROWF (tracing_error, 1, "mark_type is NULL");
187   if (!mark_value) THROWF (tracing_error, 1, "mark_value is NULL");
188
189   type_t type = PJ_type_get (mark_type, PJ_type_get_root());
190   if (!type){
191     THROWF (tracing_error, 1, "mark_type with name (%s) is not declared", mark_type);
192   }
193
194   char white[INSTR_DEFAULT_STR_SIZE] = "1.0 1.0 1.0";
195   if (!mark_color) mark_color = white;
196
197   XBT_DEBUG("MARK,declare_value %s %s %s", mark_type, mark_value, mark_color);
198   PJ_value_new (mark_value, mark_color, type);
199 }
200
201 /** \ingroup TRACE_mark
202  * \brief Declare a new value for a previously declared mark type.
203  *
204  * This function declares a new value for a Paje event type in the trace file that can be used by simulators to declare
205  * application-level marks. This function is independent of which API is used in SimGrid. Calling this function is the
206  * same as calling \ref TRACE_declare_mark_value_with_color with a NULL color.
207  *
208  * \param mark_type The name of the new type.
209  * \param mark_value The name of the new value for this type.
210  *
211  * \see TRACE_mark
212  */
213 void TRACE_declare_mark_value (const char *mark_type, const char *mark_value)
214 {
215   TRACE_declare_mark_value_with_color (mark_type, mark_value, NULL);
216 }
217
218 /**
219  * \ingroup TRACE_mark
220  * \brief Create a new instance of a tracing mark type.
221  *
222  * This function creates a mark in the trace file. The first parameter had to be previously declared using
223  * #TRACE_declare_mark, the second is the identifier for this mark instance. We recommend that the mark_value is a
224  * unique value for the whole simulation. Nevertheless, this is not a strong requirement: the trace will be valid even
225  * if there are multiple mark identifiers for the same trace.
226  *
227  * \param mark_type The name of the type for which the new instance will belong.
228  * \param mark_value The name of the new instance mark.
229  *
230  * \see TRACE_declare_mark
231  */
232 void TRACE_mark(const char *mark_type, const char *mark_value)
233 {
234   /* safe switch */
235   if (!TRACE_is_enabled()) return;
236
237   /* if platform is not traced, we don't allow marks */
238   if (!TRACE_needs_platform()) return;
239
240   if (!mark_type) THROWF (tracing_error, 1, "mark_type is NULL");
241   if (!mark_value) THROWF (tracing_error, 1, "mark_value is NULL");
242
243   //check if mark_type is already declared
244   type_t type = PJ_type_get (mark_type, PJ_type_get_root());
245   if (!type){
246     THROWF (tracing_error, 1, "mark_type with name (%s) is not declared", mark_type);
247   }
248
249   val_t value = PJ_value_get (mark_value, type);
250   XBT_DEBUG("MARK %s %s", mark_type, mark_value);
251   new_pajeNewEvent (MSG_get_clock(), PJ_container_get_root(), type, value);
252 }
253
254 /** \ingroup TRACE_mark
255  *  \brief Get declared marks
256  *
257  * This function should be used to get marks that were already declared with #TRACE_declare_mark.
258  *
259  * \return A dynar with the declared marks, must be freed with xbt_dynar_free.
260  */
261 xbt_dynar_t TRACE_get_marks (void)
262 {
263   if (!TRACE_is_enabled()) return NULL;
264
265   return instr_dict_to_dynar (declared_marks);
266 }
267
268 static void instr_user_variable(double time, const char *resource, const char *variable, const char *father_type,
269                          double value, InstrUserVariable what, const char *color, xbt_dict_t filter)
270 {
271   /* safe switch */
272   if (!TRACE_is_enabled()) return;
273
274   /* if platform is not traced, we don't allow user variables */
275   if (!TRACE_needs_platform()) return;
276
277   //check if variable is already declared
278   char *created = (char*)xbt_dict_get_or_null(filter, variable);
279   if (what == INSTR_US_DECLARE){
280     if (created){//already declared
281       return;
282     }else{
283       xbt_dict_set (filter, variable, xbt_strdup("1"), NULL);
284     }
285   }else{
286     if (!created){//not declared, ignore
287       return;
288     }
289   }
290
291   char valuestr[100];
292   snprintf(valuestr, 100, "%g", value);
293
294   switch (what){
295   case INSTR_US_DECLARE:
296     instr_new_user_variable_type (father_type, variable, color);
297     break;
298   case INSTR_US_SET:
299     {
300       container_t container = PJ_container_get(resource);
301       type_t type = PJ_type_get (variable, container->type);
302       new_pajeSetVariable(time, container, type, value);
303     }
304     break;
305   case INSTR_US_ADD:
306     {
307       container_t container = PJ_container_get(resource);
308       type_t type = PJ_type_get (variable, container->type);
309       new_pajeAddVariable(time, container, type, value);
310     }
311     break;
312   case INSTR_US_SUB:
313     {
314       container_t container = PJ_container_get(resource);
315       type_t type = PJ_type_get (variable, container->type);
316       new_pajeSubVariable(time, container, type, value);
317     }
318      break;
319   default:
320     //TODO: launch exception
321     break;
322   }
323 }
324
325 static void instr_user_srcdst_variable(double time, const char *src, const char *dst, const char *variable,
326                               const char *father_type, double value, InstrUserVariable what)
327 {
328   sg_netcard_t src_elm = sg_netcard_by_name_or_null(src);
329   if(!src_elm) xbt_die("Element '%s' not found!",src);
330
331   sg_netcard_t dst_elm = sg_netcard_by_name_or_null(dst);
332   if(!dst_elm) xbt_die("Element '%s' not found!",dst);
333
334   std::vector<Link*> *route = new std::vector<Link*>();
335   routing_platf->getRouteAndLatency (src_elm, dst_elm, route,NULL);
336   for (auto link : *route)
337     instr_user_variable (time, link->getName(), variable, father_type, value, what, NULL, user_link_variables);
338   delete route;
339 }
340
341 /** \ingroup TRACE_API
342  *  \brief Creates a file with the topology of the platform file used for the simulator.
343  *
344  *  The graph topology will have the following properties: all hosts, links and routers of the platform file are mapped
345  *  to graph nodes; routes are mapped to edges.
346  *  The platform's AS are not represented in the output.
347  *
348  *  \param filename The name of the file that will hold the graph.
349  *
350  *  \return 1 of successful, 0 otherwise.
351  */
352 int TRACE_platform_graph_export_graphviz (const char *filename)
353 {
354   /* returns 1 if successful, 0 otherwise */
355   if (!TRACE_is_enabled()) return 0;
356   xbt_graph_t g = instr_routing_platform_graph();
357   if (g == NULL) return 0;
358   instr_routing_platform_graph_export_graphviz (g, filename);
359   xbt_graph_free_graph(g, xbt_free_f, xbt_free_f, NULL);
360   return 1;
361 }
362
363 /*
364  * Derived functions that use instr_user_variable and TRACE_user_srcdst_variable. They were previously defined as
365  * pre-processors directives, but were transformed into functions so the user can track them using gdb.
366  */
367
368 /* for VM variables */
369 /** \ingroup TRACE_user_variables
370  *  \brief Declare a new user variable associated to VMs.
371  *
372  *  Declare a user variable that will be associated to VMs. A user vm variable can be used to trace user variables
373  *  such as the number of tasks in a VM, the number of clients in an application (for VMs), and so on. The color
374  *  associated to this new variable will be random.
375  *
376  *  \param variable The name of the new variable to be declared.
377  *
378  *  \see TRACE_vm_variable_declare_with_color
379  */
380 void TRACE_vm_variable_declare (const char *variable)
381 {
382   instr_user_variable(0, NULL, variable, "MSG_VM", 0, INSTR_US_DECLARE, NULL, user_vm_variables);
383 }
384
385 /** \ingroup TRACE_user_variables
386  *  \brief Declare a new user variable associated to VMs with a color.
387  *
388  *  Same as #TRACE_vm_variable_declare, but associated a color to the newly created user host variable. The color needs
389  *  to be a string with three numbers separated by spaces in the range [0,1].
390  *  A light-gray color can be specified using "0.7 0.7 0.7" as color.
391  *
392  *  \param variable The name of the new variable to be declared.
393  *  \param color The color for the new variable.
394  */
395 void TRACE_vm_variable_declare_with_color (const char *variable, const char *color)
396 {
397    instr_user_variable(0, NULL, variable, "MSG_VM", 0, INSTR_US_DECLARE, color, user_vm_variables);
398 }
399
400 /** \ingroup TRACE_user_variables
401  *  \brief Set the value of a variable of a host.
402  *
403  *  \param vm The name of the VM to be considered.
404  *  \param variable The name of the variable to be considered.
405  *  \param value The new value of the variable.
406  *
407  *  \see TRACE_vm_variable_declare, TRACE_vm_variable_add, TRACE_vm_variable_sub
408  */
409 void TRACE_vm_variable_set (const char *vm, const char *variable, double value)
410 {
411   TRACE_vm_variable_set_with_time (MSG_get_clock(), vm, variable, value);
412 }
413
414 /** \ingroup TRACE_user_variables
415  *  \brief Add a value to a variable of a VM.
416  *
417  *  \param vm The name of the VM to be considered.
418  *  \param variable The name of the variable to be considered.
419  *  \param value The value to be added to the variable.
420  *
421  *  \see TRACE_vm_variable_declare, TRACE_vm_variable_set, TRACE_vm_variable_sub
422  */
423 void TRACE_vm_variable_add (const char *vm, const char *variable, double value)
424 {
425   TRACE_vm_variable_add_with_time (MSG_get_clock(), vm, variable, value);
426 }
427
428 /** \ingroup TRACE_user_variables
429  *  \brief Subtract a value from a variable of a VM.
430  *
431  *  \param vm The name of the vm to be considered.
432  *  \param variable The name of the variable to be considered.
433  *  \param value The value to be subtracted from the variable.
434  *
435  *  \see TRACE_vm_variable_declare, TRACE_vm_variable_set, TRACE_vm_variable_add
436  */
437 void TRACE_vm_variable_sub (const char *vm, const char *variable, double value)
438 {
439   TRACE_vm_variable_sub_with_time (MSG_get_clock(), vm, variable, value);
440 }
441
442 /** \ingroup TRACE_user_variables
443  *  \brief Set the value of a variable of a VM at a given timestamp.
444  *
445  *  Same as #TRACE_vm_variable_set, but let user specify  the time used to trace it. Users can specify a time that
446  *  is not the simulated clock time as defined by the core  simulator. This allows a fine-grain control of time
447  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
448  *  also traced.
449  *
450  *  \param time The timestamp to be used to tag this change of value.
451  *  \param vm The name of the VM to be considered.
452  *  \param variable The name of the variable to be considered.
453  *  \param value The new value of the variable.
454  *
455  *  \see TRACE_vm_variable_declare, TRACE_vm_variable_add_with_time, TRACE_vm_variable_sub_with_time
456  */
457 void TRACE_vm_variable_set_with_time (double time, const char *vm, const char *variable, double value)
458 {
459   instr_user_variable(time, vm, variable, "MSG_VM", value, INSTR_US_SET, NULL, user_vm_variables);
460 }
461
462 /** \ingroup TRACE_user_variables
463  *  \brief Add a value to a variable of a VM at a given timestamp.
464  *
465  *  Same as #TRACE_vm_variable_add, but let user specify the time used to trace it. Users can specify a time that
466  *  is not the simulated clock time as defined by the core simulator. This allows a fine-grain control of time
467  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
468  *  also traced.
469  *
470  *  \param time The timestamp to be used to tag this change of value.
471  *  \param vm The name of the VM to be considered.
472  *  \param variable The name of the variable to be considered.
473  *  \param value The value to be added to the variable.
474  *
475  *  \see TRACE_vm_variable_declare, TRACE_vm_variable_set_with_time, TRACE_vm_variable_sub_with_time
476  */
477 void TRACE_vm_variable_add_with_time (double time, const char *vm, const char *variable, double value)
478 {
479   instr_user_variable(time, vm, variable, "MSG_VM", value, INSTR_US_ADD, NULL, user_vm_variables);
480 }
481
482 /** \ingroup TRACE_user_variables
483  *  \brief Subtract a value from a variable of a VM at a given timestamp.
484  *
485  *  Same as #TRACE_vm_variable_sub, but let user specify the time used to trace it. Users can specify a time that
486  *  is not the simulated clock time as defined by the core  simulator. This allows a fine-grain control of time
487  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
488  *  also traced.
489  *
490  *  \param time The timestamp to be used to tag this change of value.
491  *  \param vm The name of the VM to be considered.
492  *  \param variable The name of the variable to be considered.
493  *  \param value The value to be subtracted from the variable.
494  *
495  *  \see TRACE_vm_variable_declare, TRACE_vm_variable_set_with_time, TRACE_vm_variable_add_with_time
496  */
497 void TRACE_vm_variable_sub_with_time (double time, const char *vm, const char *variable, double value)
498 {
499   instr_user_variable(time, vm, variable, "MSG_VM", value, INSTR_US_SUB, NULL, user_vm_variables);
500 }
501
502 /** \ingroup TRACE_user_variables
503  *  \brief Get declared user vm variables
504  *
505  * This function should be used to get VM variables that were already declared with #TRACE_vm_variable_declare or with
506  * #TRACE_vm_variable_declare_with_color.
507  *
508  * \return A dynar with the declared host variables, must be freed with xbt_dynar_free.
509  */
510 xbt_dynar_t TRACE_get_vm_variables (void)
511 {
512   return instr_dict_to_dynar (user_vm_variables);
513 }
514
515 /* for host variables */
516 /** \ingroup TRACE_user_variables
517  *  \brief Declare a new user variable associated to hosts.
518  *
519  *  Declare a user variable that will be associated to hosts.
520  *  A user host variable can be used to trace user variables such as the number of tasks in a server, the number of
521  *  clients in an application (for hosts), and so on. The color associated to this new variable will be random.
522  *
523  *  \param variable The name of the new variable to be declared.
524  *
525  *  \see TRACE_host_variable_declare_with_color
526  */
527 void TRACE_host_variable_declare (const char *variable)
528 {
529   instr_user_variable(0, NULL, variable, "HOST", 0, INSTR_US_DECLARE, NULL, user_host_variables);
530 }
531
532 /** \ingroup TRACE_user_variables
533  *  \brief Declare a new user variable associated to hosts with a color.
534  *
535  *  Same as #TRACE_host_variable_declare, but associated a color to the newly created user host variable. The color
536  *  needs to be a string with three numbers separated by spaces in the range [0,1].
537  *  A light-gray color can be specified using "0.7 0.7 0.7" as color.
538  *
539  *  \param variable The name of the new variable to be declared.
540  *  \param color The color for the new variable.
541  */
542 void TRACE_host_variable_declare_with_color (const char *variable, const char *color)
543 {
544   instr_user_variable(0, NULL, variable, "HOST", 0, INSTR_US_DECLARE, color, user_host_variables);
545 }
546
547 /** \ingroup TRACE_user_variables
548  *  \brief Set the value of a variable of a host.
549  *
550  *  \param host The name of the host to be considered.
551  *  \param variable The name of the variable to be considered.
552  *  \param value The new value of the variable.
553  *
554  *  \see TRACE_host_variable_declare, TRACE_host_variable_add, TRACE_host_variable_sub
555  */
556 void TRACE_host_variable_set (const char *host, const char *variable, double value)
557 {
558   TRACE_host_variable_set_with_time (MSG_get_clock(), host, variable, value);
559 }
560
561 /** \ingroup TRACE_user_variables
562  *  \brief Add a value to a variable of a host.
563  *
564  *  \param host The name of the host to be considered.
565  *  \param variable The name of the variable to be considered.
566  *  \param value The value to be added to the variable.
567  *
568  *  \see TRACE_host_variable_declare, TRACE_host_variable_set, TRACE_host_variable_sub
569  */
570 void TRACE_host_variable_add (const char *host, const char *variable, double value)
571 {
572   TRACE_host_variable_add_with_time (MSG_get_clock(), host, variable, value);
573 }
574
575 /** \ingroup TRACE_user_variables
576  *  \brief Subtract a value from a variable of a host.
577  *
578  *  \param host The name of the host to be considered.
579  *  \param variable The name of the variable to be considered.
580  *  \param value The value to be subtracted from the variable.
581  *
582  *  \see TRACE_host_variable_declare, TRACE_host_variable_set, TRACE_host_variable_add
583  */
584 void TRACE_host_variable_sub (const char *host, const char *variable, double value)
585 {
586   TRACE_host_variable_sub_with_time (MSG_get_clock(), host, variable, value);
587 }
588
589 /** \ingroup TRACE_user_variables
590  *  \brief Set the value of a variable of a host at a given timestamp.
591  *
592  *  Same as #TRACE_host_variable_set, but let user specify  the time used to trace it. Users can specify a time that
593  *  is not the simulated clock time as defined by the core  simulator. This allows a fine-grain control of time
594  *  definition, but should be used with caution since the trace  can be inconsistent if resource utilization traces are
595  *  also traced.
596  *
597  *  \param time The timestamp to be used to tag this change of value.
598  *  \param host The name of the host to be considered.
599  *  \param variable The name of the variable to be considered.
600  *  \param value The new value of the variable.
601  *
602  *  \see TRACE_host_variable_declare, TRACE_host_variable_add_with_time, TRACE_host_variable_sub_with_time
603  */
604 void TRACE_host_variable_set_with_time (double time, const char *host, const char *variable, double value)
605 {
606   instr_user_variable(time, host, variable, "HOST", value, INSTR_US_SET, NULL, user_host_variables);
607 }
608
609 /** \ingroup TRACE_user_variables
610  *  \brief Add a value to a variable of a host at a given timestamp.
611  *
612  *  Same as #TRACE_host_variable_add, but let user specify the time used to trace it. Users can specify a time that
613  *  is not the simulated clock time as defined by the core  simulator. This allows a fine-grain control of time
614  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
615  *  also traced.
616  *
617  *  \param time The timestamp to be used to tag this change of value.
618  *  \param host The name of the host to be considered.
619  *  \param variable The name of the variable to be considered.
620  *  \param value The value to be added to the variable.
621  *
622  *  \see TRACE_host_variable_declare, TRACE_host_variable_set_with_time, TRACE_host_variable_sub_with_time
623  */
624 void TRACE_host_variable_add_with_time (double time, const char *host, const char *variable, double value)
625 {
626   instr_user_variable(time, host, variable, "HOST", value, INSTR_US_ADD, NULL, user_host_variables);
627 }
628
629 /** \ingroup TRACE_user_variables
630  *  \brief Subtract a value from a variable of a host at a given timestamp.
631  *
632  *  Same as #TRACE_host_variable_sub, but let user specify the time used to trace it. Users can specify a time that
633  *  is not the simulated clock time as defined by the core  simulator. This allows a fine-grain control of time
634  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
635  *  also traced.
636  *
637  *  \param time The timestamp to be used to tag this change of value.
638  *  \param host The name of the host to be considered.
639  *  \param variable The name of the variable to be considered.
640  *  \param value The value to be subtracted from the variable.
641  *
642  *  \see TRACE_host_variable_declare, TRACE_host_variable_set_with_time, TRACE_host_variable_add_with_time
643  */
644 void TRACE_host_variable_sub_with_time (double time, const char *host, const char *variable, double value)
645 {
646   instr_user_variable(time, host, variable, "HOST", value, INSTR_US_SUB, NULL, user_host_variables);
647 }
648
649 /** \ingroup TRACE_user_variables
650  *  \brief Get declared user host variables
651  *
652  * This function should be used to get host variables that were already declared with #TRACE_host_variable_declare or
653  * with #TRACE_host_variable_declare_with_color.
654  *
655  * \return A dynar with the declared host variables, must be freed with xbt_dynar_free.
656  */
657 xbt_dynar_t TRACE_get_host_variables (void)
658 {
659   return instr_dict_to_dynar (user_host_variables);
660 }
661
662 /* for link variables */
663 /** \ingroup TRACE_user_variables
664  *  \brief Declare a new user variable associated to links.
665  *
666  *  Declare a user variable that will be associated to links.
667  *  A user link variable can be used, for example, to trace user variables such as the number of messages being
668  *  transferred through network links. The color associated to this new variable will be random.
669  *
670  *  \param variable The name of the new variable to be declared.
671  *
672  *  \see TRACE_link_variable_declare_with_color
673  */
674 void TRACE_link_variable_declare (const char *variable)
675 {
676   instr_user_variable (0, NULL, variable, "LINK", 0, INSTR_US_DECLARE, NULL, user_link_variables);
677 }
678
679 /** \ingroup TRACE_user_variables
680  *  \brief Declare a new user variable associated to links with a color.
681  *
682  *  Same as #TRACE_link_variable_declare, but associated a color to the newly created user link variable. The color
683  *  needs to be a string with three numbers separated by spaces in the range [0,1].
684  *  A light-gray color can be specified using "0.7 0.7 0.7" as color.
685  *
686  *  \param variable The name of the new variable to be declared.
687  *  \param color The color for the new variable.
688  */
689 void TRACE_link_variable_declare_with_color (const char *variable, const char *color)
690 {
691   instr_user_variable (0, NULL, variable, "LINK", 0, INSTR_US_DECLARE, color, user_link_variables);
692 }
693
694 /** \ingroup TRACE_user_variables
695  *  \brief Set the value of a variable of a link.
696  *
697  *  \param link The name of the link to be considered.
698  *  \param variable The name of the variable to be considered.
699  *  \param value The new value of the variable.
700  *
701  *  \see TRACE_link_variable_declare, TRACE_link_variable_add, TRACE_link_variable_sub
702  */
703 void TRACE_link_variable_set (const char *link, const char *variable, double value)
704 {
705   TRACE_link_variable_set_with_time (MSG_get_clock(), link, variable, value);
706 }
707
708 /** \ingroup TRACE_user_variables
709  *  \brief Add a value to a variable of a link.
710  *
711  *  \param link The name of the link to be considered.
712  *  \param variable The name of the variable to be considered.
713  *  \param value The value to be added to the variable.
714  *
715  *  \see TRACE_link_variable_declare, TRACE_link_variable_set, TRACE_link_variable_sub
716  */
717 void TRACE_link_variable_add (const char *link, const char *variable, double value)
718 {
719   TRACE_link_variable_add_with_time (MSG_get_clock(), link, variable, value);
720 }
721
722 /** \ingroup TRACE_user_variables
723  *  \brief Subtract a value from a variable of a link.
724  *
725  *  \param link The name of the link to be considered.
726  *  \param variable The name of the variable to be considered.
727  *  \param value The value to be subtracted from the variable.
728  *
729  *  \see TRACE_link_variable_declare, TRACE_link_variable_set, TRACE_link_variable_add
730  */
731 void TRACE_link_variable_sub (const char *link, const char *variable, double value)
732 {
733   TRACE_link_variable_sub_with_time (MSG_get_clock(), link, variable, value);
734 }
735
736 /** \ingroup TRACE_user_variables
737  *  \brief Set the value of a variable of a link at a given timestamp.
738  *
739  *  Same as #TRACE_link_variable_set, but let user specify the time used to trace it. Users can specify a time that
740  *  is not the simulated clock time as defined by the core simulator. This allows a fine-grain control of time
741  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
742  *  also traced.
743  *
744  *  \param time The timestamp to be used to tag this change of value.
745  *  \param link The name of the link to be considered.
746  *  \param variable The name of the variable to be considered.
747  *  \param value The new value of the variable.
748  *
749  *  \see TRACE_link_variable_declare, TRACE_link_variable_add_with_time, TRACE_link_variable_sub_with_time
750  */
751 void TRACE_link_variable_set_with_time (double time, const char *link, const char *variable, double value)
752 {
753   instr_user_variable (time, link, variable, "LINK", value, INSTR_US_SET, NULL, user_link_variables);
754 }
755
756 /** \ingroup TRACE_user_variables
757  *  \brief Add a value to a variable of a link at a given timestamp.
758  *
759  *  Same as #TRACE_link_variable_add, but let user specify the time used to trace it. Users can specify a time that
760  *  is not the simulated clock time as defined by the core simulator. This allows a fine-grain control of time
761  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
762  *  also traced.
763  *
764  *  \param time The timestamp to be used to tag this change of value.
765  *  \param link The name of the link to be considered.
766  *  \param variable The name of the variable to be considered.
767  *  \param value The value to be added to the variable.
768  *
769  *  \see TRACE_link_variable_declare, TRACE_link_variable_set_with_time, TRACE_link_variable_sub_with_time
770  */
771 void TRACE_link_variable_add_with_time (double time, const char *link, const char *variable, double value)
772 {
773   instr_user_variable (time, link, variable, "LINK", value, INSTR_US_ADD, NULL, user_link_variables);
774 }
775
776 /** \ingroup TRACE_user_variables
777  *  \brief Subtract a value from a variable of a link at a given timestamp.
778  *
779  *  Same as #TRACE_link_variable_sub, but let user specify the time used to trace it. Users can specify a time that
780  *  is not the simulated clock time as defined by the core simulator. This allows a fine-grain control of time
781  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
782  *  also traced.
783  *
784  *  \param time The timestamp to be used to tag this change of value.
785  *  \param link The name of the link to be considered.
786  *  \param variable The name of the variable to be considered.
787  *  \param value The value to be subtracted from the variable.
788  *
789  *  \see TRACE_link_variable_declare, TRACE_link_variable_set_with_time, TRACE_link_variable_add_with_time
790  */
791 void TRACE_link_variable_sub_with_time (double time, const char *link, const char *variable, double value)
792 {
793   instr_user_variable (time, link, variable, "LINK", value, INSTR_US_SUB, NULL, user_link_variables);
794 }
795
796 /* for link variables, but with src and dst used for get_route */
797 /** \ingroup TRACE_user_variables
798  *  \brief Set the value of the variable present in the links connecting source and destination.
799  *
800  *  Same as #TRACE_link_variable_set, but instead of providing the name of link to be considered, provide the source
801  *  and destination hosts. All links that are part of the route between source and destination will have the variable
802  *  set to the provided value.
803  *
804  *  \param src The name of the source host for get route.
805  *  \param dst The name of the destination host for get route.
806  *  \param variable The name of the variable to be considered.
807  *  \param value The new value of the variable.
808  *
809  *  \see TRACE_link_variable_declare, TRACE_link_srcdst_variable_add, TRACE_link_srcdst_variable_sub
810  */
811 void TRACE_link_srcdst_variable_set (const char *src, const char *dst, const char *variable, double value)
812 {
813   TRACE_link_srcdst_variable_set_with_time (MSG_get_clock(), src, dst, variable, value);
814 }
815
816 /** \ingroup TRACE_user_variables
817  *  \brief Add a value to the variable present in the links connecting source and destination.
818  *
819  *  Same as #TRACE_link_variable_add, but instead of providing the name of link to be considered, provide the source
820  *  and destination hosts. All links that are part of the route between source and destination will have the value
821  *  passed as parameter added to the current value of the variable name to be considered.
822  *
823  *  \param src The name of the source host for get route.
824  *  \param dst The name of the destination host for get route.
825  *  \param variable The name of the variable to be considered.
826  *  \param value The value to be added to the variable.
827  *
828  *  \see TRACE_link_variable_declare, TRACE_link_srcdst_variable_set, TRACE_link_srcdst_variable_sub
829  */
830 void TRACE_link_srcdst_variable_add (const char *src, const char *dst, const char *variable, double value)
831 {
832   TRACE_link_srcdst_variable_add_with_time (MSG_get_clock(), src, dst, variable, value);
833 }
834
835 /** \ingroup TRACE_user_variables
836  *  \brief Subtract a value from the variable present in the links connecting source and destination.
837  *
838  *  Same as #TRACE_link_variable_sub, but instead of providing the name of link to be considered, provide the source
839  *  and destination hosts. All links that are part of the route between source and destination will have the value
840  *  passed as parameter subtracted from the current value of the variable name to be considered.
841  *
842  *  \param src The name of the source host for get route.
843  *  \param dst The name of the destination host for get route.
844  *  \param variable The name of the variable to be considered.
845  *  \param value The value to be subtracted from the variable.
846  *
847  *  \see TRACE_link_variable_declare, TRACE_link_srcdst_variable_set, TRACE_link_srcdst_variable_add
848  */
849 void TRACE_link_srcdst_variable_sub (const char *src, const char *dst, const char *variable, double value)
850 {
851   TRACE_link_srcdst_variable_sub_with_time (MSG_get_clock(), src, dst, variable, value);
852 }
853
854 /** \ingroup TRACE_user_variables
855  *  \brief Set the value of the variable present in the links connecting source and destination at a given timestamp.
856  *
857  *  Same as #TRACE_link_srcdst_variable_set, but let user specify the time used to trace it. Users can specify a time
858  *  that is not the simulated clock time as defined by the core simulator. This allows a fine-grain control of time
859  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
860  *  also traced.
861  *
862  *  \param time The timestamp to be used to tag this change of value.
863  *  \param src The name of the source host for get route.
864  *  \param dst The name of the destination host for get route.
865  *  \param variable The name of the variable to be considered.
866  *  \param value The new value of the variable.
867  *
868  *  \see TRACE_link_variable_declare, TRACE_link_srcdst_variable_add_with_time, TRACE_link_srcdst_variable_sub_with_time
869  */
870 void TRACE_link_srcdst_variable_set_with_time (double time, const char *src, const char *dst, const char *variable,
871                                                double value)
872 {
873   instr_user_srcdst_variable (time, src, dst, variable, "LINK", value, INSTR_US_SET);
874 }
875
876 /** \ingroup TRACE_user_variables
877  *  \brief Add a value to the variable present in the links connecting source and destination at a given timestamp.
878  *
879  *  Same as #TRACE_link_srcdst_variable_add, but let user specify the time used to trace it. Users can specify a time
880  *  that is not the simulated clock time as defined by the core simulator. This allows a fine-grain control of time
881  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
882  *  also traced.
883  *
884  *  \param time The timestamp to be used to tag this change of value.
885  *  \param src The name of the source host for get route.
886  *  \param dst The name of the destination host for get route.
887  *  \param variable The name of the variable to be considered.
888  *  \param value The value to be added to the variable.
889  *
890  *  \see TRACE_link_variable_declare, TRACE_link_srcdst_variable_set_with_time, TRACE_link_srcdst_variable_sub_with_time
891  */
892 void TRACE_link_srcdst_variable_add_with_time (double time, const char *src, const char *dst, const char *variable,
893                                                double value)
894 {
895   instr_user_srcdst_variable (time, src, dst, variable, "LINK", value, INSTR_US_ADD);
896 }
897
898 /** \ingroup TRACE_user_variables
899  *  \brief Subtract a value from the variable present in the links connecting source and dest. at a given timestamp.
900  *
901  *  Same as #TRACE_link_srcdst_variable_sub, but let user specify the time used to trace it. Users can specify a time
902  *  that is not the simulated clock time as defined by the core simulator. This allows a fine-grain control of time
903  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
904  *  also traced.
905  *
906  *  \param time The timestamp to be used to tag this change of value.
907  *  \param src The name of the source host for get route.
908  *  \param dst The name of the destination host for get route.
909  *  \param variable The name of the variable to be considered.
910  *  \param value The value to be subtracted from the variable.
911  *
912  *  \see TRACE_link_variable_declare, TRACE_link_srcdst_variable_set_with_time, TRACE_link_srcdst_variable_add_with_time
913  */
914 void TRACE_link_srcdst_variable_sub_with_time (double time, const char *src, const char *dst, const char *variable,
915                                                double value)
916 {
917   instr_user_srcdst_variable (time, src, dst, variable, "LINK", value, INSTR_US_SUB);
918 }
919
920 /** \ingroup TRACE_user_variables
921  *  \brief Get declared user link variables
922  *
923  * This function should be used to get link variables that were already declared with #TRACE_link_variable_declare or
924  * with #TRACE_link_variable_declare_with_color.
925  *
926  * \return A dynar with the declared link variables, must be freed with xbt_dynar_free.
927  */
928 xbt_dynar_t TRACE_get_link_variables (void)
929 {
930   return instr_dict_to_dynar (user_link_variables);
931 }
932
933 /** \ingroup TRACE_user_variables
934  *  \brief Declare a new user state associated to hosts.
935  *
936  *  Declare a user state that will be associated to hosts.
937  *  A user host state can be used to trace application states.
938  *
939  *  \param state The name of the new state to be declared.
940  *
941  *  \see TRACE_host_state_declare_value
942  */
943 void TRACE_host_state_declare (const char *state)
944 {
945   instr_new_user_state_type("HOST", state);
946 }
947
948 /** \ingroup TRACE_user_variables
949  *  \brief Declare a new value for a user state associated to hosts.
950  *
951  *  Declare a value for a state. The color needs to be a string with 3 numbers separated by spaces in the range [0,1].
952  *  A light-gray color can be specified using "0.7 0.7 0.7" as color.
953  *
954  *  \param state The name of the new state to be declared.
955  *  \param value The name of the value
956  *  \param color The color of the value
957  *
958  *  \see TRACE_host_state_declare
959  */
960 void TRACE_host_state_declare_value (const char *state, const char *value, const char *color)
961 {
962   instr_new_value_for_user_state_type (state, value, color);
963 }
964
965 /** \ingroup TRACE_user_variables
966  *  \brief Set the user state to the given value.
967  *
968  *  Change a user state previously declared to the given value.
969  *
970  *  \param host The name of the host to be considered.
971  *  \param state The name of the state previously declared.
972  *  \param value The new value of the state.
973  *
974  *  \see TRACE_host_state_declare, TRACE_host_push_state, TRACE_host_pop_state, TRACE_host_reset_state
975  */
976 void TRACE_host_set_state (const char *host, const char *state, const char *value)
977 {
978   container_t container = PJ_container_get(host);
979   type_t type = PJ_type_get (state, container->type);
980   val_t val = PJ_value_get_or_new (value, NULL, type); /* if user didn't declare a value with a color, use NULL color */
981   new_pajeSetState(MSG_get_clock(), container, type, val);
982 }
983
984 /** \ingroup TRACE_user_variables
985  *  \brief Push a new value for a state of a given host.
986  *
987  *  Change a user state previously declared by pushing the new value to the state.
988  *
989  *  \param host The name of the host to be considered.
990  *  \param state The name of the state previously declared.
991  *  \param value The value to be pushed.
992  *
993  *  \see TRACE_host_state_declare, TRACE_host_set_state, TRACE_host_pop_state, TRACE_host_reset_state
994  */
995 void TRACE_host_push_state (const char *host, const char *state, const char *value)
996 {
997   container_t container = PJ_container_get(host);
998   type_t type = PJ_type_get (state, container->type);
999   val_t val = PJ_value_get_or_new (value, NULL, type); /* if user didn't declare a value with a color, use NULL color */
1000   new_pajePushState(MSG_get_clock(), container, type, val);
1001 }
1002
1003 /** \ingroup TRACE_user_variables
1004  *  \brief Pop the last value of a state of a given host.
1005  *
1006  *  Change a user state previously declared by removing the last value of the state.
1007  *
1008  *  \param host The name of the host to be considered.
1009  *  \param state The name of the state to be popped.
1010  *
1011  *  \see TRACE_host_state_declare, TRACE_host_set_state, TRACE_host_push_state, TRACE_host_reset_state
1012  */
1013 void TRACE_host_pop_state (const char *host, const char *state)
1014 {
1015   container_t container = PJ_container_get(host);
1016   type_t type = PJ_type_get (state, container->type);
1017   new_pajePopState(MSG_get_clock(), container, type);
1018 }
1019
1020 /** \ingroup TRACE_user_variables
1021  *  \brief Reset the state of a given host.
1022  *
1023  *  Clear all previous values of a user state.
1024  *
1025  *  \param host The name of the host to be considered.
1026  *  \param state The name of the state to be cleared.
1027  *
1028  *  \see TRACE_host_state_declare, TRACE_host_set_state, TRACE_host_push_state, TRACE_host_pop_state
1029  */
1030 void TRACE_host_reset_state (const char *host, const char *state)
1031 {
1032   container_t container = PJ_container_get(host);
1033   type_t type = PJ_type_get (state, container->type);
1034   new_pajeResetState(MSG_get_clock(), container, type);
1035 }
1036
1037 /** \ingroup TRACE_API
1038  *  \brief Get Paje container types that can be mapped to the nodes of a graph.
1039  *
1040  *  This function can be used to create a user made  graph configuration file for Triva. Normally, it is used with the
1041  *  functions defined in \ref TRACE_user_variables.
1042  *
1043  *  \return A dynar with the types, must be freed with xbt_dynar_free.
1044  */
1045 xbt_dynar_t TRACE_get_node_types (void)
1046 {
1047   return instr_dict_to_dynar (trivaNodeTypes);
1048 }
1049
1050 /** \ingroup TRACE_API
1051  *  \brief Get Paje container types that can be mapped to the edges of a graph.
1052  *
1053  *  This function can be used to create a user made graph configuration file for Triva. Normally, it is used with the
1054  *  functions defined in \ref TRACE_user_variables.
1055  *
1056  *  \return A dynar with the types, must be freed with xbt_dynar_free.
1057  */
1058 xbt_dynar_t TRACE_get_edge_types (void)
1059 {
1060   return instr_dict_to_dynar (trivaEdgeTypes);
1061 }
1062
1063 /** \ingroup TRACE_API
1064  *  \brief Pauses all tracing activities.
1065  *  \see TRACE_resume
1066  */
1067 void TRACE_pause (void)
1068 {
1069   instr_pause_tracing();
1070 }
1071
1072 /** \ingroup TRACE_API
1073  *  \brief Resumes all tracing activities.
1074  *  \see TRACE_pause
1075  */
1076 void TRACE_resume (void)
1077 {
1078   instr_resume_tracing();
1079 }