Logo AND Algorithmique Numérique Distribuée

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