Logo AND Algorithmique Numérique Distribuée

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