Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[trace] update example to show how to get declared marks
[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/network_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 = NULL;
23 xbt_dict_t declared_marks = NULL;
24
25 /** \ingroup TRACE_category
26  *  \brief Declare a new category with a random color.
27  *
28  *  This function should be used to define a user category. The
29  *  category can be used to differentiate the tasks that are created
30  *  during the simulation (for example, tasks from server1, server2,
31  *  or request tasks, computation tasks, communication tasks). All
32  *  resource utilization (host power and link bandwidth) will be
33  *  classified according to the task category. Tasks that do not
34  *  belong to a category are not traced. The color for the category
35  *  that is being declared is random. This function has no effect
36  *  if a category with the same name has been already declared.
37  *
38  * See \ref tracing_tracing for details on how to trace
39  * the (categorized) resource utilization.
40  *
41  *  \param category The name of the new tracing category to be created.
42  *
43  *  \see TRACE_category_with_color, MSG_task_set_category, SD_task_set_category
44  */
45 void TRACE_category(const char *category)
46 {
47   TRACE_category_with_color (category, NULL);
48 }
49
50 /** \ingroup TRACE_category
51  *  \brief Declare a new category with a color.
52  *
53  *  Same as #TRACE_category, but let user specify a color encoded as a
54  *  RGB-like string with three floats from 0 to 1. So, to specify a
55  *  red color, pass "1 0 0" as color parameter. A light-gray color
56  *  can be specified using "0.7 0.7 0.7" as color. This function has
57  *  no effect if a category with the same name has been already declared.
58  *
59  * See \ref tracing_tracing for details on how to trace
60  * the (categorized) resource utilization.
61  *
62  *  \param category The name of the new tracing category to be created.
63  *  \param color The color of the category (see \ref tracing_tracing to
64  *  know how to correctly specify the color)
65  *
66  *  \see MSG_task_set_category, SD_task_set_category
67  */
68 void TRACE_category_with_color (const char *category, const char *color)
69 {
70   /* safe switch */
71   if (!TRACE_is_enabled()) return;
72
73   if (!(TRACE_categorized() && category != NULL)) return;
74
75   /* if platform is not traced, we can't deal with categories */
76   if (!TRACE_needs_platform()) return;
77
78   //check if category is already created
79   char *created = xbt_dict_get_or_null(created_categories, category);
80   if (created) return;
81   xbt_dict_set (created_categories, category, xbt_strdup("1"), NULL);
82
83   //define final_color
84   char final_color[INSTR_DEFAULT_STR_SIZE];
85   if (!color){
86     //generate a random color
87     double red = drand48();
88     double green = drand48();
89     double blue = drand48();
90     snprintf (final_color, INSTR_DEFAULT_STR_SIZE, "%f %f %f", red, green, blue);
91   }else{
92     snprintf (final_color, INSTR_DEFAULT_STR_SIZE, "%s", color);
93   }
94
95   XBT_DEBUG("CAT,declare %s, %s", category, final_color);
96
97   //define the type of this category on top of hosts and links
98   instr_new_variable_type (category, final_color);
99 }
100
101
102 /** \ingroup TRACE_category
103  *  \brief Get declared categories
104  *
105  * This function should be used to get categories that were already
106  * declared with #TRACE_category or with #TRACE_category_with_color.
107  *
108  * See \ref tracing_tracing for details on how to trace
109  * the (categorized) resource utilization.
110  *
111  * \return A dynar with the declared categories, must be freed with xbt_dynar_free.
112  *
113  *  \see MSG_task_set_category, SD_task_set_category
114  */
115 xbt_dynar_t TRACE_get_categories (void)
116 {
117   if (!TRACE_is_enabled()) return NULL;
118   if (!TRACE_categorized()) return NULL;
119
120   xbt_dynar_t ret = xbt_dynar_new (sizeof(char*), &xbt_free_ref);
121   xbt_dict_cursor_t cursor = NULL;
122   char *name, *value;
123   xbt_dict_foreach(created_categories, cursor, name, value) {
124     xbt_dynar_push_as (ret, char*, xbt_strdup(name));
125   }
126   return ret;
127 }
128
129 /** \ingroup TRACE_mark
130  * \brief Declare a new type for tracing mark.
131  *
132  * This function declares a new Paje event
133  * type in the trace file that can be used by
134  * simulators to declare application-level
135  * marks. This function is independent of
136  * which API is used in SimGrid.
137  *
138  * \param mark_type The name of the new type.
139  *
140  * \see TRACE_mark
141  */
142 void TRACE_declare_mark(const char *mark_type)
143 {
144   /* safe switch */
145   if (!TRACE_is_enabled()) return;
146
147   if (!mark_type) return;
148
149   //check if mark_type is already declared
150   char *created = xbt_dict_get_or_null(declared_marks, mark_type);
151   if (created) return;
152   xbt_dict_set (declared_marks, mark_type, xbt_strdup("1"), NULL);
153
154   XBT_DEBUG("MARK,declare %s", mark_type);
155   PJ_type_event_new(mark_type, NULL, PJ_type_get_root());
156 }
157
158 /**
159  * \ingroup TRACE_mark
160  * \brief Create a new instance of a tracing mark type.
161  *
162  * This function creates a mark in the trace file. The
163  * first parameter had to be previously declared using
164  * #TRACE_declare_mark, the second is the identifier
165  * for this mark instance. We recommend that the
166  * mark_value is a unique value for the whole simulation.
167  * Nevertheless, this is not a strong requirement: the
168  * trace will be valid even if there are multiple mark
169  * identifiers for the same trace.
170  *
171  * \param mark_type The name of the type for which the new instance will belong.
172  * \param mark_value The name of the new instance mark.
173  *
174  * \see TRACE_declare_mark
175  */
176 void TRACE_mark(const char *mark_type, const char *mark_value)
177 {
178   /* safe switch */
179   if (!TRACE_is_enabled()) return;
180
181   if (!mark_type || !mark_value) return;
182
183   //check if mark_type is already declared
184   char *created = xbt_dict_get_or_null(declared_marks, mark_type);
185   if (created) return;
186
187   XBT_DEBUG("MARK %s %s", mark_type, mark_value);
188   type_t type = PJ_type_get (mark_type, PJ_type_get_root());
189   if (type == NULL){
190     THROWF (tracing_error, 1, "mark_type with name (%s) not declared before", mark_type);
191   }
192   val_t value = PJ_value_get (mark_value, type);
193   if (value == NULL){
194     value = PJ_value_new (mark_value, NULL, type);
195   }
196   new_pajeNewEvent (MSG_get_clock(), PJ_container_get_root(), type, value);
197 }
198
199 /** \ingroup TRACE_mark
200  *  \brief Get declared marks
201  *
202  * This function should be used to get marks that were already
203  * declared with #TRACE_declare_mark.
204  *
205  * \return A dynar with the declared marks, must be freed with xbt_dynar_free.
206  *
207  */
208 xbt_dynar_t TRACE_get_marks (void)
209 {
210   if (!TRACE_is_enabled()) return NULL;
211
212   xbt_dynar_t ret = xbt_dynar_new (sizeof(char*), &xbt_free_ref);
213   xbt_dict_cursor_t cursor = NULL;
214   char *name, *value;
215   xbt_dict_foreach(declared_marks, cursor, name, value) {
216     xbt_dynar_push_as (ret, char*, xbt_strdup(name));
217   }
218   return ret;
219 }
220
221 static void instr_user_variable(double time,
222                          const char *resource,
223                          const char *variable,
224                          const char *father_type,
225                          double value,
226                          InstrUserVariable what,
227                          const char *color)
228 {
229   /* safe switch */
230   if (!TRACE_is_enabled()) return;
231
232   /* if platform is not traced, we can't deal user variables */
233   if (!TRACE_needs_platform()) return;
234
235   char valuestr[100];
236   snprintf(valuestr, 100, "%g", value);
237
238   switch (what){
239   case INSTR_US_DECLARE:
240     instr_new_user_variable_type (father_type, variable, color);
241     break;
242   case INSTR_US_SET:
243   {
244     container_t container = PJ_container_get(resource);
245     type_t type = PJ_type_get (variable, container->type);
246     new_pajeSetVariable(time, container, type, value);
247     break;
248   }
249   case INSTR_US_ADD:
250   {
251     container_t container = PJ_container_get(resource);
252     type_t type = PJ_type_get (variable, container->type);
253     new_pajeAddVariable(time, container, type, value);
254     break;
255   }
256   case INSTR_US_SUB:
257   {
258     container_t container = PJ_container_get(resource);
259     type_t type = PJ_type_get (variable, container->type);
260     new_pajeSubVariable(time, container, type, value);
261     break;
262   }
263   default:
264     //TODO: launch exception
265     break;
266   }
267 }
268
269 static void instr_user_srcdst_variable(double time,
270                               const char *src,
271                               const char *dst,
272                               const char *variable,
273                               const char *father_type,
274                               double value,
275                               InstrUserVariable what)
276 {
277   xbt_dynar_t route=NULL;
278   network_element_t src_elm = xbt_lib_get_or_null(host_lib,src,ROUTING_HOST_LEVEL);
279   if(!src_elm) src_elm = xbt_lib_get_or_null(as_router_lib,src,ROUTING_ASR_LEVEL);
280   if(!src_elm) xbt_die("Element '%s' not found!",src);
281
282   network_element_t dst_elm = xbt_lib_get_or_null(host_lib,dst,ROUTING_HOST_LEVEL);
283   if(!dst_elm) dst_elm = xbt_lib_get_or_null(as_router_lib,dst,ROUTING_ASR_LEVEL);
284   if(!dst_elm) xbt_die("Element '%s' not found!",dst);
285
286   routing_get_route_and_latency (src_elm, dst_elm, &route,NULL);
287   unsigned int i;
288   void *link;
289   xbt_dynar_foreach (route, i, link) {
290     char *link_name = ((link_CM02_t)link)->lmm_resource.generic_resource.name;
291     instr_user_variable (time, link_name, variable, father_type, value, what, NULL);
292   }
293 }
294
295 /** \ingroup TRACE_API
296  *  \brief Creates a file with the topology of the platform file used for the simulator.
297  *
298  *  The graph topology will have the following properties: all hosts, links and routers
299  *  of the platform file are mapped to graph nodes; routes are mapped to edges.
300  *  The platform's AS are not represented in the output.
301  *
302  *  \param filename The name of the file that will hold the graph.
303  *
304  *  \return 1 of successful, 0 otherwise.
305  */
306 int TRACE_platform_graph_export_graphviz (const char *filename)
307 {
308   /* returns 1 if successful, 0 otherwise */
309   if (!TRACE_is_enabled()) return 0;
310   xbt_graph_t g = instr_routing_platform_graph();
311   if (g == NULL) return 0;
312   instr_routing_platform_graph_export_graphviz (g, filename);
313   xbt_graph_free_graph (g, xbt_free, xbt_free, NULL);
314   return 1;
315 }
316
317 /*
318  * Derived functions that use instr_user_variable and TRACE_user_srcdst_variable.
319  * They were previously defined as pre-processors directives, but were transformed
320  * into functions so the user can track them using gdb.
321  */
322
323 /* for host variables */
324 /** \ingroup TRACE_user_variables
325  *  \brief Declare a new user variable associated to hosts.
326  *
327  *  Declare a user variable that will be associated to hosts.
328  *  A user host variable can be used to trace user variables
329  *  such as the number of tasks in a server, the number of
330  *  clients in an application (for hosts), and so on. The color
331  *  associated to this new variable will be random.
332  *
333  *  \param variable The name of the new variable to be declared.
334  *
335  *  \see TRACE_host_variable_declare_with_color
336  */
337 void TRACE_host_variable_declare (const char *variable)
338 {
339   instr_user_variable(0, NULL, variable, "HOST", 0, INSTR_US_DECLARE, NULL);
340 }
341
342 /** \ingroup TRACE_user_variables
343  *  \brief Declare a new user variable associated to hosts with a color.
344  *
345  *  Same as #TRACE_host_variable_declare, but associated a color
346  *  to the newly created user host variable. The color needs to be
347  *  a string with three numbers separated by spaces in the range [0,1].
348  *  A light-gray color can be specified using "0.7 0.7 0.7" as color.
349  *
350  *  \param variable The name of the new variable to be declared.
351  *  \param color The color for the new variable.
352  *
353  */
354 void TRACE_host_variable_declare_with_color (const char *variable, const char *color)
355 {
356   instr_user_variable(0, NULL, variable, "HOST", 0, INSTR_US_DECLARE, color);
357 }
358
359 /** \ingroup TRACE_user_variables
360  *  \brief Set the value of a variable of a host.
361  *
362  *  \param host The name of the host to be considered.
363  *  \param variable The name of the variable to be considered.
364  *  \param value The new value of the variable.
365  *
366  *  \see TRACE_host_variable_declare, TRACE_host_variable_add, TRACE_host_variable_sub
367  */
368 void TRACE_host_variable_set (const char *host, const char *variable, double value)
369 {
370   TRACE_host_variable_set_with_time (MSG_get_clock(), host, variable, value);
371 }
372
373 /** \ingroup TRACE_user_variables
374  *  \brief Add a value to a variable of a host.
375  *
376  *  \param host The name of the host to be considered.
377  *  \param variable The name of the variable to be considered.
378  *  \param value The value to be added to the variable.
379  *
380  *  \see TRACE_host_variable_declare, TRACE_host_variable_set, TRACE_host_variable_sub
381  */
382 void TRACE_host_variable_add (const char *host, const char *variable, double value)
383 {
384   TRACE_host_variable_add_with_time (MSG_get_clock(), host, variable, value);
385 }
386
387 /** \ingroup TRACE_user_variables
388  *  \brief Subtract a value from a variable of a host.
389  *
390  *  \param host The name of the host to be considered.
391  *  \param variable The name of the variable to be considered.
392  *  \param value The value to be subtracted from the variable.
393  *
394  *  \see TRACE_host_variable_declare, TRACE_host_variable_set, TRACE_host_variable_add
395  */
396 void TRACE_host_variable_sub (const char *host, const char *variable, double value)
397 {
398   TRACE_host_variable_sub_with_time (MSG_get_clock(), host, variable, value);
399 }
400
401 /** \ingroup TRACE_user_variables
402  *  \brief Set the value of a variable of a host at a given timestamp.
403  *
404  *  Same as #TRACE_host_variable_set, but let user specify
405  *  the time used to trace it. Users can specify a time that
406  *  is not the simulated clock time as defined by the core
407  *  simulator. This allows a fine-grain control of time
408  *  definition, but should be used with caution since the trace
409  *  can be inconsistent if resource utilization traces are also traced.
410  *
411  *  \param time The timestamp to be used to tag this change of value.
412  *  \param host The name of the host to be considered.
413  *  \param variable The name of the variable to be considered.
414  *  \param value The new value of the variable.
415  *
416  *  \see TRACE_host_variable_declare, TRACE_host_variable_add_with_time, TRACE_host_variable_sub_with_time
417  */
418 void TRACE_host_variable_set_with_time (double time, const char *host, const char *variable, double value)
419 {
420   instr_user_variable(time, host, variable, "HOST", value, INSTR_US_SET, NULL);
421 }
422
423 /** \ingroup TRACE_user_variables
424  *  \brief Add a value to a variable of a host at a given timestamp.
425  *
426  *  Same as #TRACE_host_variable_add, but let user specify
427  *  the time used to trace it. Users can specify a time that
428  *  is not the simulated clock time as defined by the core
429  *  simulator. This allows a fine-grain control of time
430  *  definition, but should be used with caution since the trace
431  *  can be inconsistent if resource utilization traces are also traced.
432  *
433  *  \param time The timestamp to be used to tag this change of value.
434  *  \param host The name of the host to be considered.
435  *  \param variable The name of the variable to be considered.
436  *  \param value The value to be added to the variable.
437  *
438  *  \see TRACE_host_variable_declare, TRACE_host_variable_set_with_time, TRACE_host_variable_sub_with_time
439  */
440 void TRACE_host_variable_add_with_time (double time, const char *host, const char *variable, double value)
441 {
442   instr_user_variable(time, host, variable, "HOST", value, INSTR_US_ADD, NULL);
443 }
444
445 /** \ingroup TRACE_user_variables
446  *  \brief Subtract a value from a variable of a host at a given timestamp.
447  *
448  *  Same as #TRACE_host_variable_sub, but let user specify
449  *  the time used to trace it. Users can specify a time that
450  *  is not the simulated clock time as defined by the core
451  *  simulator. This allows a fine-grain control of time
452  *  definition, but should be used with caution since the trace
453  *  can be inconsistent if resource utilization traces are also traced.
454  *
455  *  \param time The timestamp to be used to tag this change of value.
456  *  \param host The name of the host to be considered.
457  *  \param variable The name of the variable to be considered.
458  *  \param value The value to be subtracted from the variable.
459  *
460  *  \see TRACE_host_variable_declare, TRACE_host_variable_set_with_time, TRACE_host_variable_add_with_time
461  */
462 void TRACE_host_variable_sub_with_time (double time, const char *host, const char *variable, double value)
463 {
464   instr_user_variable(time, host, variable, "HOST", value, INSTR_US_SUB, NULL);
465 }
466
467 /* for link variables */
468 /** \ingroup TRACE_user_variables
469  *  \brief Declare a new user variable associated to links.
470  *
471  *  Declare a user variable that will be associated to links.
472  *  A user link variable can be used, for example, to trace
473  *  user variables such as the number of messages being
474  *  transferred through network links. The color
475  *  associated to this new variable will be random.
476  *
477  *  \param variable The name of the new variable to be declared.
478  *
479  *  \see TRACE_link_variable_declare_with_color
480  */
481 void TRACE_link_variable_declare (const char *variable)
482 {
483   instr_user_variable (0, NULL, variable, "LINK", 0, INSTR_US_DECLARE, NULL);
484 }
485
486 /** \ingroup TRACE_user_variables
487  *  \brief Declare a new user variable associated to links with a color.
488  *
489  *  Same as #TRACE_link_variable_declare, but associated a color
490  *  to the newly created user link variable. The color needs to be
491  *  a string with three numbers separated by spaces in the range [0,1].
492  *  A light-gray color can be specified using "0.7 0.7 0.7" as color.
493  *
494  *  \param variable The name of the new variable to be declared.
495  *  \param color The color for the new variable.
496  *
497  */
498 void TRACE_link_variable_declare_with_color (const char *variable, const char *color)
499 {
500   instr_user_variable (0, NULL, variable, "LINK", 0, INSTR_US_DECLARE, color);
501 }
502
503 /** \ingroup TRACE_user_variables
504  *  \brief Set the value of a variable of a link.
505  *
506  *  \param link The name of the link to be considered.
507  *  \param variable The name of the variable to be considered.
508  *  \param value The new value of the variable.
509  *
510  *  \see TRACE_link_variable_declare, TRACE_link_variable_add, TRACE_link_variable_sub
511  */
512 void TRACE_link_variable_set (const char *link, const char *variable, double value)
513 {
514   TRACE_link_variable_set_with_time (MSG_get_clock(), link, variable, value);
515 }
516
517 /** \ingroup TRACE_user_variables
518  *  \brief Add a value to a variable of a link.
519  *
520  *  \param link The name of the link to be considered.
521  *  \param variable The name of the variable to be considered.
522  *  \param value The value to be added to the variable.
523  *
524  *  \see TRACE_link_variable_declare, TRACE_link_variable_set, TRACE_link_variable_sub
525  */
526 void TRACE_link_variable_add (const char *link, const char *variable, double value)
527 {
528   TRACE_link_variable_add_with_time (MSG_get_clock(), link, variable, value);
529 }
530
531 /** \ingroup TRACE_user_variables
532  *  \brief Subtract a value from a variable of a link.
533  *
534  *  \param link The name of the link to be considered.
535  *  \param variable The name of the variable to be considered.
536  *  \param value The value to be subtracted from the variable.
537  *
538  *  \see TRACE_link_variable_declare, TRACE_link_variable_set, TRACE_link_variable_add
539  */
540 void TRACE_link_variable_sub (const char *link, const char *variable, double value)
541 {
542   TRACE_link_variable_sub_with_time (MSG_get_clock(), link, variable, value);
543 }
544
545 /** \ingroup TRACE_user_variables
546  *  \brief Set the value of a variable of a link at a given timestamp.
547  *
548  *  Same as #TRACE_link_variable_set, but let user specify
549  *  the time used to trace it. Users can specify a time that
550  *  is not the simulated clock time as defined by the core
551  *  simulator. This allows a fine-grain control of time
552  *  definition, but should be used with caution since the trace
553  *  can be inconsistent if resource utilization traces are also traced.
554  *
555  *  \param time The timestamp to be used to tag this change of value.
556  *  \param link The name of the link to be considered.
557  *  \param variable The name of the variable to be considered.
558  *  \param value The new value of the variable.
559  *
560  *  \see TRACE_link_variable_declare, TRACE_link_variable_add_with_time, TRACE_link_variable_sub_with_time
561  */
562 void TRACE_link_variable_set_with_time (double time, const char *link, const char *variable, double value)
563 {
564   instr_user_variable (time, link, variable, "LINK", value, INSTR_US_SET, NULL);
565 }
566
567 /** \ingroup TRACE_user_variables
568  *  \brief Add a value to a variable of a link at a given timestamp.
569  *
570  *  Same as #TRACE_link_variable_add, but let user specify
571  *  the time used to trace it. Users can specify a time that
572  *  is not the simulated clock time as defined by the core
573  *  simulator. This allows a fine-grain control of time
574  *  definition, but should be used with caution since the trace
575  *  can be inconsistent if resource utilization traces are also traced.
576  *
577  *  \param time The timestamp to be used to tag this change of value.
578  *  \param link The name of the link to be considered.
579  *  \param variable The name of the variable to be considered.
580  *  \param value The value to be added to the variable.
581  *
582  *  \see TRACE_link_variable_declare, TRACE_link_variable_set_with_time, TRACE_link_variable_sub_with_time
583  */
584 void TRACE_link_variable_add_with_time (double time, const char *link, const char *variable, double value)
585 {
586   instr_user_variable (time, link, variable, "LINK", value, INSTR_US_ADD, NULL);
587 }
588
589 /** \ingroup TRACE_user_variables
590  *  \brief Subtract a value from a variable of a link at a given timestamp.
591  *
592  *  Same as #TRACE_link_variable_sub, but let user specify
593  *  the time used to trace it. Users can specify a time that
594  *  is not the simulated clock time as defined by the core
595  *  simulator. This allows a fine-grain control of time
596  *  definition, but should be used with caution since the trace
597  *  can be inconsistent if resource utilization traces are also traced.
598  *
599  *  \param time The timestamp to be used to tag this change of value.
600  *  \param link The name of the link to be considered.
601  *  \param variable The name of the variable to be considered.
602  *  \param value The value to be subtracted from the variable.
603  *
604  *  \see TRACE_link_variable_declare, TRACE_link_variable_set_with_time, TRACE_link_variable_add_with_time
605  */
606 void TRACE_link_variable_sub_with_time (double time, const char *link, const char *variable, double value)
607 {
608   instr_user_variable (time, link, variable, "LINK", value, INSTR_US_SUB, NULL);
609 }
610
611 /* for link variables, but with src and dst used for get_route */
612 /** \ingroup TRACE_user_variables
613  *  \brief Set the value of the variable present in the links connecting source and destination.
614  *
615  *  Same as #TRACE_link_variable_set, but instead of providing the
616  *  name of link to be considered, provide the source and destination
617  *  hosts. All links that are part of the route between source and
618  *  destination will have the variable set to the provided value.
619  *
620  *  \param src The name of the source host for get route.
621  *  \param dst The name of the destination host for get route.
622  *  \param variable The name of the variable to be considered.
623  *  \param value The new value of the variable.
624  *
625  *  \see TRACE_link_variable_declare, TRACE_link_srcdst_variable_add, TRACE_link_srcdst_variable_sub
626  */
627 void TRACE_link_srcdst_variable_set (const char *src, const char *dst, const char *variable, double value)
628 {
629   TRACE_link_srcdst_variable_set_with_time (MSG_get_clock(), src, dst, variable, value);
630 }
631
632 /** \ingroup TRACE_user_variables
633  *  \brief Add a value to the variable present in the links connecting source and destination.
634  *
635  *  Same as #TRACE_link_variable_add, but instead of providing the
636  *  name of link to be considered, provide the source and destination
637  *  hosts. All links that are part of the route between source and
638  *  destination will have the value passed as parameter added to
639  *  the current value of the variable name to be considered.
640  *
641  *  \param src The name of the source host for get route.
642  *  \param dst The name of the destination host for get route.
643  *  \param variable The name of the variable to be considered.
644  *  \param value The value to be added to the variable.
645  *
646  *  \see TRACE_link_variable_declare, TRACE_link_srcdst_variable_set, TRACE_link_srcdst_variable_sub
647  */
648 void TRACE_link_srcdst_variable_add (const char *src, const char *dst, const char *variable, double value)
649 {
650   TRACE_link_srcdst_variable_add_with_time (MSG_get_clock(), src, dst, variable, value);
651 }
652
653 /** \ingroup TRACE_user_variables
654  *  \brief Subtract a value from the variable present in the links connecting source and destination.
655  *
656  *  Same as #TRACE_link_variable_sub, but instead of providing the
657  *  name of link to be considered, provide the source and destination
658  *  hosts. All links that are part of the route between source and
659  *  destination will have the value passed as parameter subtracted from
660  *  the current value of the variable name to be considered.
661  *
662  *  \param src The name of the source host for get route.
663  *  \param dst The name of the destination host for get route.
664  *  \param variable The name of the variable to be considered.
665  *  \param value The value to be subtracted from the variable.
666  *
667  *  \see TRACE_link_variable_declare, TRACE_link_srcdst_variable_set, TRACE_link_srcdst_variable_add
668  */
669 void TRACE_link_srcdst_variable_sub (const char *src, const char *dst, const char *variable, double value)
670 {
671   TRACE_link_srcdst_variable_sub_with_time (MSG_get_clock(), src, dst, variable, value);
672 }
673
674 /** \ingroup TRACE_user_variables
675  *  \brief Set the value of the variable present in the links connecting source and destination at a given timestamp.
676  *
677  *  Same as #TRACE_link_srcdst_variable_set, but let user specify
678  *  the time used to trace it. Users can specify a time that
679  *  is not the simulated clock time as defined by the core
680  *  simulator. This allows a fine-grain control of time
681  *  definition, but should be used with caution since the trace
682  *  can be inconsistent if resource utilization traces are also traced.
683  *
684  *  \param time The timestamp to be used to tag this change of value.
685  *  \param src The name of the source host for get route.
686  *  \param dst The name of the destination host for get route.
687  *  \param variable The name of the variable to be considered.
688  *  \param value The new value of the variable.
689  *
690  *  \see TRACE_link_variable_declare, TRACE_link_srcdst_variable_add_with_time, TRACE_link_srcdst_variable_sub_with_time
691  */
692 void TRACE_link_srcdst_variable_set_with_time (double time, const char *src, const char *dst, const char *variable, double value)
693 {
694   instr_user_srcdst_variable (time, src, dst, variable, "LINK", value, INSTR_US_SET);
695 }
696
697 /** \ingroup TRACE_user_variables
698  *  \brief Add a value to the variable present in the links connecting source and destination at a given timestamp.
699  *
700  *  Same as #TRACE_link_srcdst_variable_add, but let user specify
701  *  the time used to trace it. Users can specify a time that
702  *  is not the simulated clock time as defined by the core
703  *  simulator. This allows a fine-grain control of time
704  *  definition, but should be used with caution since the trace
705  *  can be inconsistent if resource utilization traces are also traced.
706  *
707  *  \param time The timestamp to be used to tag this change of value.
708  *  \param src The name of the source host for get route.
709  *  \param dst The name of the destination host for get route.
710  *  \param variable The name of the variable to be considered.
711  *  \param value The value to be added to the variable.
712  *
713  *  \see TRACE_link_variable_declare, TRACE_link_srcdst_variable_set_with_time, TRACE_link_srcdst_variable_sub_with_time
714  */
715 void TRACE_link_srcdst_variable_add_with_time (double time, const char *src, const char *dst, const char *variable, double value)
716 {
717   instr_user_srcdst_variable (time, src, dst, variable, "LINK", value, INSTR_US_ADD);
718 }
719
720 /** \ingroup TRACE_user_variables
721  *  \brief Subtract a value from the variable present in the links connecting source and destination at a given timestamp.
722  *
723  *  Same as #TRACE_link_srcdst_variable_sub, but let user specify
724  *  the time used to trace it. Users can specify a time that
725  *  is not the simulated clock time as defined by the core
726  *  simulator. This allows a fine-grain control of time
727  *  definition, but should be used with caution since the trace
728  *  can be inconsistent if resource utilization traces are also traced.
729  *
730  *  \param time The timestamp to be used to tag this change of value.
731  *  \param src The name of the source host for get route.
732  *  \param dst The name of the destination host for get route.
733  *  \param variable The name of the variable to be considered.
734  *  \param value The value to be subtracted from the variable.
735  *
736  *  \see TRACE_link_variable_declare, TRACE_link_srcdst_variable_set_with_time, TRACE_link_srcdst_variable_add_with_time
737  */
738 void TRACE_link_srcdst_variable_sub_with_time (double time, const char *src, const char *dst, const char *variable, double value)
739 {
740   instr_user_srcdst_variable (time, src, dst, variable, "LINK", value, INSTR_US_SUB);
741 }
742
743 #endif /* HAVE_TRACING */