--- /dev/null
+#ifndef ATTRIBUTE_H
+#define ATTRIBUTE_H
+
+
+#include <glib.h>
+#include <time.h>
+
+/* Attributes are used to store any value identified by a key. They are
+ typically used to store state information or accumulated statistics for
+ some object. Each value is accessed through a multi-component key, which
+ resembles hierarchical pathnames in filesystems.
+
+ The attributes may store integers, doubles or time values, in which case
+ the values are created upon first access of a key and with a default
+ value of 0. Pointer values are also available with a default value of NULL
+ and must thus be set explicitely to user managed (statically or dynamically
+ allocated) memory. */
+
+
+typedef guint32 lttv_string_id;
+
+typedef GArray _lttv_key;
+
+typedef _lttv_key lttv_key;
+
+typedef struct timespec lttv_time;
+
+
+typedef struct _lttv_attributes {
+ GHashTable *ints;
+ GHashTable *times;
+ GHashTable *doubles;
+ GHashTable *pointers;
+} lttv_attributes;
+
+
+/* A unique integer identifier represents each different string
+ used as a key component. A single copy of each different string is
+ stored but its usage count is incremented each time the corresponding id
+ is returned by lttv_string_id_from_string. The usage count is decremented
+ each time an id is released. */
+
+lttv_string_id lttv_string_id_from_string(const char *s);
+
+void lttv_string_id_release(lttv_string_id i);
+
+const char *lttv_string_id_to_string(lttv_string_id i);
+
+
+/* Keys are created and subsequently filled with key components */
+
+lttv_key *lttv_key_new();
+
+void lttv_key_destroy(lttv_key *k);
+
+/* macro to access/replace a the i th component of key k */
+
+#define lttv_key_index(k,i) _lttv_key_index(k,i)
+
+
+/* Append a new component */
+
+void lttv_key_append(lttv_key *k, lttv_string_id i);
+
+
+/* Number of components in a key */
+
+unsigned int lttv_key_number(lttv_key *k);
+
+
+/* It is also possible to create a key directly from a pathname,
+ key components separated by /, (e.g., "/hooks/options/before"). */
+
+lttv_key *lttv_key_new_pathname(const char *pathname);
+
+
+/* Create a new set of attributes */
+
+lttv_attributes *lttv_attributes_new();
+
+
+/* Destroy the set of attributes including all the memory allocated
+ internally for it (copies of keys, and integer, double and time
+ values...). */
+
+void lttv_attributes_destroy(lttv_attributes *a);
+
+
+/* Total number of attributes in a lttv_attributes. */
+
+unsigned int lttv_attributes_number(lttv_attributes *a);
+
+
+/* Obtain a pointer to the value of the corresponding type associated with
+ the specified key. New values are created on demand with 0 as initial
+ value. These values are freed when the attributes set is destroyed. */
+
+int *lttv_attributes_get_integer(lttv_attributes *a, lttv_key *k);
+
+lttv_time *lttv_attributes_get_time(lttv_attributes *a, lttv_key *k);
+
+double *lttv_attributes_get_double(lttv_attributes *a, lttv_key *k);
+
+
+/* Set or get the pointer value associated with the specified key.
+ NULL is returned if no pointer was set for the key. */
+
+void *lttv_attributes_get_pointer(lttv_attributes *a, lttv_key *k);
+
+void lttv_attributes_set_pointer(lttv_attributes *a, lttv_key *k, void *p);
+
+void *lttv_attributes_get_pointer_pathname(lttv_attributes *a, char *pn);
+
+void lttv_attributes_set_pointer_pathname(lttv_attributes *a,char *pn,void *p);
+
+
+/* It is often useful to copy over some elements from the source attributes
+ table to the destination table. While doing so, constraints on each key
+ component may be used to select the elements of interest. Finally, some
+ numerical elements may need to be summed, for example summing the number
+ of page faults over all processes. A flexible function to copy attributes
+ may be used for all these operations.
+
+ If the key of the element copied already exists in the destination
+ attributes, numerical values (integer, double or time) are summed and
+ pointers are replaced.
+
+ The lttv_key_select_data structure specifies for each key component the
+ test applied to decide to copy or not the corresponding element.
+ It contains the relation to apply to each key component, the rel vector,
+ and the comparison key, both of size length. To decide if an element
+ should be copied, each component of its key is compared with the
+ comparison key, and the relation specified for each component must
+ be verified. The relation ANY is always verified and the comparison key
+ component is not used. The relation NONE is only verified if the key
+ examined contains fewer components than the position examined. The EQ, NE,
+ LT, LE, GT, GE relations are verified if the key is long enough and the
+ component satisfies the relation with respect to the comparison key.
+ Finally, the CUT relation is satisfied if the key is long enough, but the
+ element is copied with that component removed from its key. All the keys
+ which only differ by that component become identical after being shortened
+ and their numerical values are thus summed when copied. */
+
+typedef enum _lttv_key_select_relation
+{ LTTV_KEY_ANY, /* Any value is good */
+ LTTV_KEY_NONE, /* No value is good, i.e. the key must be shorter */
+ LTTV_KEY_EQ, /* key[n] is equal to match[n] */
+ LTTV_KEY_NE, /* key[n] is not equal to match[n] */
+ LTTV_KEY_LT, /* key[n] is lower than match[n] */
+ LTTV_KEY_LE, /* key[n] is lower or equal than match[n] */
+ LTTV_KEY_GT, /* key[n] is greater than match[n] */
+ LTTV_KEY_GE, /* key[n] is greater or equal than match[n] */
+ LTTV_KEY_CUT /* cut key[n], shortening the key for the copy */
+} lttv_key_select_relation;
+
+typedef struct _lttv_key_select_data
+{
+ unsigned length;
+ lttv_key_select_relation *rel;
+ lttv_key *comparison;
+} lttv_key_select_data;
+
+void lttv_attributes_copy(lttv_attributes *src, lttv_attributes *dest,
+ lttv_key_select_data d);
+
+
+/* Sometimes the attributes must be accessed in bulk, sorted in different
+ ways. For this purpose they may be converted to arrays and sorted
+ multiple times. The keys used in the array belong to the lttv_attributes
+ object from which the array was obtained and are freed when it is
+ destroyed. Each element in the array is an lttv_attribute, a structure
+ containing the key, the value type, and a union containing a value of
+ that type. Multiple attributes with equal keys may be possible in some
+ implementations if their type differs. */
+
+
+typedef enum _lttv_attribute_type
+{ LTTV_INTEGER, LTTV_TIME, LTTV_DOUBLE, LTTV_POINTER }
+lttv_attribute_type;
+
+typedef union _lttv_value_any
+{ int i;
+ lttv_time t;
+ double d;
+ void *p;
+} lttv_value_any;
+
+typedef struct _lttv_attribute {
+ lttv_key *key;
+ lttv_attribute_type t;
+ lttv_value_any v;
+} lttv_attribute;
+
+
+/* Obtain all the attributes in an array */
+
+lttv_attribute *lttv_attributes_array_get(lttv_attributes *a);
+
+lttv_attribute *lttv_attribute_array_destroy(lttv_attribute *a);
+
+
+/* The sorting order is determined by the supplied comparison function.
+ The comparison function must return a negative value if a < b,
+ 0 if a = b, and a positive if a > b. */
+
+typedef int (*lttv_key_compare)(lttv_key *a, lttv_key *b, void *user_data);
+
+void lttv_attribute_array_sort(lttv_attribute *a, unsigned size,
+ lttv_key_compare f, void *user_data);
+
+
+/* Sort in lexicographic order using the specified key components as primary,
+ secondary... keys. A vector containing the key components positions is
+ specified. */
+
+int lttv_attribute_array_sort_lexicographic(lttv_attribute *a, unsigned size,
+ unsigned *positions, unsigned nb_positions);
+
+#endif // ATTRIBUTE_H
--- /dev/null
+#ifndef FILTER_H
+#define FILTER_H
+
+/* A filter expression consists in nested AND, OR and NOT expressions
+ involving boolean relation (>, >=, =, !=, <, <=) between event fields and
+ specific values. It is compiled into an efficient data structure which
+ is used in functions to check if a given event or tracefile satisfies the
+ filter.
+
+ The grammar for filters is:
+
+ filter = expression
+
+ expression = "(" expression ")" | "!" expression |
+ expression "&&" expression | expression "||" expression |
+ simpleExpression
+
+ simpleExpression = fieldPath op value
+
+ fieldPath = fieldComponent [ "." fieldPath ]
+
+ fieldComponent = name [ "[" integer "]" ]
+
+ value = integer | double | string
+
+*/
+
+
+typedef struct _lttv_filter lttv_filter;
+
+
+/* Compile the filter expression into an efficient data structure */
+
+lttv_filter *lttv_filter_new(char *expression, lttv_trace *t);
+
+
+/* Check if the tracefile or event satisfies the filter. The arguments are
+ declared as void * to allow these functions to be used as hooks. */
+
+bool lttv_filter_tracefile(void *filter, void *tracefile);
+
+bool lttv_filter_event(void *filter, void *event);
+
+#endif // FILTER_H
+
--- /dev/null
+#ifndef LTTV_H
+#define LTTV_H
+
+#include "attribute.h"
+
+/* Initial draft by Michel Dagenais May 2003
+ * Reworked by Mathieu Desnoyers, May 2003
+ */
+
+
+/* The modules in the visualizer communicate with the main module and
+ with each other through attributes. There is a global set of attributes as
+ well as attributes attached to each trace set, trace and tracefile. */
+
+lttv_attributes *lttv_global_attributes();
+
+
+
+/* Modules are allowed to define new command line options.
+
+ Each option has a long name (--long_name), a short one character
+ name (-c), a descriptive text, the argument type, and a
+ pointer to where the argument value will be stored. For an option of
+ type LTTV_OPT_NONE, the argument is a boolean value set to true when the
+ option is present. */
+
+/* Those are already in option.h, cause conflict */
+//typedef enum _lttv_option_type
+//{LTTV_OPT_NONE, LTTV_OPT_STRING, LTTV_OPT_INT, LTTV_OPT_LONG }
+//lttv_option_type;
+
+
+//void lttv_option_add(char *long_name, char char_name, char *description,
+// lttv_option_type t, void *p);
+
+
+
+/* A number of global attributes are initialized before modules are
+ loaded, for example hooks lists. More global attributes are defined
+ in individual mudules to store information or to communicate with other
+ modules (GUI windows, menus...).
+
+ The hooks lists (lttv_hooks) are initialized in the main module and may be
+ used by other modules. Each corresponds to a specific location in the main
+ module processing loop. The attribute key and typical usage for each
+ is indicated.
+
+ /hooks/options/before
+ Good place to define new command line options to be parsed.
+
+ /hooks/options/after
+ Read the values set by the command line options.
+
+ /hooks/trace_set/before
+ Before any analysis.
+
+ /hooks/trace_set/after
+ After all traces were analyzed.
+
+ /hooks/trace/before
+ Before each trace.
+
+ /hooks/trace/after
+ After each trace.
+
+ /hooks/tracefile/before
+ Before each tracefile.
+
+ /hooks/tracefile/after
+ After each tracefile.
+
+ /hooks/event
+ Called for each event
+
+ /hooks/event_id
+ This attribute contains an lttv_hooks_by_id, where the hooks for each
+ id are to be called when an event of the associated type are found.
+
+*/
+
+#endif // LTTV_H
--- /dev/null
+#ifndef OPTION_H
+#define OPTION_H
+
+/* Options parsing mechanism */
+
+/* Define a new command line option with a long name (--long_name), a short
+ one character name (-c), a descriptive text, the argument type, and a
+ pointer to where the argument value will be stored. For an option of
+ type LTTV_OPT_NONE, the argument is a boolean value set to true when the
+ option is present. */
+
+/* Initial draft by Michel Dagenais May 2003
+ * Reworked by Mathieu Desnoyers, May 2003
+ */
+
+typedef enum _lttv_option_type
+{LTTV_OPT_NONE, LTTV_OPT_STRING, LTTV_OPT_INT, LTTV_OPT_LONG }
+lttv_option_type;
+
+typedef void (*lttv_option_hook)(void *hook_data);
+
+void lttv_option_add(const char *long_name, const char char_name,
+ const char *description, const char *argDescription,
+ const lttv_option_type t, void *p,
+ const lttv_option_hook h, void *hook_data);
+
+
+
+#endif // OPTION_H
--- /dev/null
+#ifndef TRACESET_H
+#define TRACESET_H
+
+#include <lttv/attribute.h>
+#include <lttv/hook.h>
+
+/* A traceSet is a set of traces to be analyzed together. */
+
+typedef struct _lttv_trace_set lttv_trace_set;
+
+
+/* Trace sets may be added to, removed from and their content listed. */
+
+lttv_trace_set *lttv_trace_set_new();
+
+lttv_trace_set *lttv_trace_set_destroy(lttv_trace_set *s);
+
+void lttv_trace_set_add(lttv_trace_set *s, ltt_trace *t);
+
+unsigned lttv_trace_set_number(lttv_trace_set *s);
+
+ltt_trace *lttv_trace_set_get(lttv_trace_set *s, unsigned i);
+
+ltt_trace *lttv_trace_set_remove(lttv_trace_set *s, unsigned i);
+
+
+/* An attributes table is attached to the set and to each trace in the set. */
+
+lttv_attributes *lttv_trace_set_attributes(lttv_trace_set *s);
+
+lttv_attributes *lttv_trace_set_trace_attributes(lttv_trace_set *s,
+ unsigned i);
+
+
+/* Process the events in a trace set. Lists of hooks are provided to be
+ called before and after the trace set and each trace and tracefile.
+ For each event, a trace set filter function is called to verify if the
+ event is of interest (if it returns TRUE). If this is the case, hooks
+ are called for the event, as well as type specific hooks if applicable.
+ Any of the hooks lists and the filter may be null if not to be used. */
+
+lttv_trace_set_process(lttv_trace_set *s,
+ lttv_hooks *before_trace_set, lttv_hooks *after_trace_set,
+ char *filter, ltt_time start, ltt_time end);
+
+#endif // TRACESET_H
+
+++ /dev/null
-#ifndef ATTRIBUTE_H
-#define ATTRIBUTE_H
-
-
-#include <glib.h>
-#include <time.h>
-
-/* Attributes are used to store any value identified by a key. They are
- typically used to store state information or accumulated statistics for
- some object. Each value is accessed through a multi-component key, which
- resembles hierarchical pathnames in filesystems.
-
- The attributes may store integers, doubles or time values, in which case
- the values are created upon first access of a key and with a default
- value of 0. Pointer values are also available with a default value of NULL
- and must thus be set explicitely to user managed (statically or dynamically
- allocated) memory. */
-
-
-typedef guint32 lttv_string_id;
-
-typedef GArray _lttv_key;
-
-typedef _lttv_key lttv_key;
-
-typedef struct timespec lttv_time;
-
-
-typedef struct _lttv_attributes {
- GHashTable *ints;
- GHashTable *times;
- GHashTable *doubles;
- GHashTable *pointers;
-} lttv_attributes;
-
-
-/* A unique integer identifier represents each different string
- used as a key component. A single copy of each different string is
- stored but its usage count is incremented each time the corresponding id
- is returned by lttv_string_id_from_string. The usage count is decremented
- each time an id is released. */
-
-lttv_string_id lttv_string_id_from_string(const char *s);
-
-void lttv_string_id_release(lttv_string_id i);
-
-const char *lttv_string_id_to_string(lttv_string_id i);
-
-
-/* Keys are created and subsequently filled with key components */
-
-lttv_key *lttv_key_new();
-
-void lttv_key_destroy(lttv_key *k);
-
-/* macro to access/replace a the i th component of key k */
-
-#define lttv_key_index(k,i) _lttv_key_index(k,i)
-
-
-/* Append a new component */
-
-void lttv_key_append(lttv_key *k, lttv_string_id i);
-
-
-/* Number of components in a key */
-
-unsigned int lttv_key_number(lttv_key *k);
-
-
-/* It is also possible to create a key directly from a pathname,
- key components separated by /, (e.g., "/hooks/options/before"). */
-
-lttv_key *lttv_key_new_pathname(const char *pathname);
-
-
-/* Create a new set of attributes */
-
-lttv_attributes *lttv_attributes_new();
-
-
-/* Destroy the set of attributes including all the memory allocated
- internally for it (copies of keys, and integer, double and time
- values...). */
-
-void lttv_attributes_destroy(lttv_attributes *a);
-
-
-/* Total number of attributes in a lttv_attributes. */
-
-unsigned int lttv_attributes_number(lttv_attributes *a);
-
-
-/* Obtain a pointer to the value of the corresponding type associated with
- the specified key. New values are created on demand with 0 as initial
- value. These values are freed when the attributes set is destroyed. */
-
-int *lttv_attributes_get_integer(lttv_attributes *a, lttv_key *k);
-
-lttv_time *lttv_attributes_get_time(lttv_attributes *a, lttv_key *k);
-
-double *lttv_attributes_get_double(lttv_attributes *a, lttv_key *k);
-
-
-/* Set or get the pointer value associated with the specified key.
- NULL is returned if no pointer was set for the key. */
-
-void *lttv_attributes_get_pointer(lttv_attributes *a, lttv_key *k);
-
-void lttv_attributes_set_pointer(lttv_attributes *a, lttv_key *k, void *p);
-
-void *lttv_attributes_get_pointer_pathname(lttv_attributes *a, char *pn);
-
-void lttv_attributes_set_pointer_pathname(lttv_attributes *a,char *pn,void *p);
-
-
-/* It is often useful to copy over some elements from the source attributes
- table to the destination table. While doing so, constraints on each key
- component may be used to select the elements of interest. Finally, some
- numerical elements may need to be summed, for example summing the number
- of page faults over all processes. A flexible function to copy attributes
- may be used for all these operations.
-
- If the key of the element copied already exists in the destination
- attributes, numerical values (integer, double or time) are summed and
- pointers are replaced.
-
- The lttv_key_select_data structure specifies for each key component the
- test applied to decide to copy or not the corresponding element.
- It contains the relation to apply to each key component, the rel vector,
- and the comparison key, both of size length. To decide if an element
- should be copied, each component of its key is compared with the
- comparison key, and the relation specified for each component must
- be verified. The relation ANY is always verified and the comparison key
- component is not used. The relation NONE is only verified if the key
- examined contains fewer components than the position examined. The EQ, NE,
- LT, LE, GT, GE relations are verified if the key is long enough and the
- component satisfies the relation with respect to the comparison key.
- Finally, the CUT relation is satisfied if the key is long enough, but the
- element is copied with that component removed from its key. All the keys
- which only differ by that component become identical after being shortened
- and their numerical values are thus summed when copied. */
-
-typedef enum _lttv_key_select_relation
-{ LTTV_KEY_ANY, /* Any value is good */
- LTTV_KEY_NONE, /* No value is good, i.e. the key must be shorter */
- LTTV_KEY_EQ, /* key[n] is equal to match[n] */
- LTTV_KEY_NE, /* key[n] is not equal to match[n] */
- LTTV_KEY_LT, /* key[n] is lower than match[n] */
- LTTV_KEY_LE, /* key[n] is lower or equal than match[n] */
- LTTV_KEY_GT, /* key[n] is greater than match[n] */
- LTTV_KEY_GE, /* key[n] is greater or equal than match[n] */
- LTTV_KEY_CUT /* cut key[n], shortening the key for the copy */
-} lttv_key_select_relation;
-
-typedef struct _lttv_key_select_data
-{
- unsigned length;
- lttv_key_select_relation *rel;
- lttv_key *comparison;
-} lttv_key_select_data;
-
-void lttv_attributes_copy(lttv_attributes *src, lttv_attributes *dest,
- lttv_key_select_data d);
-
-
-/* Sometimes the attributes must be accessed in bulk, sorted in different
- ways. For this purpose they may be converted to arrays and sorted
- multiple times. The keys used in the array belong to the lttv_attributes
- object from which the array was obtained and are freed when it is
- destroyed. Each element in the array is an lttv_attribute, a structure
- containing the key, the value type, and a union containing a value of
- that type. Multiple attributes with equal keys may be possible in some
- implementations if their type differs. */
-
-
-typedef enum _lttv_attribute_type
-{ LTTV_INTEGER, LTTV_TIME, LTTV_DOUBLE, LTTV_POINTER }
-lttv_attribute_type;
-
-typedef union _lttv_value_any
-{ int i;
- lttv_time t;
- double d;
- void *p;
-} lttv_value_any;
-
-typedef struct _lttv_attribute {
- lttv_key *key;
- lttv_attribute_type t;
- lttv_value_any v;
-} lttv_attribute;
-
-
-/* Obtain all the attributes in an array */
-
-lttv_attribute *lttv_attributes_array_get(lttv_attributes *a);
-
-lttv_attribute *lttv_attribute_array_destroy(lttv_attribute *a);
-
-
-/* The sorting order is determined by the supplied comparison function.
- The comparison function must return a negative value if a < b,
- 0 if a = b, and a positive if a > b. */
-
-typedef int (*lttv_key_compare)(lttv_key *a, lttv_key *b, void *user_data);
-
-void lttv_attribute_array_sort(lttv_attribute *a, unsigned size,
- lttv_key_compare f, void *user_data);
-
-
-/* Sort in lexicographic order using the specified key components as primary,
- secondary... keys. A vector containing the key components positions is
- specified. */
-
-int lttv_attribute_array_sort_lexicographic(lttv_attribute *a, unsigned size,
- unsigned *positions, unsigned nb_positions);
-
-#endif // ATTRIBUTE_H
--- /dev/null
+/* This module inserts a hook in the program main loop. This hook processes
+ all the events in the main tracefile. */
+
+
+#include <lttv/lttv.h>
+#include <lttv/attribute.h>
+#include <lttv/hook.h>
+
+static void process_trace_set(void *hook_data, void *call_data)
+{
+ int i, nb;
+ lttv_attributes *a, *sa;
+ lttv_trace_set *s;
+ lttv_hooks *global_before, *before, *global_after, *after;
+ ltt_time start, end;
+ lttv_key *key;
+ lttv_hook f;
+ void *hook_data;
+
+ a = lttv_global_attributes();
+ global_before = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,
+ "hooks/trace_set/before");
+ global_after = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,
+ "hooks/trace_set/after");
+ s = (lttv_trace_set *)lttv_attributes_get_pointer_pathname(a,
+ "traceSet/main");
+
+ key = lttv_key_new_pathname("time/start");
+ start = lttv_attributes_get_time(a,key);
+ lttv_key_destroy(key);
+
+ key = lttv_key_new_pathname("time/end");
+ end = lttv_attributes_get_time(a,key);
+ lttv_key_destroy(key);
+
+ sa = lttv_trace_set_attributes(s);
+
+ before = (lttv_hooks *)lttv_attributes_get_pointer_pathname(sa,
+ "hooks/before");
+ if(before == NULL) {
+ before = lttv_hooks_new();
+ lttv_attributes_set_pointer_pathname(sa, "hooks/before", before);
+ }
+
+ after = (lttv_hooks *)lttv_attributes_get_pointer_pathname(sa,
+ "hooks/after");
+ if(after == NULL) {
+ after = lttv_hooks_new();
+ lttv_attributes_set_pointer_pathname(sa, "hooks/after", after);
+ }
+
+ nb = lttv_hooks_number(global_before);
+ for(i = 0 ; i < nb ; i++) {
+ lttv_hooks_get(global_before, i, &f, &hook_data);
+ lttv_hooks_add(before, f, hook_data);
+ }
+
+ nb = lttv_hooks_number(global_after);
+ for(i = 0 ; i < nb ; i++) {
+ lttv_hooks_get(global_after, i, &f, &hook_data);
+ lttv_hooks_add(after, f, hook_data);
+ }
+
+ lttv_trace_set_process(s, before_trace_set, after_trace_set, filter, start,
+ end);
+
+ nb = lttv_hooks_number(global_before);
+ for(i = 0 ; i < nb ; i++) {
+ lttv_hooks_get(global_before, i, &f, &hook_data);
+ lttv_hooks_remove(before, f, hook_data);
+ }
+
+ nb = lttv_hooks_number(global_after);
+ for(i = 0 ; i < nb ; i++) {
+ lttv_hooks_get(global_after, i, &f, &hook_data);
+ lttv_hooks_remove(after, f, hook_data);
+ }
+}
+
+
+void init(int argc, char **argv)
+{
+ lttv_attributes *a;
+ lttv_hooks *h;
+
+ a = lttv_global_attributes();
+ h = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,"hooks/main");
+ lttv_hooks_add(h, process_trace_set, NULL);
+}
+
+
+void destroy()
+{
+ lttv_attributes *a;
+ lttv_hooks *h;
+
+ a = lttv_global_attributes();
+ h = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,"hooks/main");
+ lttv_hooks_remove(h, process_trace_set, NULL);
+}
+
+
+
+
--- /dev/null
+/* The countEvents module accumulates data for various basic reports
+
+ Not only does it count the events for each event type, it also tracks
+ the current state (current process and user/system mode) in order to
+ categorize accordingly the event counts. */
+
+void init(int argc, char **argv)
+{
+ lttv_attributes *a;
+ lttv_hooks *before, *after;
+
+ a = lttv_global_attributes();
+ before = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,
+ "hooks/trace_set/before");
+ after = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,
+ "hooks/trace_set/after");
+ lttv_hooks_add(before, countEvents_trace_set_before, NULL);
+ lttv_hooks_add(after, countEvents_trace_set_after, NULL);
+}
+
+
+void destroy()
+{
+ lttv_attributes *a;
+ lttv_hooks *before, *after;
+
+ a = lttv_global_attributes();
+ before = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,
+ "hooks/trace_set/before");
+ after = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,
+ "hooks/trace_set/after");
+ lttv_hooks_remove(before, countEvents_trace_set_before, NULL);
+ lttv_hooks_remove(after, countEvents_trace_set_after, NULL);
+}
+
+
+/* Insert the hooks before and after each trace and tracefile */
+
+typedef struct _trace_context {
+ unsigned nb_cpu;
+ struct cpu_context *cpus;
+ lttv_attributes *processes;
+ lttv_key *key;
+ lttv_attributes *event_counts;
+ lttv_attributes *trace_attributes;
+} trace_context;
+
+static bool countEvents_trace_set_before(void *hook_data, void *call_data)
+{
+ int i, j, nb, nbtf;
+ lttv_trace_set *s;
+ lttv_attributes *a;
+ trace_context *c;
+
+ s = (lttv_trace_set *)call_data;
+
+ /* For each trace prepare the contexts and insert the hooks */
+
+ nb = lttv_trace_set_number(s);
+ for(i = 0 ; i < nb ; i++) {
+ c = g_new(trace_context);
+ a = lttv_trace_set_trace_attributes(s, i);
+
+ if(lttv_attributes_get_pointer_pathname(a, "countEvents/context") != NULL){
+ g_error("Recursive call to TextDump");
+ }
+
+ lttv_attributes_set_pointer_pathname(a, "countEvents/context", c);
+
+ h = lttv_attributes_get_hooks(a, "hooks/before");
+ lttv_hooks_add(h, countEvents_trace_before, c);
+ h = lttv_attributes_get_hooks(a, "hooks/after");
+ lttv_hooks_add(h, countEvents_trace_after, c);
+ h = lttv_attributes_get_hooks(a, "hooks/tacefile/before");
+ lttv_hooks_add(h, countEvents_tracefile_before, c);
+ h = lttv_attributes_get_hooks(a, "hooks/tracefile/after");
+ lttv_hooks_add(h, countEvents_tracefile_after, c);
+ h = lttv_attributes_get_hooks(a, "hooks/event/selected");
+ lttv_hooks_add(h, couneEvents_event, c);
+ }
+
+ return TRUE;
+}
+
+
+/* Remove the hooks before and after each trace and tracefile, and for each
+ event. Print trace set level statistics. */
+
+static bool countEvents_trace_set_after(void *hook_data, void *call_data)
+{
+ int i, j, nb, nbtf;
+ lttv_trace_set *s;
+ lttv_attributes *a;
+ trace_context *c;
+
+ s = (lttv_trace_set *)call_data;
+
+ /* Get the file pointer */
+
+ fp = (FILE *)lttv_attributes_get_pointer_pathname(ga, "textDump/file");
+
+ /* For each trace remove the hooks */
+
+ nb = lttv_trace_set_number(s);
+ for(i = 0 ; i < nb ; i++) {
+ a = lttv_trace_set_trace_attributes(s, i);
+ c = (trace_context *)lttv_attributes_get_pointer_pathname(a,
+ "textDump/context");
+ lttv_attributes_set_pointer_pathname(a, "textDump/context", NULL);
+
+ h = lttv_attributes_get_hooks(a, "hooks/before");
+ lttv_hooks_remove(h, countEvents_trace_before, c);
+ h = lttv_attributes_get_hooks(a, "hooks/after");
+ lttv_hooks_remove(h, countEvents_trace_after, c);
+ h = lttv_attributes_get_hooks(a, "hooks/tacefile/before");
+ lttv_hooks_remove(h, countEvents_tracefile_before, c);
+ h = lttv_attributes_get_hooks(a, "hooks/tracefile/after");
+ lttv_hooks_remove(h, countEvents_tracefile_after, c);
+ h = lttv_attributes_get_hooks(a, "hooks/event/selected");
+ lttv_hooks_remove(h, countEvents_event, c);
+ g_free(c);
+ }
+
+ /* Compute statistics for the complete trace set */
+
+ return TRUE;
+}
+
+
+static bool countEvents_trace_before(void *hook_data, void *call_data)
+{
+ ltt_trace *t;
+ trace_context *c;
+
+ c = (trace_context *)hook_data;
+ t = (ltt_trace *)call_data;
+
+ /* Initialize the context */
+
+ return TRUE;
+}
+
+
+/* Print trace level statistics */
+
+static bool countEvents_trace_after(void *hook_data, void *call_data)
+{
+ ltt_trace *t;
+ trace_context *c;
+
+ c = (trace_context *)hook_data;
+ t = (ltt_trace *)call_data;
+
+ /* Sum events in different ways for the whole trace */
+
+ return TRUE;
+}
+
+
+static bool countEvents_tracefile_before(void *hook_data, void *call_data)
+{
+ ltt_tracefile *tf;
+ trace_context *c;
+
+ c = (trace_context *)hook_data;
+ tf = (ltt_tracefile *)call_data;
+
+ /* Nothing special to do for now */
+
+ return TRUE;
+}
+
+
+static bool countEvents_tracefile_after(void *hook_data, void *call_data)
+{
+ ltt_tracefile *tf;
+ trace_context *c;
+
+ c = (trace_context *)hook_data;
+ tf = (ltt_tracefile *)call_data;
+
+ /* Nothing special to do for now */
+
+ return TRUE;
+}
+
+
+static bool countEvents_event(void *hook_data, void *call_data)
+{
+ ltt_event *e;
+ trace_context *c;
+ unsigned cpu;
+ unsigned eventtype;
+ ltt_time t;
+
+ e = (ltt_event *)call_data;
+ c = (event_context *)hook_data;
+
+ eventtype = ltt_event_eventtype_id(e);
+ cpu = ltt_event_cpu_id(e);
+ time = ltt_event_time(e);
+
+ /* Accumulate the CPU time spent in that state */
+
+ key = c->cpu[cpu].key;
+ last_time = c->cpu[cpu].last_time;
+ c->cpu[cpu].last_time; = time;
+ lttv_key_index(key,LTTV_KEY_TYPE) = KEY_CPU;
+ total_time = lttv_attributes_time_get(c->main_attributes, key);
+
+ lttv_sub_time_value(delta_time, last_time, time);
+ lttv_add_time_valie(*total_time, *total_time, delta_time);
+
+ /* Some events indicate a state change to remember (syscall goes from user to
+ system mode, open assigns a new file to a file descriptor, exec changes
+ the memory map for the text section...) or have additional statistics
+ gathered. */
+
+ switch(c->eventtype_class[eventtype]) {
+
+ case LTTV_EVENT_SYSCALL_ENTRY:
+ n = ltt_event_get_unsigned(e,c->syscall_field)
+ push_state(c, cpu, KEY_SYSCALL, n, time);
+ /* For page faults it may be interesting to note waiting on which file */
+ break;
+
+ case LTTV_EVENT_SYSCALL_EXIT:
+ pop_state(c->cpu, cpu, KEY_SYSCALL, time);
+ break;
+
+ case LTTV_EVENT_TRAP_ENTRY:
+ n = ltt_event_get_unsigned(e,c->trap_field)
+ push_state(c, cpu, KEY_TRAP, n, time);
+ break;
+
+ case LTTV_EVENT_TRAP_EXIT:
+ pop_state(c->cpu, cpu, KEY_TRAP, time);
+ break;
+
+ case LTTV_EVENT_IRQ_ENTRY:
+ n = ltt_event_get_unsigned(e,c->irq_field)
+ push_state(c, cpu, KEY_IRQ, n, time);
+ break;
+
+ case LTTV_EVENT_IRQ_EXIT:
+ pop_state(c->cpu, cpu, KEY_IRQ, time);
+ break;
+
+
+ default:
+ }
+
+ /* The key already specifies the host, cpu, process and state, add the
+ event type and simply count one for the current event. */
+
+ lttv_key_index(key,LTTV_KEY_TYPE) = c->eventtype_key[eventtype];
+ count = lttv_attributes_get_integer(c->main_attributes, key);
+ (*count)++;
+
+ return TRUE;
+}
--- /dev/null
+
+ consist in AND, OR and NOT nested expressions, forming a tree with
+ simple relations as leaves. The simple relations test is a field
+ in an event is equal, not equal, smaller, smaller or equal, larger, or
+ larger or equal to a specified value. */
+
+typedef enum _lttv_expression_op
+{ LTTV_FIELD_EQ,
+ LTTV_FIELD_NE,
+ LTTV_FIELD_LT,
+ LTTV_FIELD_LE,
+ LTTV_FIELD_GT,
+ LTTV_FIELD_GE
+} lttv_expression_op;
+
+typedef _lttv_simple_expression
+{ lttv_expression_op op;
+ char *field_name;
+ char *value;
+} lttv_simple_expression;
+
+typedef _lttv_expression_type
+{ LTTV_EXPRESSION,
+ LTTV_SIMPLE_EXPRESSION
+
+}
+typedef struct _lttv_expression
+{ bool or;
+ bool not;
+ bool simple_expression;
+ union
+ { lttv_expression *e;
+ lttv_field_relation *se;
+ } e;
+} lttv_expression;
+
+read_token
+
+read_expression
+ ( read expr )
+ simple expr [ op expr ]
+
+read_simple_expression
+ read_field_path [ rel value ]
+
+read_field_path
+ read_field_component [. field path]
+
+read_field_component
+ name [ \[ value \] ]
+
+data struct:
+and/or(left/right)
+not(child)
+op(left/right)
+path(component...) -> field
+
+
+++ /dev/null
-#ifndef LTTV_H
-#define LTTV_H
-
-#include "attribute.h"
-
-/* Initial draft by Michel Dagenais May 2003
- * Reworked by Mathieu Desnoyers, May 2003
- */
-
-
-/* The modules in the visualizer communicate with the main module and
- with each other through attributes. There is a global set of attributes as
- well as attributes attached to each trace set, trace and tracefile. */
-
-lttv_attributes *lttv_global_attributes();
-
-
-
-/* Modules are allowed to define new command line options.
-
- Each option has a long name (--long_name), a short one character
- name (-c), a descriptive text, the argument type, and a
- pointer to where the argument value will be stored. For an option of
- type LTTV_OPT_NONE, the argument is a boolean value set to true when the
- option is present. */
-
-/* Those are already in option.h, cause conflict */
-//typedef enum _lttv_option_type
-//{LTTV_OPT_NONE, LTTV_OPT_STRING, LTTV_OPT_INT, LTTV_OPT_LONG }
-//lttv_option_type;
-
-
-//void lttv_option_add(char *long_name, char char_name, char *description,
-// lttv_option_type t, void *p);
-
-
-
-/* A number of global attributes are initialized before modules are
- loaded, for example hooks lists. More global attributes are defined
- in individual mudules to store information or to communicate with other
- modules (GUI windows, menus...).
-
- The hooks lists (lttv_hooks) are initialized in the main module and may be
- used by other modules. Each corresponds to a specific location in the main
- module processing loop. The attribute key and typical usage for each
- is indicated.
-
- /hooks/options/before
- Good place to define new command line options to be parsed.
-
- /hooks/options/after
- Read the values set by the command line options.
-
- /hooks/trace_set/before
- Before any analysis.
-
- /hooks/trace_set/after
- After all traces were analyzed.
-
- /hooks/trace/before
- Before each trace.
-
- /hooks/trace/after
- After each trace.
-
- /hooks/tracefile/before
- Before each tracefile.
-
- /hooks/tracefile/after
- After each tracefile.
-
- /hooks/event
- Called for each event
-
- /hooks/event_id
- This attribute contains an lttv_hooks_by_id, where the hooks for each
- id are to be called when an event of the associated type are found.
-
-*/
-
-#endif // LTTV_H
+++ /dev/null
-#ifndef OPTION_H
-#define OPTION_H
-
-/* Options parsing mechanism */
-
-/* Define a new command line option with a long name (--long_name), a short
- one character name (-c), a descriptive text, the argument type, and a
- pointer to where the argument value will be stored. For an option of
- type LTTV_OPT_NONE, the argument is a boolean value set to true when the
- option is present. */
-
-/* Initial draft by Michel Dagenais May 2003
- * Reworked by Mathieu Desnoyers, May 2003
- */
-
-typedef enum _lttv_option_type
-{LTTV_OPT_NONE, LTTV_OPT_STRING, LTTV_OPT_INT, LTTV_OPT_LONG }
-lttv_option_type;
-
-typedef void (*lttv_option_hook)(void *hook_data);
-
-void lttv_option_add(const char *long_name, const char char_name,
- const char *description, const char *argDescription,
- const lttv_option_type t, void *p,
- const lttv_option_hook h, void *hook_data);
-
-
-
-#endif // OPTION_H
--- /dev/null
+/* The text dump facility needs to print headers before the trace set and
+ before each trace, to print each event, and to print statistics
+ after each trace. */
+
+void init(int argc, char **argv)
+{
+ lttv_attributes *a;
+ lttv_hooks *before, *after;
+
+ a = lttv_global_attributes();
+ before = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,
+ "hooks/trace_set/before");
+ after = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,
+ "hooks/trace_set/after");
+ lttv_hooks_add(before, textDump_trace_set_before, NULL);
+ lttv_hooks_add(after, textDump_trace_set_after, NULL);
+}
+
+
+void destroy()
+{
+ lttv_attributes *a;
+ lttv_hooks *before, *after;
+
+ a = lttv_global_attributes();
+ before = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,
+ "hooks/trace_set/before");
+ after = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,
+ "hooks/trace_set/after");
+ lttv_hooks_remove(before, textDump_trace_set_before, NULL);
+ lttv_hooks_remove(after, textDump_trace_set_after, NULL);
+}
+
+/* Insert the hooks before and after each trace and tracefile, and for each
+ event. Print a global header. */
+
+typedef struct _trace_context {
+ g_string s;
+ FILE *fp;
+ bool mandatory_fields;
+ lttv_attributes *a;
+} trace_context;
+
+static bool textDump_trace_set_before(void *hook_data, void *call_data)
+{
+ FILE *fp;
+ int i, j, nb, nbtf;
+ lttv_trace_set *s;
+ lttv_attributes *a;
+ trace_context *c;
+
+ a = lttv_global_attributes();
+ s = (lttv_trace_set *)call_data
+
+ /* Get the file pointer */
+
+ fp = (FILE *)lttv_attributes_get_pointer_pathname(a, "textDump/file");
+
+ /* For each trace prepare the contexts and insert the hooks */
+
+ nb = lttv_trace_set_number(s);
+ for(i = 0 ; i < nb ; i++) {
+ c = g_new(trace_context);
+ a = lttv_trace_set_trace_attributes(s, i);
+
+ if(lttv_attributes_get_pointer_pathname(a, "textDump/context") != NULL) {
+ g_error("Recursive call to TextDump");
+ }
+
+ c->fp = fp;
+ c->mandatory_fields = TRUE;
+ c->s = g_string_new();
+ c->a = a;
+
+ lttv_attributes_set_pointer_pathname(a, "textDump/context", c);
+
+ h = lttv_attributes_get_hooks(a, "hooks/before");
+ lttv_hooks_add(h, textDump_trace_before, c);
+ h = lttv_attributes_get_hooks(a, "hooks/after");
+ lttv_hooks_add(h, textDump_trace_after, c);
+ h = lttv_attributes_get_hooks(a, "hooks/tacefile/before");
+ lttv_hooks_add(h, textDump_tracefile_before, c);
+ h = lttv_attributes_get_hooks(a, "hooks/tracefile/after");
+ lttv_hooks_add(h, textDump_tracefile_after, c);
+ h = lttv_attributes_get_hooks(a, "hooks/event/selected");
+ lttv_hooks_add(h, textDump_event, c);
+ }
+
+ /* Print the trace set header */
+ fprintf(fp,"Trace set contains %d traces\n\n", nb);
+
+ return TRUE;
+}
+
+
+/* Remove the hooks before and after each trace and tracefile, and for each
+ event. Print trace set level statistics. */
+
+static bool textDump_trace_set_after(void *hook_data, void *call_data)
+{
+ FILE *fp;
+ int i, j, nb, nbtf;
+ lttv_trace_set *s;
+ lttv_attributes *ga, *a;
+ trace_context *c;
+
+ ga = lttv_global_attributes();
+ s = (lttv_trace_set *)lttv_attributes_get_pointer_pathname(ga,
+ "trace_set/main");
+
+ /* Get the file pointer */
+
+ fp = (FILE *)lttv_attributes_get_pointer_pathname(ga, "textDump/file");
+
+ /* For each trace remove the hooks */
+
+ nb = lttv_trace_set_number(s);
+ for(i = 0 ; i < nb ; i++) {
+ a = lttv_trace_set_trace_attributes(s, i);
+ c = (trace_context *)lttv_attributes_get_pointer_pathname(a,
+ "textDump/context");
+ lttv_attributes_set_pointer_pathname(a, "textDump/context", NULL);
+ g_string_free(c->s);
+
+ h = lttv_attributes_get_hooks(a, "hooks/before");
+ lttv_hooks_remove(h, textDump_trace_before, c);
+ h = lttv_attributes_get_hooks(a, "hooks/after");
+ lttv_hooks_remove(h, textDump_trace_after, c);
+ h = lttv_attributes_get_hooks(a, "hooks/tacefile/before");
+ lttv_hooks_remove(h, textDump_tracefile_before, c);
+ h = lttv_attributes_get_hooks(a, "hooks/tracefile/after");
+ lttv_hooks_remove(h, textDump_tracefile_after, c);
+ h = lttv_attributes_get_hooks(a, "hooks/event/selected");
+ lttv_hooks_remove(h, textDump_event, c);
+ g_free(c);
+ }
+
+ /* Print the trace set statistics */
+
+ fprintf(fp,"Trace set contains %d traces\n\n", nb);
+
+ print_stats(fp, ga);
+
+ return TRUE;
+}
+
+
+/* Print a trace level header */
+
+static bool textDump_trace_before(void *hook_data, void *call_data)
+{
+ ltt_trace *t;
+ trace_context *c;
+
+ c = (trace_context *)hook_data;
+ t = (ltt_trace *)call_data;
+ fprintf(c->fp,"Start trace\n");
+ return TRUE;
+}
+
+
+/* Print trace level statistics */
+
+static bool textDump_trace_after(void *hook_data, void *call_data)
+{
+ ltt_trace *t;
+ trace_context *c;
+
+ c = (trace_context *)hook_data;
+ t = (ltt_trace *)call_data;
+ fprintf(c->fp,"End trace\n");
+ print_stats(c->fp,c->a);
+ return TRUE;
+}
+
+
+static bool textDump_tracefile_before(void *hook_data, void *call_data)
+{
+ ltt_tracefile *tf;
+ trace_context *c;
+
+ c = (trace_context *)hook_data;
+ tf = (ltt_tracefile *)call_data;
+ fprintf(c->fp,"Start tracefile\n");
+ return TRUE;
+}
+
+
+static bool textDump_tracefile_after(void *hook_data, void *call_data)
+{
+ ltt_tracefile *tf;
+ trace_context *c;
+
+ c = (trace_context *)hook_data;
+ tf = (ltt_tracefile *)call_data;
+ fprintf(c->fp,"End tracefile\n");
+ return TRUE;
+}
+
+
+/* Print the event content */
+
+static bool textDump_event(void *hook_data, void *call_data)
+{
+ ltt_event *e;
+ trace_context *c;
+
+ e = (ltt_event *)call_data;
+ c = (event_context *)hook_data;
+ lttv_event_to_string(e,c->s,c->mandatory_fields);
+ fputs(s, c->fd);
+ return TRUE;
+}
+
+
+static void print_stats(FILE *fp, lttv_attributes *a)
+{
+ int i, j, k, nb, nbc;
+
+ lttv_attributes *sa, *ra;
+ lttv_attribute *reports, *content;
+ lttv_key *key, *previous_key, null_key;
+
+ null_key = lttv_key_new_pathname("");
+ sa = (lttv_attributes *)lttv_attributes_get_pointer_pathname(a,"stats");
+ reports = lttv_attributes_array_get(sa);
+ nb= lttv_attributes_number(sa);
+
+ for(i = 0 ; i < nb ; i++) {
+ ra = (lttv_attributes *)reports[i].v.p;
+ key = reports[i].key;
+ g_assert(reports[i].t == LTTV_POINTER);
+
+ /* CHECK maybe have custom handlers registered for some specific reports */
+
+ print_key(fp,key);
+
+ content = lttv_attributes_array_get(ra);
+ nbc = lttv_attributes_number(ra);
+ lttv_attribute_array_sort_lexicographic(content, nbc, NULL, 0);
+ previous_key = nullKey;
+ for(j = 0 ; j < nbc ; j++) {
+ key = content[j].key;
+ for(k = 0 ; lttv_key_index(previous_key,k) == lttv_index(key,k) ; k++)
+ for(; k < lttv_key_number(key) ; k++) {
+ for(l = 0 ; l < k ; l++) fprintf(fp," ");
+ fprintf(fp, "%s", lttv_string_id_to_string(lttv_index(key,k)));
+ if(k == lttv_key_number(key)) {
+ switch(content[j].t) {
+ case LTTV_INTEGER:
+ fprintf(fp," %d\n", content[j].v.i);
+ break;
+ case LTTV_TIME:
+ fprintf(fp," %d.%09d\n", content[j].v.t.tv_sec,
+ content[j].v.t.tv_nsec);
+ break;
+ case LTTV_DOUBLE:
+ fprintf(fp," %g\n", content[j].v.d);
+ break;
+ case LTTV_POINTER:
+ fprintf(fp," pointer\n");
+ break;
+ }
+ }
+ else fprintf(fp,"\n");
+ }
+ }
+ lttv_attribute_array_destroy(content);
+ }
+ lttv_attribute_array_destroy(reports);
+ lttv_key_destroy(null_key);
+}
+
+
+void lttv_event_to_string(ltt_event *e, lttv_string *s, bool mandatory_fields)
+{
+ ltt_facility *facility;
+ ltt_eventtype *eventtype;
+ ltt_type *type;
+ ltt_field *field;
+ ltt_time time;
+
+ g_string_set_size(s,0);
+
+ facility = lttv_event_facility(e);
+ eventtype = ltt_event_eventtype(e);
+ field = ltt_event_field(e);
+
+ if(mandatory_fields) {
+ time = ltt_event_time(e);
+ g_string_append_printf(s,"%s.%s: %ld.%ld",ltt_facility_name(facility),
+ ltt_eventtype_name(eventtype), (long)time.tv_sec, time.tv_nsec);
+ }
+
+ print_field(e,f,s);
+}
+
+void print_field(ltt_event *e, ltt_field *f, lttv_string *s) {
+ ltt_type *type;
+ ltt_field *element;
+
+ int nb, i;
+
+ type = ltt_field_type(f);
+ switch(ltt_type_class(type)) {
+ case LTT_INT:
+ g_string_append_printf(s, " %ld", ltt_event_get_long_int(e,f));
+ break;
+
+ case LTT_UINT:
+ g_string_append_printf(s, " %lu", ltt_event_get_long_unsigned(e,f));
+ break;
+
+ case LTT_FLOAT:
+ g_string_append_printf(s, " %g", ltt_event_get_double(e,f));
+ break;
+
+ case LTT_STRING:
+ g_string_append_printf(s, " \"%s\"", ltt_event_get_string(e,f));
+ break;
+
+ case LTT_ENUM:
+ g_string_append_printf(s, " %s", ltt_enum_string_get(type,
+ event_get_unsigned(e,f));
+ break;
+
+ case LTT_ARRAY:
+ case LTT_SEQUENCE:
+ g_string_append_printf(s, " {");
+ nb = ltt_event_field_element_number(e,f);
+ element = ltt_field_element(f);
+ for(i = 0 ; i < nb ; i++) {
+ ltt_event_field_element_select(e,f,i);
+ print_field(e,element,s);
+ }
+ g_string_append_printf(s, " }");
+ break;
+
+ case LTT_STRUCT:
+ g_string_append_printf(s, " {");
+ nb = ltt_type_member_number(type);
+ for(i = 0 ; i < nb ; i++) {
+ element = ltt_field_member(f,i);
+ print_field(e,element,s);
+ }
+ g_string_append_printf(s, " }");
+ break;
+ }
+}
+
+
+
+
+++ /dev/null
-#ifndef TRACESET_H
-#define TRACESET_H
-
-#include <lttv/attribute.h>
-#include <lttv/hook.h>
-
-/* A traceSet is a set of traces to be analyzed together. */
-
-typedef struct _lttv_trace_set lttv_trace_set;
-
-
-/* Trace sets may be added to, removed from and their content listed. */
-
-lttv_trace_set *lttv_trace_set_new();
-
-lttv_trace_set *lttv_trace_set_destroy(lttv_trace_set *s);
-
-void lttv_trace_set_add(lttv_trace_set *s, ltt_trace *t);
-
-unsigned lttv_trace_set_number(lttv_trace_set *s);
-
-ltt_trace *lttv_trace_set_get(lttv_trace_set *s, unsigned i);
-
-ltt_trace *lttv_trace_set_remove(lttv_trace_set *s, unsigned i);
-
-
-/* An attributes table is attached to the set and to each trace in the set. */
-
-lttv_attributes *lttv_trace_set_attributes(lttv_trace_set *s);
-
-lttv_attributes *lttv_trace_set_trace_attributes(lttv_trace_set *s,
- unsigned i);
-
-
-/* Process the events in a trace set. Lists of hooks are provided to be
- called before and after the trace set and each trace and tracefile.
- For each event, a trace set filter function is called to verify if the
- event is of interest (if it returns TRUE). If this is the case, hooks
- are called for the event, as well as type specific hooks if applicable.
- Any of the hooks lists and the filter may be null if not to be used. */
-
-lttv_trace_set_process(lttv_trace_set *s,
- lttv_hooks *before_trace_set, lttv_hooks *after_trace_set,
- char *filter, ltt_time start, ltt_time end);
-
-#endif // TRACESET_H
-