Logo AND Algorithmique Numérique Distribuée

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