Logo AND Algorithmique Numérique Distribuée

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