Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
simplify access to netponts
[simgrid.git] / src / instr / instr_interface.cpp
1 /* Copyright (c) 2010-2022. 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 <simgrid/s4u/Host.hpp>
9 #include <simgrid/s4u/VirtualMachine.hpp>
10 #include <xbt/random.hpp>
11
12 #include "src/instr/instr_private.hpp"
13 #include "src/kernel/resource/StandardLinkImpl.hpp"
14 #include <algorithm>
15 #include <cmath>
16
17 enum class InstrUserVariable { DECLARE, SET, ADD, SUB };
18
19 XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_api, instr, "API");
20
21 std::set<std::string, std::less<>> created_categories;
22 std::set<std::string, std::less<>> declared_marks;
23 std::set<std::string, std::less<>> user_host_variables;
24 std::set<std::string, std::less<>> user_vm_variables;
25 std::set<std::string, std::less<>> user_link_variables;
26
27 static void instr_user_variable(double time, const char* resource, const std::string& variable_name,
28                                 const std::string& parent_type, double value, InstrUserVariable what,
29                                 const std::string& color, std::set<std::string, std::less<>>* filter)
30 {
31   /* safe switches. tracing has to be activated and if platform is not traced, we don't allow user variables */
32   if (not TRACE_is_enabled() || not TRACE_needs_platform())
33     return;
34
35   // check if variable is already declared
36   auto created = filter->find(variable_name);
37   if (what == InstrUserVariable::DECLARE) {
38     if (created == filter->end()) { // not declared yet
39       filter->insert(variable_name);
40       instr_new_user_variable_type(parent_type, variable_name, color);
41     }
42   } else {
43     if (created != filter->end()) { // declared, let's work
44       simgrid::instr::VariableType* variable =
45           simgrid::instr::Container::by_name(resource)->get_variable(variable_name);
46       switch (what) {
47         case InstrUserVariable::SET:
48           variable->set_event(time, value);
49           break;
50         case InstrUserVariable::ADD:
51           variable->add_event(time, value);
52           break;
53         case InstrUserVariable::SUB:
54           variable->sub_event(time, value);
55           break;
56         default:
57           THROW_IMPOSSIBLE;
58       }
59     }
60   }
61 }
62
63 static void instr_user_srcdst_variable(double time, const char* src, const char* dst, const std::string& variable,
64                                        const std::string& parent_type, double value, InstrUserVariable what)
65 {
66   const auto* src_elm = sg_netpoint_by_name_or_null(src);
67   xbt_assert(src_elm, "Element '%s' not found!", src);
68
69   const auto* dst_elm = sg_netpoint_by_name_or_null(dst);
70   xbt_assert(dst_elm, "Element '%s' not found!", dst);
71
72   std::vector<simgrid::kernel::resource::StandardLinkImpl*> route;
73   simgrid::kernel::routing::NetZoneImpl::get_global_route(src_elm, dst_elm, route, nullptr);
74   for (auto const& link : route)
75     instr_user_variable(time, link->get_cname(), variable, parent_type, value, what, "", &user_link_variables);
76 }
77
78 namespace simgrid {
79 namespace instr {
80 static void user_srcdst_variable(double time, const s4u::Host* src, const s4u::Host* dst, const std::string& variable,
81                                  double value, InstrUserVariable what)
82 {
83   const auto* src_elm = src->get_netpoint();
84   xbt_assert(src_elm, "Element '%s' not found!", src->get_cname());
85
86   const auto* dst_elm = dst->get_netpoint();
87   xbt_assert(dst_elm, "Element '%s' not found!", dst->get_cname());
88
89   std::vector<kernel::resource::StandardLinkImpl*> route;
90   kernel::routing::NetZoneImpl::get_global_route(src_elm, dst_elm, route, nullptr);
91   for (auto const& link : route)
92     instr_user_variable(time, link->get_cname(), variable, "LINK", value, what, "", &user_link_variables);
93 }
94
95 /** @brief Declare a new user variable associated to hosts.
96  *
97  *  Declare a user variable that will be associated to hosts.
98  *  A user host variable can be used to trace user variables such as the number of tasks in a server, the number of
99  *  clients in an application (for hosts), and so on. The color associated to this new variable will be random if
100  *  not given as parameter.
101  */
102 void declare_host_variable(const std::string& variable, const std::string& color)
103 {
104   instr_user_variable(0, nullptr, variable, "HOST", 0, InstrUserVariable::DECLARE, color, &user_host_variables);
105 }
106
107 void set_host_variable(const s4u::Host* host, const std::string& variable, double value, double time)
108 {
109   instr_user_variable(time, host->get_cname(), variable, "HOST", value, InstrUserVariable::SET, "",
110                       &user_host_variables);
111 }
112
113 /** @brief Add a value to a variable of a host */
114 void add_host_variable(const s4u::Host* host, const std::string& variable, double value, double time)
115 {
116   instr_user_variable(time, host->get_cname(), variable, "HOST", value, InstrUserVariable::ADD, "",
117                       &user_host_variables);
118 }
119
120 /** @brief Subtract a value to a variable of a host */
121 void sub_host_variable(const s4u::Host* host, const std::string& variable, double value, double time)
122 {
123   instr_user_variable(time, host->get_cname(), variable, "HOST", value, InstrUserVariable::SUB, "",
124                       &user_host_variables);
125 }
126
127 /** @brief Get host variables that were already declared with #declare_host_variable. */
128 const std::set<std::string, std::less<>>& get_host_variables()
129 {
130   return user_host_variables;
131 }
132
133 /** @brief Declare a new user variable associated to links.
134  *
135  *  Declare a user variable that will be associated to links.
136  *  A user link variable can be used, for example, to trace user variables such as the number of messages being
137  *  transferred through network links. The color associated to this new variable will be random if not given as
138  *  parameter.
139  */
140 void declare_link_variable(const std::string& variable, const std::string& color)
141 {
142   instr_user_variable(0, nullptr, variable, "LINK", 0, InstrUserVariable::DECLARE, color, &user_link_variables);
143 }
144
145 void set_link_variable(const s4u::Link* link, const std::string& variable, double value, double time)
146 {
147   instr_user_variable(time, link->get_cname(), variable, "LINK", value, InstrUserVariable::SET, "",
148                       &user_link_variables);
149 }
150
151 void set_link_variable(const s4u::Host* src, const s4u::Host* dst, const std::string& variable, double value,
152                        double time)
153 {
154   user_srcdst_variable(time, src, dst, variable, value, InstrUserVariable::SET);
155 }
156
157 /** @brief Add a value to a variable of a link */
158 void add_link_variable(const s4u::Link* link, const std::string& variable, double value, double time)
159 {
160   instr_user_variable(time, link->get_cname(), variable, "LINK", value, InstrUserVariable::ADD, "",
161                       &user_link_variables);
162 }
163
164 /** @brief Add a value to a variable of a link */
165 void add_link_variable(const s4u::Host* src, const s4u::Host* dst, const std::string& variable, double value,
166                        double time)
167 {
168   user_srcdst_variable(time, src, dst, variable, value, InstrUserVariable::ADD);
169 }
170
171 /** @brief Subtract a value to a variable of a link */
172 void sub_link_variable(const s4u::Link* link, const std::string& variable, double value, double time)
173 {
174   instr_user_variable(time, link->get_cname(), variable, "LINK", value, InstrUserVariable::SUB, "",
175                       &user_link_variables);
176 }
177
178 /** @brief Subtract a value to a variable of a link */
179 void sub_link_variable(const s4u::Host* src, const s4u::Host* dst, const std::string& variable, double value,
180                        double time)
181 {
182   user_srcdst_variable(time, src, dst, variable, value, InstrUserVariable::SUB);
183 }
184
185 /** @brief Get link variables that were already declared with #declare_link_variable. */
186 const std::set<std::string, std::less<>>& get_link_variables()
187 {
188   return user_link_variables;
189 }
190
191 /** @brief Declare a new user variable associated to VMs.
192  *
193  *  Declare a user variable that will be associated to VMs. A user host variable can be used to trace user variables
194  *  such as the number of tasks in a VM, the number of clients in an application (for hosts), and so on. The color
195  *  associated to this new variable will be random if not given as parameter.
196  */
197 void declare_vm_variable(const std::string& variable, const std::string& color)
198 {
199   instr_user_variable(0, nullptr, variable, "VM", 0, InstrUserVariable::DECLARE, color, &user_vm_variables);
200 }
201
202 void set_vm_variable(const s4u::VirtualMachine* vm, const std::string& variable, double value, double time)
203 {
204   instr_user_variable(time, vm->get_cname(), variable, "VM", value, InstrUserVariable::SET, "", &user_vm_variables);
205 }
206
207 /** @brief Add a value to a variable of a VM */
208 void add_vm_variable(const s4u::VirtualMachine* vm, const std::string& variable, double value, double time)
209 {
210   instr_user_variable(time, vm->get_cname(), variable, "HOST", value, InstrUserVariable::ADD, "", &user_vm_variables);
211 }
212
213 /** @brief Subtract a value from a variable of a VM */
214 void sub_vm_variable(const s4u::VirtualMachine* vm, const std::string& variable, double value, double time)
215 {
216   instr_user_variable(time, vm->get_cname(), variable, "HOST", value, InstrUserVariable::SUB, "", &user_vm_variables);
217 }
218
219 /** @brief Get VM variables that were already declared with #declare_vm_variable. */
220 const std::set<std::string, std::less<>>& get_vm_variables()
221 {
222   return user_vm_variables;
223 }
224
225 /**@brief Declare a new type for tracing mark.
226  *
227  * This function declares a new Paje event type in the trace file that can be used by simulators to declare
228  * application-level marks. This function is independent of which API is used in SimGrid.
229  */
230 void declare_mark(const std::string& mark_type)
231 {
232   /* safe switches. tracing has to be activated and if platform is not traced, we can't deal with marks */
233   if (not TRACE_is_enabled() || not TRACE_needs_platform())
234     return;
235
236   // check if mark_type is already declared
237   if (declared_marks.find(mark_type) != declared_marks.end()) {
238     throw TracingError(XBT_THROW_POINT,
239                        xbt::string_printf("mark_type with name (%s) is already declared", mark_type.c_str()));
240   }
241
242   XBT_DEBUG("MARK,declare %s", mark_type.c_str());
243   Container::get_root()->get_type()->by_name_or_create<EventType>(mark_type);
244   declared_marks.emplace(mark_type);
245 }
246
247 /** @brief Declare a new colored value for a previously declared mark type.
248  *
249  * This function declares a new colored value for a Paje event type in the trace file that can be used by simulators to
250  * declare application-level marks. This function is independent of which API is used in SimGrid. The color needs to be
251  * a string with three numbers separated by spaces in the range [0,1].
252  * A light-gray color can be specified using "0.7 0.7 0.7" as color. If no color is provided, the default color used
253  * will be white ("1 1 1").
254  */
255 void declare_mark_value(const std::string& mark_type, const std::string& mark_value, const std::string& mark_color)
256 {
257   /* safe switches. tracing has to be activated and if platform is not traced, we can't deal with marks */
258   if (not TRACE_is_enabled() || not TRACE_needs_platform())
259     return;
260
261   auto* type = static_cast<EventType*>(Container::get_root()->get_type()->by_name(mark_type));
262   if (not type) {
263     throw TracingError(XBT_THROW_POINT,
264                        xbt::string_printf("mark_type with name (%s) is not declared", mark_type.c_str()));
265   } else {
266     XBT_DEBUG("MARK, declare_value %s %s %s", mark_type.c_str(), mark_value.c_str(), mark_color.c_str());
267     type->add_entity_value(mark_value, mark_color);
268   }
269 }
270
271 /** @brief Create a new instance of a tracing mark type.
272  *
273  * This function creates a mark in the trace file. The first parameter had to be previously declared using
274  * #declare_mark, the second is the identifier for this mark instance. We recommend that the mark_value is a
275  * unique value for the whole simulation. Nevertheless, this is not a strong requirement: the trace will be valid even
276  * if there are multiple mark identifiers for the same trace.
277  */
278 void mark(const std::string& mark_type, const std::string& mark_value)
279 {
280   /* safe switches. tracing has to be activated and if platform is not traced, we can't deal with marks */
281   if (not TRACE_is_enabled() || not TRACE_needs_platform())
282     return;
283
284   // check if mark_type is already declared
285   auto* type = static_cast<EventType*>(Container::get_root()->get_type()->by_name(mark_type));
286   if (not type) {
287     throw TracingError(XBT_THROW_POINT,
288                        xbt::string_printf("mark_type with name (%s) is not declared", mark_type.c_str()));
289   } else {
290     XBT_DEBUG("MARK %s %s", mark_type.c_str(), mark_value.c_str());
291     new NewEvent(simgrid_get_clock(), Container::get_root(), type, type->get_entity_value(mark_value));
292   }
293 }
294
295 /** @brief Get marks that were already declared with #declare_mark. */
296 const std::set<std::string, std::less<>>& get_marks()
297 {
298   return declared_marks;
299 }
300
301 /** @brief Declare a new category.
302  *
303  *  This function should be used to define a user category. The category can be used to differentiate the tasks that
304  *  are created during the simulation (for example, tasks from server1, server2, or request tasks, computation tasks,
305  *  communication tasks). All resource utilization (host power and link bandwidth) will be classified according to the
306  *  task category. Tasks that do not belong to a category are not traced. The color for the category that is being
307  *  declared is random. This function has no effect if a category with the same name has been already declared.
308  *
309  * See @ref outcomes_vizu for details on how to trace the (categorized) resource utilization.
310  */
311 void declare_tracing_category(const std::string& name, const std::string& color)
312 {
313   /* safe switches. tracing has to be activated and if platform is not traced, we can't deal with categories */
314   if (not TRACE_is_enabled() || not TRACE_needs_platform() || not TRACE_categorized())
315     return;
316
317   // check if category is already created
318   if (created_categories.find(name) != created_categories.end())
319     return;
320
321   created_categories.emplace(name);
322
323   // define final_color
324   std::string final_color;
325   if (color.empty()) {
326     // generate a random color
327     double red   = simgrid::xbt::random::uniform_real(0.0, std::nextafter(1.0, 2.0));
328     double green = simgrid::xbt::random::uniform_real(0.0, std::nextafter(1.0, 2.0));
329     double blue  = simgrid::xbt::random::uniform_real(0.0, std::nextafter(1.0, 2.0));
330     final_color  = std::to_string(red) + " " + std::to_string(green) + " " + std::to_string(blue);
331   } else {
332     final_color = std::string(color);
333   }
334
335   XBT_DEBUG("CAT,declare %s, \"%s\" \"%s\"", name.c_str(), color.c_str(), final_color.c_str());
336
337   // define the type of this category on top of hosts and links
338   instr_new_variable_type(name, final_color);
339 }
340
341 /** @brief Get categories that were already declared with #declare_tracing_category.
342  *
343  * See @ref outcomes_vizu for details on how to trace the (categorized) resource utilization.
344  */
345 const std::set<std::string, std::less<>>& get_tracing_categories()
346 {
347   return created_categories;
348 }
349
350 } // namespace instr
351 } // namespace simgrid
352
353 static xbt_dynar_t instr_set_to_dynar(const std::set<std::string, std::less<>>& filter) // XBT_ATTRIB_DEPRECATED_v333
354 {
355   if (not TRACE_is_enabled() || not TRACE_needs_platform())
356     return nullptr;
357
358   xbt_dynar_t ret = xbt_dynar_new (sizeof(char*), &xbt_free_ref);
359   for (auto const& name : filter)
360     xbt_dynar_push_as(ret, char*, xbt_strdup(name.c_str()));
361
362   return ret;
363 }
364
365 void TRACE_category(const char* category) // XBT_ATTRIB_DEPRECATED_v333
366 {
367   simgrid::instr::declare_tracing_category(category);
368 }
369
370 void TRACE_category_with_color(const char* category, const char* color) // XBT_ATTRIB_DEPRECATED_v333
371 {
372   simgrid::instr::declare_tracing_category(category, color);
373 }
374
375 xbt_dynar_t TRACE_get_categories() // XBT_ATTRIB_DEPRECATED_v333
376 {
377   if (not TRACE_is_enabled() || not TRACE_categorized())
378     return nullptr;
379   return instr_set_to_dynar(created_categories);
380 }
381
382 void TRACE_declare_mark(const char* mark_type) // XBT_ATTRIB_DEPRECATED_v333
383 {
384   simgrid::instr::declare_mark(mark_type);
385 }
386
387 void TRACE_declare_mark_value_with_color(const char* mark_type, const char* mark_value,
388                                          const char* mark_color) // XBT_ATTRIB_DEPRECATED_v333
389 {
390   simgrid::instr::declare_mark_value(mark_type, mark_value, mark_color);
391 }
392
393 void TRACE_declare_mark_value(const char* mark_type, const char* mark_value) // XBT_ATTRIB_DEPRECATED_v333
394 {
395   simgrid::instr::declare_mark_value(mark_type, mark_value);
396 }
397
398 void TRACE_mark(const char* mark_type, const char* mark_value) // XBT_ATTRIB_DEPRECATED_v333
399 {
400   simgrid::instr::mark(mark_type, mark_value);
401 }
402
403 xbt_dynar_t TRACE_get_marks() // XBT_ATTRIB_DEPRECATED_v333
404 {
405   if (not TRACE_is_enabled())
406     return nullptr;
407
408   return instr_set_to_dynar(declared_marks);
409 }
410
411 int TRACE_platform_graph_export_graphviz(const char* filename) // XBT_ATTRIB_DEPRECATED_v333
412 {
413   simgrid::instr::platform_graph_export_graphviz(filename);
414   return 1;
415 }
416
417 /*
418  * Derived functions that use instr_user_variable and TRACE_user_srcdst_variable. They were previously defined as
419  * pre-processors directives, but were transformed into functions so the user can track them using gdb.
420  */
421
422 /* for VM variables */
423 void TRACE_vm_variable_declare(const char* variable) // XBT_ATTRIB_DEPRECATED_v333
424 {
425   instr_user_variable(0, nullptr, variable, "VM", 0, InstrUserVariable::DECLARE, "", &user_vm_variables);
426 }
427 void TRACE_vm_variable_declare_with_color(const char* variable, const char* color) // XBT_ATTRIB_DEPRECATED_v333
428 {
429   instr_user_variable(0, nullptr, variable, "VM", 0, InstrUserVariable::DECLARE, color, &user_vm_variables);
430 }
431
432 /** @ingroup TRACE_user_variables
433  *  @brief Set the value of a variable of a host.
434  *
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 new value of the variable.
438  *
439  *  @see TRACE_vm_variable_declare, TRACE_vm_variable_add, TRACE_vm_variable_sub
440  */
441 void TRACE_vm_variable_set (const char *vm, const char *variable, double value)
442 {
443   instr_user_variable(simgrid_get_clock(), vm, variable, "VM", value, InstrUserVariable::SET, "", &user_vm_variables);
444 }
445
446 void TRACE_vm_variable_add(const char* vm, const char* variable, double value) // XBT_ATTRIB_DEPRECATED_v333
447 {
448   instr_user_variable(simgrid_get_clock(), vm, variable, "VM", value, InstrUserVariable::ADD, "", &user_vm_variables);
449 }
450 void TRACE_vm_variable_sub(const char* vm, const char* variable, double value) // XBT_ATTRIB_DEPRECATED_v333
451 {
452   instr_user_variable(simgrid_get_clock(), vm, variable, "VM", value, InstrUserVariable::SUB, "", &user_vm_variables);
453 }
454
455 void TRACE_vm_variable_set_with_time(double time, const char* vm, const char* variable,
456                                      double value) // XBT_ATTRIB_DEPRECATED_v333
457 {
458   instr_user_variable(time, vm, variable, "VM", value, InstrUserVariable::SET, "", &user_vm_variables);
459 }
460
461 void TRACE_vm_variable_add_with_time(double time, const char* vm, const char* variable,
462                                      double value) // XBT_ATTRIB_DEPRECATED_v333
463 {
464   instr_user_variable(time, vm, variable, "VM", value, InstrUserVariable::ADD, "", &user_vm_variables);
465 }
466 void TRACE_vm_variable_sub_with_time(double time, const char* vm, const char* variable,
467                                      double value) // XBT_ATTRIB_DEPRECATED_v333
468 {
469   instr_user_variable(time, vm, variable, "VM", value, InstrUserVariable::SUB, "", &user_vm_variables);
470 }
471
472 /* for host variables */
473 void TRACE_host_variable_declare(const char* variable) // XBT_ATTRIB_DEPRECATED_v333
474 {
475   simgrid::instr::declare_host_variable(variable);
476 }
477
478 void TRACE_host_variable_declare_with_color(const char* variable, const char* color) // XBT_ATTRIB_DEPRECATED_v333
479 {
480   simgrid::instr::declare_host_variable(variable, color);
481 }
482
483 /** @ingroup TRACE_user_variables
484  *  @brief Set the value of a variable of a host.
485  *
486  *  @param host The name of the host to be considered.
487  *  @param variable The name of the variable to be considered.
488  *  @param value The new value of the variable.
489  *
490  *  @see TRACE_host_variable_declare, TRACE_host_variable_add, TRACE_host_variable_sub
491  */
492 void TRACE_host_variable_set (const char *host, const char *variable, double value)
493 {
494   instr_user_variable(simgrid_get_clock(), host, variable, "HOST", value, InstrUserVariable::SET, "",
495                       &user_host_variables);
496 }
497
498 void TRACE_host_variable_add(const char* host, const char* variable, double value) // XBT_ATTRIB_DEPRECATED_v333
499 {
500   instr_user_variable(simgrid_get_clock(), host, variable, "HOST", value, InstrUserVariable::ADD, "",
501                       &user_host_variables);
502 }
503
504 /** @ingroup TRACE_user_variables
505  *  @brief Subtract a value from a variable of a host.
506  *
507  *  @param host The name of the host to be considered.
508  *  @param variable The name of the variable to be considered.
509  *  @param value The value to be subtracted from the variable.
510  *
511  *  @see TRACE_host_variable_declare, TRACE_host_variable_set, TRACE_host_variable_add
512  */
513 void TRACE_host_variable_sub(const char* host, const char* variable, double value) // XBT_ATTRIB_DEPRECATED_v333
514 {
515   instr_user_variable(simgrid_get_clock(), host, variable, "HOST", value, InstrUserVariable::SUB, "",
516                       &user_host_variables);
517 }
518
519 void TRACE_host_variable_set_with_time(double time, const char* host, const char* variable,
520                                        double value) // XBT_ATTRIB_DEPRECATED_v333
521 {
522   instr_user_variable(time, host, variable, "HOST", value, InstrUserVariable::SET, "", &user_host_variables);
523 }
524
525 void TRACE_host_variable_add_with_time(double time, const char* host, const char* variable,
526                                        double value) // XBT_ATTRIB_DEPRECATED_v333
527 {
528   instr_user_variable(time, host, variable, "HOST", value, InstrUserVariable::ADD, "", &user_host_variables);
529 }
530
531 void TRACE_host_variable_sub_with_time(double time, const char* host, const char* variable,
532                                        double value) // XBT_ATTRIB_DEPRECATED_v333
533 {
534   instr_user_variable(time, host, variable, "HOST", value, InstrUserVariable::SUB, "", &user_host_variables);
535 }
536
537 xbt_dynar_t TRACE_get_host_variables() // XBT_ATTRIB_DEPRECATED_v333
538 {
539   return instr_set_to_dynar(user_host_variables);
540 }
541
542 /* for link variables */
543 void TRACE_link_variable_declare(const char* variable) // XBT_ATTRIB_DEPRECATED_v333
544 {
545   simgrid::instr::declare_link_variable(variable);
546 }
547
548 /** @ingroup TRACE_user_variables
549  *  @brief Declare a new user variable associated to links with a color.
550  *
551  *  Same as #TRACE_link_variable_declare, but associated a color to the newly created user link variable. The color
552  *  needs to be a string with three numbers separated by spaces in the range [0,1].
553  *  A light-gray color can be specified using "0.7 0.7 0.7" as color.
554  *
555  *  @param variable The name of the new variable to be declared.
556  *  @param color The color for the new variable.
557  */
558 void TRACE_link_variable_declare_with_color(const char* variable, const char* color) // XBT_ATTRIB_DEPRECATED_v333
559 {
560   simgrid::instr::declare_link_variable(variable, color);
561 }
562
563 /** @ingroup TRACE_user_variables
564  *  @brief Set the value of a variable of a link.
565  *
566  *  @param link The name of the link to be considered.
567  *  @param variable The name of the variable to be considered.
568  *  @param value The new value of the variable.
569  *
570  *  @see TRACE_link_variable_declare, TRACE_link_variable_add, TRACE_link_variable_sub
571  */
572 void TRACE_link_variable_set (const char *link, const char *variable, double value)
573 {
574   instr_user_variable(simgrid_get_clock(), link, variable, "LINK", value, InstrUserVariable::SET, "",
575                       &user_link_variables);
576 }
577
578 void TRACE_link_variable_add(const char* link, const char* variable, double value)
579 {
580   instr_user_variable(simgrid_get_clock(), link, variable, "LINK", value, InstrUserVariable::ADD, "",
581                       &user_link_variables);
582 }
583
584 void TRACE_link_variable_sub(const char* link, const char* variable, double value)
585 {
586   instr_user_variable(simgrid_get_clock(), link, variable, "LINK", value, InstrUserVariable::SUB, "",
587                       &user_link_variables);
588 }
589
590 void TRACE_link_variable_set_with_time(double time, const char* link, const char* variable,
591                                        double value) // XBT_ATTRIB_DEPRECATED_v333
592 {
593   instr_user_variable(time, link, variable, "LINK", value, InstrUserVariable::SET, "", &user_link_variables);
594 }
595
596 void TRACE_link_variable_add_with_time(double time, const char* link, const char* variable,
597                                        double value) // XBT_ATTRIB_DEPRECATED_v333
598 {
599   instr_user_variable(time, link, variable, "LINK", value, InstrUserVariable::ADD, "", &user_link_variables);
600 }
601
602 void TRACE_link_variable_sub_with_time(double time, const char* link, const char* variable,
603                                        double value) // XBT_ATTRIB_DEPRECATED_v333
604 {
605   instr_user_variable(time, link, variable, "LINK", value, InstrUserVariable::SUB, "", &user_link_variables);
606 }
607
608 void TRACE_link_srcdst_variable_set (const char *src, const char *dst, const char *variable, double value)
609 {
610   instr_user_srcdst_variable(simgrid_get_clock(), src, dst, variable, "LINK", value, InstrUserVariable::SET);
611 }
612
613 void TRACE_link_srcdst_variable_add(const char* src, const char* dst, const char* variable,
614                                     double value) // XBT_ATTRIB_DEPRECATED_v333
615 {
616   instr_user_srcdst_variable(simgrid_get_clock(), src, dst, variable, "LINK", value, InstrUserVariable::ADD);
617 }
618
619 void TRACE_link_srcdst_variable_sub(const char* src, const char* dst, const char* variable,
620                                     double value) // XBT_ATTRIB_DEPRECATED_v333
621 {
622   instr_user_srcdst_variable(simgrid_get_clock(), src, dst, variable, "LINK", value, InstrUserVariable::SUB);
623 }
624
625 void TRACE_link_srcdst_variable_set_with_time(double time, const char* src, const char* dst, const char* variable,
626                                               double value) // XBT_ATTRIB_DEPRECATED_v333
627 {
628   instr_user_srcdst_variable(time, src, dst, variable, "LINK", value, InstrUserVariable::SET);
629 }
630
631 void TRACE_link_srcdst_variable_add_with_time(double time, const char* src, const char* dst, const char* variable,
632                                               double value) // XBT_ATTRIB_DEPRECATED_v333
633 {
634   instr_user_srcdst_variable(time, src, dst, variable, "LINK", value, InstrUserVariable::ADD);
635 }
636
637 void TRACE_link_srcdst_variable_sub_with_time(double time, const char* src, const char* dst, const char* variable,
638                                               double value) // XBT_ATTRIB_DEPRECATED_v333
639 {
640   instr_user_srcdst_variable(time, src, dst, variable, "LINK", value, InstrUserVariable::SUB);
641 }
642
643 xbt_dynar_t TRACE_get_link_variables() // XBT_ATTRIB_DEPRECATED_v333
644 {
645   return instr_set_to_dynar(user_link_variables);
646 }
647
648 /** @ingroup TRACE_user_variables
649  *  @brief Declare a new user state associated to hosts.
650  *
651  *  Declare a user state that will be associated to hosts.
652  *  A user host state can be used to trace application states.
653  *
654  *  @param state The name of the new state to be declared.
655  *
656  *  @see TRACE_host_state_declare_value
657  */
658 void TRACE_host_state_declare (const char *state)
659 {
660   instr_new_user_state_type("HOST", state);
661 }
662
663 /** @ingroup TRACE_user_variables
664  *  @brief Declare a new value for a user state associated to hosts.
665  *
666  *  Declare a value for a state. The color needs to be a string with 3 numbers separated by spaces in the range [0,1].
667  *  A light-gray color can be specified using "0.7 0.7 0.7" as color.
668  *
669  *  @param state The name of the new state to be declared.
670  *  @param value The name of the value
671  *  @param color The color of the value
672  *
673  *  @see TRACE_host_state_declare
674  */
675 void TRACE_host_state_declare_value (const char *state, const char *value, const char *color)
676 {
677   instr_new_value_for_user_state_type (state, value, color);
678 }
679
680 /** @ingroup TRACE_user_variables
681  *  @brief Set the user state to the given value.
682  *
683  *  Change a user state previously declared to the given value.
684  *
685  *  @param host The name of the host to be considered.
686  *  @param state_name The name of the state previously declared.
687  *  @param value_name The new value of the state.
688  *
689  *  @see TRACE_host_state_declare, TRACE_host_push_state, TRACE_host_pop_state, TRACE_host_reset_state
690  */
691 void TRACE_host_set_state(const char* host, const char* state_name, const char* value_name)
692 {
693   simgrid::instr::StateType* state = simgrid::instr::Container::by_name(host)->get_state(state_name);
694   state->add_entity_value(value_name);
695   state->set_event(value_name);
696 }
697
698 /** @ingroup TRACE_user_variables
699  *  @brief Push a new value for a state of a given host.
700  *
701  *  Change a user state previously declared by pushing the new value to the state.
702  *
703  *  @param host The name of the host to be considered.
704  *  @param state_name The name of the state previously declared.
705  *  @param value_name The value to be pushed.
706  *
707  *  @see TRACE_host_state_declare, TRACE_host_set_state, TRACE_host_pop_state, TRACE_host_reset_state
708  */
709 void TRACE_host_push_state(const char* host, const char* state_name, const char* value_name)
710 {
711   simgrid::instr::Container::by_name(host)->get_state(state_name)->push_event(value_name);
712 }
713
714 /** @ingroup TRACE_user_variables
715  *  @brief Pop the last value of a state of a given host.
716  *
717  *  Change a user state previously declared by removing the last value of the state.
718  *
719  *  @param host The name of the host to be considered.
720  *  @param state_name The name of the state to be popped.
721  *
722  *  @see TRACE_host_state_declare, TRACE_host_set_state, TRACE_host_push_state, TRACE_host_reset_state
723  */
724 void TRACE_host_pop_state(const char* host, const char* state_name)
725 {
726   simgrid::instr::Container::by_name(host)->get_state(state_name)->pop_event();
727 }