Logo AND Algorithmique Numérique Distribuée

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