Logo AND Algorithmique Numérique Distribuée

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