Logo AND Algorithmique Numérique Distribuée

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