From 1b82f325932b2d092d1e0ff33f58afd9ede44d72 Mon Sep 17 00:00:00 2001 From: dagenais Date: Mon, 9 Jun 2003 20:30:14 +0000 Subject: [PATCH] Adjust the ltt API to reflect that facilities, types and fields belong to traces, not tracefiles. Refine the modularization of traces processing and statistics computation. git-svn-id: http://ltt.polymtl.ca/svn@90 04897980-b3bd-0310-b5e0-8ef037075253 --- ltt/branches/poly/include/ltt/event.h | 6 +- ltt/branches/poly/include/ltt/facility.h | 20 +- ltt/branches/poly/include/ltt/ltt.h | 44 ++-- ltt/branches/poly/include/ltt/trace.h | 100 ++++++++ ltt/branches/poly/include/ltt/tracefile.h | 107 --------- ltt/branches/poly/include/ltt/type.h | 25 +- ltt/branches/poly/include/lttv/hook.h | 14 +- ltt/branches/poly/lttv/attribute.h | 82 +++++-- ltt/branches/poly/lttv/plugins/analyse.c | 90 ------- ltt/branches/poly/lttv/plugins/asciiDump.c | 217 ----------------- ltt/branches/poly/lttv/plugins/basicStats.c | 246 -------------------- ltt/branches/poly/lttv/plugins/textDump.c | 98 -------- ltt/branches/poly/lttv/trace.c | 136 ----------- ltt/branches/poly/lttv/trace.h | 80 ------- ltt/branches/poly/lttv/traceSet.c | 178 ++++++++++++++ ltt/branches/poly/lttv/traceSet.h | 47 ++++ 16 files changed, 453 insertions(+), 1037 deletions(-) create mode 100644 ltt/branches/poly/include/ltt/trace.h delete mode 100644 ltt/branches/poly/include/ltt/tracefile.h delete mode 100644 ltt/branches/poly/lttv/plugins/analyse.c delete mode 100644 ltt/branches/poly/lttv/plugins/asciiDump.c delete mode 100644 ltt/branches/poly/lttv/plugins/basicStats.c delete mode 100644 ltt/branches/poly/lttv/plugins/textDump.c delete mode 100644 ltt/branches/poly/lttv/trace.c delete mode 100644 ltt/branches/poly/lttv/trace.h create mode 100644 ltt/branches/poly/lttv/traceSet.c create mode 100644 ltt/branches/poly/lttv/traceSet.h diff --git a/ltt/branches/poly/include/ltt/event.h b/ltt/branches/poly/include/ltt/event.h index d525cbb5..a9f511f1 100644 --- a/ltt/branches/poly/include/ltt/event.h +++ b/ltt/branches/poly/include/ltt/event.h @@ -9,7 +9,7 @@ the memory associated with an event may be reused at each read. */ -/* Obtain the tracefile unique integer id associated with the type of +/* Obtain the trace unique integer id associated with the type of this event */ unsigned ltt_event_eventtype_id(ltt_event *e); @@ -21,8 +21,12 @@ ltt_facility *ltt_event_facility(ltt_event *e); ltt_eventtype *ltt_event_eventtype(ltt_event *e); + +/* Root field for the event */ + ltt_field *ltt_event_field(ltt_event *e); + /* Time and cycle count for the event */ ltt_time ltt_event_time(ltt_event *e); diff --git a/ltt/branches/poly/include/ltt/facility.h b/ltt/branches/poly/include/ltt/facility.h index 89c997de..f322fa89 100644 --- a/ltt/branches/poly/include/ltt/facility.h +++ b/ltt/branches/poly/include/ltt/facility.h @@ -3,17 +3,9 @@ #include -/* A facility is obtained from a .event file containing event type - declarations. The facility content must have the specified checksum. - The structures associated with a facility may be released with - a call to ltt_close_facility if its usage count is 0. */ - -ltt_facility *ltt_facility_open(char *pathname, ltt_checksum c); - -int ltt_facility_close(ltt_facility *f); - - -/* Obtain the name and checksum of the facility */ +/* Facilities are obtained from an opened trace. The structures associated + with a facility are released when the trace is closed. Each facility + is characterized by its name and checksum. */ char *ltt_facility_name(ltt_facility *f); @@ -21,7 +13,11 @@ ltt_checksum ltt_facility_checksum(ltt_facility *f); /* Discover the event types within the facility. The event type integer id - used here is specific to the trace (from 0 to nb_event_types - 1). */ + relative to the trace is from 0 to nb_event_types - 1. The event + type id within the trace is the relative id + the facility base event + id. */ + +unsigned ltt_facility_base_id(ltt_facility *f); unsigned ltt_facility_eventtype_number(ltt_facility *f); diff --git a/ltt/branches/poly/include/ltt/ltt.h b/ltt/branches/poly/include/ltt/ltt.h index 2208b925..75700530 100644 --- a/ltt/branches/poly/include/ltt/ltt.h +++ b/ltt/branches/poly/include/ltt/ltt.h @@ -6,10 +6,10 @@ multi-cpu, system. It is defined as a pathname to a directory containing all the relevant trace files. All the tracefiles for a trace were generated in a single system for the same time period by the same - trace daemon. They simply contain different events. Typically one file - contains the important events (process creations and registering tracing - facilities) for all CPUs, and one file for each CPU contains all the - events for that CPU. All the tracefiles within the same trace directory + trace daemon. They simply contain different events. Typically a "control" + tracefile contains the important events (process creations and registering + tracing facilities) for all CPUs, and one file for each CPU contains all + the events for that CPU. All the tracefiles within the same trace directory then use the exact same id numbers for event types. A tracefile (ltt_tracefile) contains a list of events (ltt_event) sorted @@ -20,15 +20,12 @@ A facility is a list of event types (ltt_eventtype), declared in a special .event file. An associated checksum differentiates different facilities which would have the same name but a different content (e.g., different - versions). - - The list of facilities (and associated checksum) used in a tracefile + versions). The .event files are stored within the trace directory, or + in the default path, and are accessed automatically upon opening a trace. + The list of facilities (and associated checksum) used in a trace must be known in order to properly decode the contained events. An event - is usually stored in the trace to denote each different "facility used". - While many facilities may be present when the trace starts, new - facilities may be introduced later as kernel modules are loaded. - This is fine as long as the "facility used" event precedes any event - described in that facility. + is usually stored in the "control" tracefile to denote each different + "facility used". Event types (ltt_eventtype) refer to data types (ltt_type) describing their content. The data types supported are integer and unsigned integer @@ -40,15 +37,17 @@ An ltt_field is a special object to denote a specific, possibly nested, field within an event type. Suppose an event type socket_connect is a - structure containing two data membes, source and destination, of type + structure containing two data members, source and destination, of type socket_address. Type socket_address contains two unsigned integer data members, ip and port. An ltt_field is different from a data type structure member since it can denote a specific nested field, like the source port, and store associated access information (byte offset within - the event data). The ltt_field objects are tracefile specific since the + the event data). The ltt_field objects are trace specific since the contained information (byte offsets) may vary with the architecture - associated to the tracefile. */ + associated to the trace. */ +typedef struct _ltt_trace ltt_trace; + typedef struct _ltt_tracefile ltt_tracefile; typedef struct _ltt_facility ltt_facility; @@ -62,14 +61,6 @@ typedef struct _ltt_field ltt_field; typedef struct _ltt_event ltt_event; -/* Different types allowed */ - -typedef enum _ltt_type_enum -{ LTT_INT, LTT_UINT, LTT_FLOAT, LTT_STRING, LTT_ENUM, LTT_ARRAY, - LTT_SEQUENCE, LTT_STRUCT -} ltt_type_enum; - - /* Checksums are used to differentiate facilities which have the same name but differ. */ @@ -86,10 +77,17 @@ typedef struct timespec ltt_time; typedef uint64_t ltt_cycle_count; + +/* Differences between architectures include word sizes, endianess, + alignment, floating point format and calling conventions. For a + packed binary trace, endianess and size matter, assuming that the + floating point format is standard (and is seldom used anyway). */ + typedef enum _ltt_arch_size { LTT_LP32, LTT_ILP32, LTT_LP64, LTT_ILP64, LTT_UNKNOWN } ltt_arch_size; + typedef enum _ltt_arch_endian { LTT_LITTLE_ENDIAN, LTT_BIG_ENDIAN } ltt_arch_endian; diff --git a/ltt/branches/poly/include/ltt/trace.h b/ltt/branches/poly/include/ltt/trace.h new file mode 100644 index 00000000..0aa69f5c --- /dev/null +++ b/ltt/branches/poly/include/ltt/trace.h @@ -0,0 +1,100 @@ +#ifndef TRACEFILE_H +#define TRACEFILE_H + +#include + +/* A trace is specified as a pathname to the directory containing all the + associated data (control tracefile, per cpu tracefiles, event + descriptions...). + + When a trace is closed, all the associated facilities, types and fields + are released as well. */ + +ltt_trace *ltt_trace_open(char *pathname); + +void ltt_trace_close(ltt_trace *t); + + +/* A trace may be queried for its architecture type (e.g., "i386", + "powerpc", "powerpcle", "s390", "s390x"), its architecture variant + (e.g., "att" versus "sun" for m68k), its operating system (e.g., "linux", + "bsd"), its generic architecture, and the machine identity (e.g., system + host name). All character strings belong to the associated tracefile + and are freed when it is closed. */ + + +char *ltt_tracefile_arch_type(ltt_trace *t); + +char *ltt_tracefile_arch_variant(ltt_trace *t); + +char *ltt_tracefile_system_type(ltt_trace *t); + +ltt_arch_size ltt_tracefile_arch_size(ltt_trace *t); + +ltt_arch_endian ltt_tracefile_arch_endian(ltt_trace *t); + + +/* Hostname of the system where the trace was recorded */ + +char *ltt_trace_system_name(ltt_tracefile *t); + + +/* SMP multi-processors have 2 or more CPUs */ + +unsigned ltt_trace_cpu_number(ltt_trace *t); + + +/* Start and end time of the trace and its duration */ + +ltt_time ltt_tracefile_time_start(ltt_trace *t); + +ltt_time ltt_tracefile_time_end(ltt_trace *t); + +ltt_time ltt_tracefile_duration(ltt_tracefile *t); + + +/* Functions to discover the facilities in the trace */ + +unsigned ltt_trace_facility_number(ltt_trace *t); + +ltt_facility *ltt_trace_facility_get(ltt_trace *t, unsigned i); + +ltt_facility *ltt_trace_facility_get_by_name(ltt_trace *t, char *name); + + +/* Functions to discover all the event types in the trace */ + +unsigned ltt_trace_eventtype_number(ltt_tracefile *t); + +ltt_eventtype *ltt_trace_eventtype_get(ltt_tracefile *t, unsigned i); + + +/* A trace typically contains one "control" tracefile with important events + (for all CPUs), and one tracefile with ordinary events per cpu. + The tracefiles in a trace may be enumerated for each category + (all cpu and per cpu). The total number of tracefiles and of CPUs + may also be obtained. */ + +unsigned int ltt_trace_tracefile_number(ltt_trace *t); + +unsigned int ltt_trace_tracefile_number_per_cpu(ltt_trace *t); + +unsigned int ltt_trace_tracefile_number_all_cpu(ltt_trace *t); + +ltt_tracefile *ltt_trace_tracefile_get_per_cpu(ltt_trace *t, unsigned i); + +ltt_tracefile *ltt_trace_tracefile_get_all_cpu(ltt_trace *t, unsigned i); + +char *ltt_tracefile_name(ltt_tracefile *tf); + + +/* Seek to the first event of the trace with time larger or equal to time */ + +int ltt_tracefile_seek_time(ltt_tracefile *t, ltt_time time); + + +/* Read the next event */ + +ltt_event *ltt_tracefile_read(ltt_tracefile *t); + +#endif // TRACE_H diff --git a/ltt/branches/poly/include/ltt/tracefile.h b/ltt/branches/poly/include/ltt/tracefile.h deleted file mode 100644 index 79a9dcfa..00000000 --- a/ltt/branches/poly/include/ltt/tracefile.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef TRACEFILE_H -#define TRACEFILE_H - -#include - -/* A tracefile is specified as a pathname. Facilities must be added to the - tracefile to declare the type of the contained events. - - The ltt_tracefile_facility_add call increases the facility - usage count and also specifies the base of the numeric range - assigned to the event types in the facility for this tracefile. - This information is normally obtained through "facility used" events - stored in the tracefile. - - When a tracefile is closed, all the associated facilities may be - automatically closed as well, if their usage count is 0, when the - close_facilities argument is true. */ - -ltt_tracefile *ltt_tracefile_open(char *pathname); - -int ltt_tracefile_close(ltt_tracefile *t, int close_facilities); - -int ltt_tracefile_facility_add(ltt_tracefile *t, ltt_facility *f, int base_id); - - -/* A tracefile may be queried for its architecture type (e.g., "i386", - "powerpc", "powerpcle", "s390", "s390x"), its architecture variant - (e.g., "att" versus "sun" for m68k), its operating system (e.g., "linux", - "bsd"), its generic architecture, and the machine identity (e.g., system - host name). All character strings belong to the associated tracefile - and are freed when it is closed. */ - - -uint32_t ltt_tracefile_arch_type(ltt_tracefile *t); - -uint32_t ltt_tracefile_arch_variant(ltt_tracefile *t); - -ltt_arch_size ltt_tracefile_arch_size(ltt_tracefile *t); - -ltt_arch_endian ltt_tracefile_arch_endian(ltt_tracefile *t); - -uint32_t ltt_tracefile_system_type(ltt_tracefile *t); - -char *ltt_tracefile_system_name(ltt_tracefile *t); - - -/* SMP multi-processors have 2 or more CPUs */ - -unsigned ltt_tracefile_cpu_number(ltt_tracefile *t); - - -/* Does the tracefile contain events only for a single CPU? */ - -int ltt_tracefile_cpu_single(ltt_tracefile *t); - - -/* It this is the case, which CPU? */ - -unsigned ltt_tracefile_cpu_id(ltt_tracefile *t); - - -/* Start and end time of the trace and its duration */ - -ltt_time ltt_tracefile_time_start(ltt_tracefile *t); - -ltt_time ltt_tracefile_time_end(ltt_tracefile *t); - -ltt_time ltt_tracefile_duration(ltt_tracefile *t); - - -/* Functions to discover the facilities added to the tracefile */ - -unsigned ltt_tracefile_facility_number(ltt_tracefile *t); - -ltt_facility *ltt_tracefile_facility_get(ltt_tracefile *t, unsigned i); - -ltt_facility *ltt_tracefile_facility_get_by_name(ltt_tracefile *t, char *name); - - -/* Functions to discover all the event types in the facilities added to the - tracefile. The event type integer id, unique for the trace, is used. */ - -unsigned ltt_tracefile_eventtype_number(ltt_tracefile *t); - -ltt_eventtype *ltt_tracefile_eventtype_get(ltt_tracefile *t, unsigned i); - - -/* Given an event type, find its unique id within the tracefile */ - -unsigned ltt_tracefile_eventtype_id(ltt_tracefile *t, ltt_eventtype *et); - - -/* Get the root field associated with an event type for the tracefile */ - -ltt_field *ltt_tracefile_eventtype_root_field(ltt_tracefile *t, unsigned id); - - -/* Seek to the first event of the trace with time larger or equal to time */ - -int ltt_tracefile_seek_time(ltt_tracefile *t, ltt_time time); - - -/* Read the next event */ - -ltt_event *ltt_tracefile_read(ltt_tracefile *t); - -#endif // TRACEFILE_H diff --git a/ltt/branches/poly/include/ltt/type.h b/ltt/branches/poly/include/ltt/type.h index 822e2c34..de1fd03c 100644 --- a/ltt/branches/poly/include/ltt/type.h +++ b/ltt/branches/poly/include/ltt/type.h @@ -3,16 +3,35 @@ #include -/* All event types and data types belong to their facilities and - are released at the same time. All fields belong to their tracefile and + +/* Different types allowed */ + +typedef enum _ltt_type_enum +{ LTT_INT, LTT_UINT, LTT_FLOAT, LTT_STRING, LTT_ENUM, LTT_ARRAY, + LTT_SEQUENCE, LTT_STRUCT +} ltt_type_enum; + + +/* All event types, data types and fields belong to their trace and are released at the same time. */ +/* Obtain the name, description, facility, facility relative id, global id, + type and root field for an eventtype */ + char *ltt_eventtype_name(ltt_eventtype *et); char *ltt_eventtype_description(ltt_eventtype *et); +ltt_facility *ltt_eventtype_facility(ltt_eventtype *et); + +unsigned *ltt_eventtype_relative_id(ltt_eventtype *et); + +unsigned *ltt_eventtype_id(ltt_eventtype *et); + ltt_type *ltt_eventtype_type(ltt_eventtype *et); +ltt_field *ltt_eventtype_field(ltt_eventtype *et); + /* obtain the type name and size. The size is the number of bytes for primitive types (INT, UINT, FLOAT, ENUM), or the size for the unsigned @@ -56,7 +75,7 @@ char *ltt_enum_string_get(ltt_type *t, unsigned i); sequences simply point to one nested field representing the currently selected element among all the (identically typed) elements. For structures, a nested field exists for each data member. Each field stores the - platform/tracefile specific offset values (for efficient access) and + platform/trace specific offset values (for efficient access) and points back to the corresponding ltt_type for the rest. */ ltt_field *ltt_field_element(ltt_field *f); diff --git a/ltt/branches/poly/include/lttv/hook.h b/ltt/branches/poly/include/lttv/hook.h index 71a0a139..b5e6ed8d 100644 --- a/ltt/branches/poly/include/lttv/hook.h +++ b/ltt/branches/poly/include/lttv/hook.h @@ -7,7 +7,7 @@ call site specific data (e.g., hooks for events are called with a pointer to the current event). */ -typedef void (*lttv_hook)(void *hook_data, void *call_data); +typedef bool (*lttv_hook)(void *hook_data, void *call_data); /* A list of hooks allows registering hooks to be called later. */ @@ -21,7 +21,17 @@ void lttv_hooks_destroy(lttv_hooks *h); void lttv_hooks_add(lttv_hooks *h, lttv_hook f, void *hook_data); -void lttv_hooks_call(lttv_hooks *h, void *call_data); +void lttv_hooks_remove(lttv_hooks *h, lttv_hook f, void *hook_data); + +unsigned lttv_hooks_number(lttv_hooks *h); + +void lttv_hooks_get(lttv_hooks *h, unsigned i, lttv_hook *f, void **hook_data); + +void lttv_hooks_remove_by_position(lttv_hooks *h, unsigned i); + +bool lttv_hooks_call(lttv_hooks *h, void *call_data); + +bool lttv_hooks_call_check(lttv_hooks *h, void *call_data); /* Sometimes different hooks need to be called based on the case. The diff --git a/ltt/branches/poly/lttv/attribute.h b/ltt/branches/poly/lttv/attribute.h index b831dce5..be79a330 100644 --- a/ltt/branches/poly/lttv/attribute.h +++ b/ltt/branches/poly/lttv/attribute.h @@ -114,23 +114,54 @@ void *lttv_attributes_get_pointer_pathname(lttv_attributes *a, char *pn); void lttv_attributes_set_pointer_pathname(lttv_attributes *a,char *pn,void *p); -typedef int (*lttv_key_select)(lttv_key *in, lttv_key *out, void *user_data); - -typedef enum _lttv_key_select_action -{ LTTV_KEEP, LTTV_KEEP_EQUAL, LTTV_KEEP_SMALLER, LTTV_KEEP_GREATER, LTTV_IGNORE -} lttv_key_select_action; - -typedef struct _lttv_key_select_spec_data +/* 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_action *spec; - lttv_key *match; -} lttv_key_select_spec_data; + lttv_key_select_relation *rel; + lttv_key *comparison; +} lttv_key_select_data; -int lttv_key_select_spec(lttv_key *in, lttv_key *out, void *user_data); - -lttv_attributes *lttv_attributes_select(lttv_attributes *a, lttv_key_select f, - void *user_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 @@ -161,21 +192,28 @@ typedef struct _lttv_attribute { } lttv_attribute; -/* User defined function used to compare keys in the sort. It returns - 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); - -int lttv_key_compare_priority(lttv_key *a, lttv_key *b, void *compare_data); - - /* 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 diff --git a/ltt/branches/poly/lttv/plugins/analyse.c b/ltt/branches/poly/lttv/plugins/analyse.c deleted file mode 100644 index 178d0000..00000000 --- a/ltt/branches/poly/lttv/plugins/analyse.c +++ /dev/null @@ -1,90 +0,0 @@ - -#include - -void lttv_analyse_init() { - - -} - -void lttv_analyse_destroy() { - -} - - -void lttv_analyse_trace_set(lttv_trace_set *s) { - int i, nb; - lttv_hooks *before, *after; - lttv_attributes *a; - - a = lttv_trace_set_attributes(s); - before = (lttv_hooks*)lttv_attributes_get_pointer_pathname(a,"hooks/before"); - after = (lttv_hooks*)lttv_attributes_get_pointer_pathname(a,"hooks/after"); - nb = lttv_trace_set_number(s); - - lttv_hooks_call(before, s); - for(i = 0; i < nb; i++) { - lttv_analyse_trace(lttv_trace_set_get(s,i)); - } - lttv_hooks_call(after, s); -} - - -void lttv_analyse_trace(lttv_trace *t) { - int i, nb_all_cpu, nb_per_cpu; - lttv_hooks *before, *after; - lttv_attributes *a; - - a = lttv_trace_attributes(t); - before = (lttv_hooks*)lttv_attributes_get_pointer_pathname(a,"hooks/before"); - after = (lttv_hooks*)lttv_attributes_get_pointer_pathname(a,"hooks/after"); - - nb_all_cpu = lttv_trace_tracefile_number_all_cpu(t); - nb_per_cpu = lttv_trace_tracefile_number_per_cpu(t); - - lttv_hooks_call(before, t); - - for(i = 0; i < nb_all_cpu; i++) { - lttv_analyse_tracefile(lttv_trace_get_all_cpu(t,i)); - } - - for(i = 0; i < nb_per_cpu; i++) { - lttv_analyse_tracefile(lttv_trace_get_per_cpu(t,i)); - } - - lttv_hooks_call(after, t); -} - - -void lttv_analyse_tracefile(lttv_tracefile *t) { - ltt_tracefile *tf; - ltt_event *event; - unsigned id; - lttv_hooks *before, *after, *event_hooks; - lttv_hooks_by_id *event_hooks_by_id; - lttv_attributes *a; - - a = lttv_tracefile_attributes(t); - before = (lttv_hooks*)lttv_attributes_get_pointer_pathname(a,"hooks/before"); - after = (lttv_hooks*)lttv_attributes_get_pointer_pathname(a,"hooks/after"); - event_hooks = (lttv_hooks*)lttv_attributes_get_pointer_pathname(a, - "hooks/event"); - event_hooks_by_id = (lttv_hooks_by_id*) - lttv_attributes_get_pointer_pathname(a, "hooks/eventid"); - - tf = lttv_tracefile_ltt_tracefile(t); - - lttv_hooks_call(before, t); - - if(lttv_hooks_number(hooks_event) != 0 || - lttv_hooks_by_id_number(event_hook_by_id) != 0){ - while(event = ltt_tracefile_read(tf) != NULL) { - lttv_hooks_call(event_hooks,event); - lttv_hooks_by_id_call(event_hooks_by_id,event,ltt_event_type_id(event)); - } - } - - lttv_hooks_call(after, t); - -} - - diff --git a/ltt/branches/poly/lttv/plugins/asciiDump.c b/ltt/branches/poly/lttv/plugins/asciiDump.c deleted file mode 100644 index 143f0bca..00000000 --- a/ltt/branches/poly/lttv/plugins/asciiDump.c +++ /dev/null @@ -1,217 +0,0 @@ - -#include "ltt_module.h" - -/* This module dumps all events in a simple ascii format */ - -static gboolean - ascii_dump = FALSE, - syscall_stats = FALSE; - -static gchar *dump_file = NULL; - -static FILE *dump_fp = stdout; - -struct poptOption - ascii_dump_option = { "ascii-dump", 'd', POPT_ARG_NONE, &ascii_dump, 0}, - ascii_dump_option = { "dump-file", 'f', POPT_ARG_STRING, &dump_file, 0}, - syscall_stats_option = { "syscall-stats", 's', POPT_ARG_NONE, - &syscall_stats, 0}; - -static void after_options_hook(gpointer hook_data, gpointer call_data); - -static void before_trace_hook(gpointer hook_data, gpointer call_data); - -static void after_trace_hook(gpointer hook_data, gpointer call_data); - -static void events_hook(gpointer hook_data, gpointer call_data); - -void init(int argc, char **argv) -{ - ltt_add_command_option(&ascii_dump_option); - ltt_add_command_option(&syscall_stats_option); - ltt_add_hook(ltt_after_options_hooks,after_options_hook,NULL) -} - -/* Check the command line options and insert hooks to do the work */ - -static void after_options_hook(gpointer hook_data, gpointer call_data) -{ - if(ascii_dump_option || syscall_stats) { - ltt_add_hook(ltt_before_process_each_trace_hooks,before_trace_hook,NULL); - if(dump_file != NULL) { - dump_fp = fopen(dump_file,"w"); - if(dump_fp == NULL) g_critical("cannot open output file %s",dump_file); - } - ltt_add_hook(ltt_after_process_each_trace_hooks,after_trace_hook,NULL); - } -} - -/* Insert the hooks to print the events and compute and print the statistics */ - -static unsigned *eventsCounters; - -struct CPUState { - lttProcess *current_process; - lttStatKey *key; - lttTime lastTime; -} *CPUStates; - -static void before_trace_hook(gpointer hook_data, gpointer call_data) { - ltt_add_hook(ltt_trace_events_hooks,events_hooks,NULL); - fprintf(dump_fp,"Trace %s\n",(struct trace *)call_data->name); - - if(ascii_dump) fprintf(dump_fp,"\nEvents\n"); - - /* To gather stats, register a few hooks */ - - if(syscall_stats) { - eventsCounters = g_new0(unsigned,nbEventType); - CPUStates = g_new0(struct CPUState, nbCPU); - /* initialize the state of each CPU and associated process */ - CHECK - } -} - -/* Print the events */ - -static void events_hook(gpointer hook_data, gpointer call_data) -{ - event_struct event; - - int i; - - event = (struct_event *)call_data; - - if(ascii_dump) { - fprintf(dump_fp,"\n%s.%s t=%d.%d CPU%d",event->facility_handle->name, - event->event_handle->name, event->time.tv_seconds, - event->time.tv_nanoseconds,event->CPU_id); - - for(i = 0 ; i < event->base_field->nb_elements ; i++) { - field = event->base_field->fields + i; - fprintf(dump_fp," %s=",field->name); - switch(field->type) { - case INT: - fprintf(dump_fp,"%d",ltt_get_integer(field,event->data)); - break; - case UINT: - fprintf(dump_fp,"%u",ltt_get_uinteger(field,event->data)); - break; - case FLOAT: - fprintf(dump_fp,"%lg",ltt_get_float(field,event->data)); - break; - case DOUBLE: - fprintf(dump_fp,"%g",ltt_get_double(field,event->data)); - break; - case STRING: - fprintf(dump_fp,"%s",ltt_get_string(field,event->data)); - break; - case ENUM: - fprintf(dump_fp,"%d",ltt_get_integer(field,event->data)); - break; - case ARRAY: - fprintf(dump_fp,""); - break; - case SEQUENCE: - fprintf(dump_fp,""); - break; - case STRUCT: - fprintf(dump_fp,""); - break; - } - } - } - - /* Collect statistics about each event type */ - - if(syscall_stats) { - /* Get the key for the corresponding CPU. It already contains the - path components for the ip, CPU, process, state, subState. - We add the event id and increment the statistic with that key. */ - - key = (GQuark *)CPUStates[event->CPUid]->key1; - path = key->data; - path[5] = eventsQuark[event->id]; - pval = ltt_get_integer(currentStats,key); - (*pval)++; - - /* Count the time spent in the current state. Could be done only - at state changes to optimize. */ - - key = (GQuark *)CPUStates[event->CPUid]->key2; - path = key->data; - ptime = ltt_get_time(currentStats,key); - (*ptime) = ltt_add_time((*ptime),ltt_sub_time(lastTime,event->time)); - } -} - -/* Specific hooks to note process and state changes, compute the following values: number of bytes read/written, - time elapsed, user, system, waiting, time spent in each system call, - name for each process. */ - -maintain the process table, process state, last time... what we are waiting for - -syscall_entry_hook -syscall_exit_hook -trap_entry_hook -trap_exit_hook -irq_entry_hook -irq_exit_hook -sched_change_hook -> not waiting -fork_hook -> wait fork -wait_hook -> waiting -wakeup_hook -> not waiting add up waiting time -exit_hook -exec_hook -> note file name -open_hook -> keep track of fd/name -close_hook -> keep track of fd -read_hook -> bytes read, if server CPU for client... -write_hook -> bytes written -select_hook -> wait reason -poll_hook -> wait reason -mmap_hook -> keep track of fd -munmap_hook -> keep track of fd -setitimer_hook -> wait reason -settimeout_hook -> wait reason -sockcreate_hook -> client/server -sockbind_hook -> client/server -sockaccept_hook -> client/server -sockconnect_hook -> client/server -/* Close the output file and print the statistics, globally for all CPUs and - processes, per CPU, per process. */ - -static void after_trace_hook(gpointer hook_data, gpointer call_data) -{ - lttTrace t; - - unsigned nbEvents = 0; - - t = (lttTrace *)call_data; - - fprintf(dump_fp,"\n"); - fclose(dump_fp); - - if(syscall_stats) { - fprintf(dump_fp,"\n\nStatistics\n\n"); - - /* Trace start, end and duration */ - - fprintf(dump_fp,"Trace started %s, ended %s, duration %s", - ltt_format_time(t->startTime),ltt_format_time(t->endTime), - ltt_format_time(ltt_sub_time(t->endTime,t->startTime))); - - /* Number of events of each type */ - - for(i = 0 ; i < t->nbEventTypes ; i++) { - nbEvents += eventsCounters[i]; - if(eventsCounters[i] > 0) - fprintf(dump_fp,"%s: %u\n",t->types[i]->name,eventsCounters[i]); - } - fprintf(dump_fp,"\n\nTotal number of events: %u\n",nbEvents); - - /* Print the details for each process */ - } -} - - - diff --git a/ltt/branches/poly/lttv/plugins/basicStats.c b/ltt/branches/poly/lttv/plugins/basicStats.c deleted file mode 100644 index 678966cf..00000000 --- a/ltt/branches/poly/lttv/plugins/basicStats.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - -Analyse: loop over events, either one tracefile after another or - simultaneously by increasing time over all tracefiles. - -Process: create the process_state structure and register for all state - changing events to update the process_state. - -Stats: create an lttv_attributes to receive statistics. Offer functions - to specify statistics gathering (event types, specific field as int, - specific field as histogram...); this is used for syscalls and for - bytes read and written. Eventually factor out the type of - state and key positions (disk state, ethernet state...) - -Operations on stats: - select based on match, sort based on compare function/key order, - sum based on equality of truncated key - -Sort order: - key to base the sort on, by decreasing order of preference - -Match/combine: - for each key component, accept as is, only accept x, combine with previous. - -Print stats: - print hierarchically - - -*/ - - -typedef struct _stats_hook_data { - lttv_attributes *a; - lttv_key *key; - GHashTable *processes; - lttv_string_id current_process; - GArray *state; - lttv_string_id current_state; - bool init_done; -} stats_hook_data; - -/* Process state is wait, user, system, trap, irq */ - -/* before, after, print, free */ - -/* The accumulated statistics are: - -for each trace: - - The hierarchical key contains: - - system/cpu/process/state/type/id - - where state is one of user, system, irq, trap or wait, and type is one - of eventtype, syscall, and id is specific to each category (event id, - syscall number...). - - print per system/state/substate/eventid (sum over process/cpu) - print per system/cpu/state/substate/eventid (sum over process) - print per system/process/state/substate/eventid (sum over cpu) - - number of events of each type -*/ - -lttv_basicStats_before(lttv_trace_set *s) -{ - int i, j, nb_trace, nb_tracefile; - lttv_trace *t; - lttv_tracefile *tf; - lttv_attributes *a; - stats_hook_data *hook_data, *old; - - nb_trace = lttv_trace_set_number(s); - - for(i = 0 ; i < nb_trace ; i++) { - t = lttv_trace_set_get(s,i); - nb_tracefile = lttv_trace_number(t); - - hook_data = lttv_basicStats_new(); - a = lttv_trace_attributes(t); - old = (stats_hook_data *)lttv_attributes_get_pointer_pathname(a, - "stats/basic"); - lttv_basicStats_destroy(old); - lttv_attributes_set_pointer_pathname(a,"stats/basic",hook_data); - - for(j = 0 ; j < nb_tracefile ; j++) { - tf = lttv_trace_get(t,j); - a = lttv_tracefile_attributes(tf); - h = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,"hooks/event"); - lttv_hooks_add(h, compute_stats, hook_data); - } - } -} - -lttv_basicStats_after(lttv_trace_set *s) -{ - int i, j, nb_trace, nb_tracefile; - lttv_trace *t; - lttv_tracefile *tf; - lttv_attributes *a; - stats_hook_data *hook_data; - - nb_trace = lttv_trace_set_number(s); - - for(i = 0 ; i < nb_trace ; i++) { - t = lttv_trace_set_get(s,i); - nb_tracefile = lttv_trace_number(t); - - hook_data = (stats_hook_data *)lttv_attributes_get_pointer_pathname(a, - "stats/basic"); - - for(j = 0 ; j < nb_tracefile ; j++) { - tf = lttv_trace_get(t,j); - a = lttv_tracefile_attributes(tf); - h = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,"hooks/event"); - lttv_hooks_remove(h, compute_stats, hook_data); - } - - lttv_basicStats_destroy(hook_data); - } -} - - -update_state - -compute time in that state... - -For processes remember the command name... - -Compute bytes read/written... - -static void compute_eventtype_id_stats(void *hook_data, void *call_data) -{ - stats_hook_data *d; - ltt_event *e; - - d = (stats_hook_data *)hook_data; - e = (ltt_event *)call_data; - - lttv_key_index(d->key,4) = string_id_EventType; - lttv_key_index(d->key,5) = string_id_unsigned(ltt_event_eventtype_id(e)); - (*lttv_attributes_get_integer(d->a,d->key))++; -} - -/* The field for which a sum is required is expressed as eventtype/field */ - -typedef struct _field_sum_data { - stats_hook_data *d; - ltt_field *f; - lttv_string_id type_name; - lttv_string_id id_name; -} field_sum_data; - -lttv_basicStats_sum_integer_field_before(lttv_trace_set *s, char *field_path, - char *type_name, char *id_name) -{ - int i, j, nb_trace, nb_tracefile; - lttv_trace *t; - lttv_tracefile *tf; - lttv_attributes *a; - lttv_hooks_by_id h; - stats_hook_data *stats_data; - field_sum_data *hook_data; - unsigned id; - - nb_trace = lttv_trace_set_number(s); - - for(i = 0 ; i < nb_trace ; i++) { - t = lttv_trace_set_get(s,i); - nb_tracefile = lttv_trace_number(t); - - a = lttv_trace_attributes(t); - stats_data = (stats_hook_data *)lttv_attributes_get_pointer_pathname(a, - "stats/basic"); - - for(j = 0 ; j < nb_tracefile ; j++) { - tf = lttv_trace_get(t,j); - a = lttv_tracefile_attributes(tf); - hook_data = g_new(field_sum_data); - hook_data->d = stats_data; - hook_data->f = lttv_tracefile_eventtype_field_pathname( - lttv_tracefile_ltt_tracefile(tf), field_path, &id); - hook_data->type_name = type_name; - hook_data->id_name = id_name; - h = (lttv_hooks_by_id *)lttv_attributes_get_pointer_pathname(a, - "hooks/eventid"); - if(id_name != NULL) { - lttv_hooks_add(h, compute_integer_field_sum, hook_data); - } - else { - lttv_hooks_add(h, compute_integer_field_histogram, hook_data); - } - } - } -} - -static void compute_integer_field_sum(void *hook_data, void *call_data) -{ - field_sum_data *d; - ltt_event *e; - - d = (field_sum_data *)hook_data; - e = (ltt_event *)call_data; - - lttv_key_index(d->key,4) = d->type_name; - lttv_key_index(d->key,5) = d->id_name; - (*lttv_attributes_get_integer(d->a,d->key)) += - ltt_event_get_unsigned(e,d->f); -} - -static void compute_integer_field_histogram(void *hook_data, void *call_data) -{ - field_sum_data *d; - ltt_event *e; - - d = (field_sum_data *)hook_data; - e = (ltt_event *)call_data; - - lttv_key_index(d->key,4) = d->type_name; - lttv_key_index(d->key,5)= string_id_unsigned(ltt_event_get_unsigned(e,d->f)); - (*lttv_attributes_get_integer(d->a,d->key))++; -} - - -stats_hook_data *lttv_basicStats_new() -{ - g_new(stats_hook_data,1); - hook_data->a = lttv_attributes_new(); - hook_data->key = lttv_key_new(); - id = lttv_string_id(""); - for j = 0 ; j < 6 ; j++) lttv_key_append(hook_data->key,id); - hook_data->processes = g_hash_table_new(g_int_hash,g_int_equal); - hook_data->init_done = FALSE; -} - -stats_hook_data *lttv_basicStats_destroy(stats_hook_data *hook_data) -{ - lttv_attributes_destroy(hook_data->a); - lttv_key_destroy(hook_data->key); - lttv_process_state_destroy(hook_data->processes); - g_free(hook_data); - return NULL; -} - - - diff --git a/ltt/branches/poly/lttv/plugins/textDump.c b/ltt/branches/poly/lttv/plugins/textDump.c deleted file mode 100644 index 3c3ce2b8..00000000 --- a/ltt/branches/poly/lttv/plugins/textDump.c +++ /dev/null @@ -1,98 +0,0 @@ - -typedef struct _text_hook_data { - FILE *fp; - lttv_string *s; -} text_hook_data; - -void *lttv_textDump_before(lttv_trace_set *s, FILE *fp) -{ - int i, j, nb_trace, nb_tracefile; - lttv_attributes *a; - lttv_hooks *h; - lttv_trace *t; - lttv_tracefile *tf; - text_hook_data *hook_data; - - hook_data = g_new(ltt_hook_data,1); - nb_trace = lttv_trace_set_number(s); - hook_data->fp = fp; - hook_data->s = lttv_string_new; - - for(i = 0 ; i < nb_trace ; i++) { - t = lttv_trace_set_get(s,i); - a = lttv_trace_attributes(t); - h = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,"hooks/before"); - lttv_hooks_add(h, print_trace_title, hook_data); - nb_tracefile = lttv_trace_number(t); - - for(j = 0 ; j < nb_tracefile ; j++) { - h = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,"hooks/before"); - lttv_hooks_add(h, print_tracefile_title, hook_data); - h = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,"hooks/event"); - lttv_hooks_add(h, print_event, hook_data); - } - } -} - -void lttv_textDump_after(lttv_trace_set *ts, void *hook_data) -{ - int i, j, nb_trace, nb_tracefile; - lttv_attributes *a; - lttv_hooks *h; - lttv_trace *t; - lttv_tracefile *tf; - - nb_trace = lttv_trace_set_number(s); - - for(i = 0 ; i < nb_trace ; i++) { - t = lttv_trace_set_get(s,i); - a = lttv_trace_attributes(t); - h = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,"hooks/before"); - lttv_hooks_remove(h, print_trace_title, hook_data); - nb_tracefile = lttv_trace_number(t); - - for(j = 0 ; j < nb_tracefile ; j++) { - h = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,"hooks/before"); - lttv_hooks_remove(h, print_tracefile_title, hook_data); - h = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,"hooks/event"); - lttv_hooks_remove(h, print_event, hook_data); - } - } - lttv_string_destroy(hook_data->s); - g_free(hook_data); -} - -static void print_trace_title(void *hook_data, void *call_data) -{ - lttv_trace *t; - FILE *fp; - - fp = ((text_hook_data *)hook_data)->fp; - t = (lttv_trace *)call_data; - fprintf(fp,"\n\nTrace %s:\n\n" lttv_trace_name(t)); -} - -static void print_trace(void *hook_data, void *call_data) -{ - lttv_tracefile *tf; - FILE *fp; - - fp = ((text_hook_data *)hook_data)->fp; - tf = (lttv_tracefile *)call_data; - fprintf(fp,"\n\nTracefile %s:\n\n" lttv_tracefile_name(tf)); -} - -static void print_event(void *hook_data, void *call_data) -{ - ltt_event *e; - FILE *fp; - text_hook_data *d; - - d = ((text_hook_data *)hook_data; - e = (lttv_event *)call_data; - lttv_event_to_string(e,d->s,TRUE); - fprintf(fp,"%s\n" d->s->str); -} - - - diff --git a/ltt/branches/poly/lttv/trace.c b/ltt/branches/poly/lttv/trace.c deleted file mode 100644 index 55f6103d..00000000 --- a/ltt/branches/poly/lttv/trace.c +++ /dev/null @@ -1,136 +0,0 @@ -/* A trace is a sequence of events gathered in the same tracing session. The - events may be stored in several tracefiles in the same directory. - A trace set is defined when several traces are to be analyzed together, - possibly to study the interactions between events in the different traces. -*/ - -struct _lttv_trace_set { - GPtrArray *traces; - lttv_attributes *a; -}; - -struct _lttv_trace { - GPtrArray *all_cpu; - GPtrArray *per_cpu; - char *name; - lttv_attributes *a; -}; - - -struct _lttv_tracefile { - ltt_tracefile *t; - lttv_attributes *a; -}; - - -lttv_trace_set *lttv_trace_set_new() { - lttv_trace_set s; - - s = g_new(lttv_trace_set, 1); - s->traces = g_ptr_array_new(); - s->a = lttv_attributes_new(); -} - -lttv_trace_set *lttv_trace_set_destroy(lttv_trace_set *s) { - g_ptr_array_free(s->traces); - lttv_attributes_destroy(s->a); - return g_free(s); -} - -void lttv_trace_set_add(lttv_trace_set *s, lttv_trace *t) { - g_ptr_array_add(s,t); -} - -unsigned lttv_trace_set_number(lttv_trace_set *s) { - return s->traces.len; -} - - -lttv_trace *lttv_trace_set_get(lttv_trace_set *s, unsigned i) { - g_assert(s->traces->len <= i); - return s->traces.pdata[i]; -} - - -lttv_trace *lttv_trace_set_remove(lttv_trace_set *s, unsigned i) { - return g_ptr_array_remove_index(s->traces,i); -} - - -/* Look at all files in the directory. Open all those with ltt as extension - and sort these as per cpu or all cpu. */ - -lttv_trace *lttv_trace_open(char *pathname) { - lttv_trace *t; - - t = g_new(lttv_trace, 1); - t->per_cpu = g_ptr_array_new(); - t->all_cpu = g_ptr_array_new(); - t->a = lttv_attributes_new(); - return t; -} - -int lttv_trace_close(lttv_trace *t) { - - g_ptr_array_free(t->per_cpu); - g_ptr_array_free(t->all_cpu); - lttv_attributes_destroy(t->a); - g_free(t); - return 0; -} - -char *lttv_trace_name(lttv_trace *t) { - return t->name; -} - - -unsigned int lttv_trace_tracefile_number(lttv_trace *t) { - return t->per_cpu->len + t->all_cpu->len; -} - -unsigned int lttv_trace_cpu_number(lttv_trace *t) { - /* */ -} - -unsigned int lttv_trace_tracefile_number_per_cpu(lttv_trace *t) { - return t->per_cpu->len; -} - -unsigned int lttv_trace_tracefile_number_all_cpu(lttv_trace *t) { - return t->all_cpu_len; -} - -lttv_tracefile *lttv_trace_tracefile_get_per_cpu(lttv_trace *t, unsigned i) { - return t->per_cpu->pdata[i]; -} - -lttv_tracefile *lttv_trace_tracefile_get_all_cpu(lttv_trace *t, unsigned i) { - return t->all_cpu->pdata[i]; -} - - -/* A set of attributes is attached to each trace set, trace and tracefile - to store user defined data as needed. */ - -lttv_attributes *lttv_trace_set_attributes(lttv_trace_set *s) { - return s->a; -} - -lttv_attributes *lttv_trace_attributes(lttv_trace *t) { - return t->a; -} - -lttv_attributes *lttv_tracefile_attributes(lttv_tracefile *tf) { - return tf->a; -} - - -ltt_tracefile *lttv_tracefile_ltt_tracefile(lttv_tracefile *tf) { - return tf->t; -} - -char *lttv_tracefile_name(lttv_tracefile *tf) { - return tf->name; -} - - diff --git a/ltt/branches/poly/lttv/trace.h b/ltt/branches/poly/lttv/trace.h deleted file mode 100644 index 9e33e175..00000000 --- a/ltt/branches/poly/lttv/trace.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef TRACE_H -#define TRACE_H - -#include "attribute.h" - -/* A trace is a sequence of events gathered in the same tracing session. The - events may be stored in several tracefiles in the same directory. - A trace set is defined when several traces are to be analyzed together, - possibly to study the interactions between events in the different traces. -*/ - -typedef struct _lttv_trace_set lttv_trace_set; - -typedef struct _lttv_trace lttv_trace; - -typedef struct _lttv_tracefile lttv_tracefile; - - -/* 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, lttv_trace *t); - -unsigned lttv_trace_set_number(lttv_trace_set *s); - -lttv_trace *lttv_trace_set_get(lttv_trace_set *s, unsigned i); - -lttv_trace *lttv_trace_set_remove(lttv_trace_set *s, unsigned i); - - -/* A trace is identified by the pathname of its containing directory */ - -lttv_trace *lttv_trace_open(char *pathname); - -int lttv_trace_close(lttv_trace *t); - -char *lttv_trace_name(lttv_trace *t); - - -/* A trace typically contains one tracefile with important events - (for all CPUs), and one tracefile with ordinary events per cpu. - The tracefiles in a trace may be enumerated for each category - (all cpu and per cpu). The total number of tracefiles and of CPUs - may also be obtained. */ - -unsigned int lttv_trace_tracefile_number(lttv_trace *t); - -unsigned int lttv_trace_cpu_number(lttv_trace *t); - -unsigned int lttv_trace_tracefile_number_per_cpu(lttv_trace *t); - -unsigned int lttv_trace_tracefile_number_all_cpu(lttv_trace *t); - -lttv_tracefile *lttv_trace_tracefile_get_per_cpu(lttv_trace *t, unsigned i); - -lttv_tracefile *lttv_trace_tracefile_get_all_cpu(lttv_trace *t, unsigned i); - - -/* A set of attributes is attached to each trace set, trace and tracefile - to store user defined data as needed. */ - -lttv_attributes *lttv_trace_set_attributes(lttv_trace_set *s); - -lttv_attributes *lttv_trace_attributes(lttv_trace *t); - -lttv_attributes *lttv_tracefile_attributes(lttv_tracefile *tf); - - -/* The underlying ltt_tracefile, from which events may be read, is accessible. - The tracefile name is also available. */ - -lttv_tracefile *lttv_tracefile_ltt_tracefile(lttv_tracefile *tf); - -char *lttv_tracefile_name(lttv_tracefile *tf); - -#endif // TRACE_H - diff --git a/ltt/branches/poly/lttv/traceSet.c b/ltt/branches/poly/lttv/traceSet.c new file mode 100644 index 00000000..b889a893 --- /dev/null +++ b/ltt/branches/poly/lttv/traceSet.c @@ -0,0 +1,178 @@ +/* A trace is a sequence of events gathered in the same tracing session. The + events may be stored in several tracefiles in the same directory. + A trace set is defined when several traces are to be analyzed together, + possibly to study the interactions between events in the different traces. +*/ + +struct _lttv_trace_set { + GPtrArray *traces; + GPtrArray *attributes; + lttv_attributes *a; +}; + + +lttv_trace_set *lttv_trace_set_new() +{ + lttv_trace_set s; + + s = g_new(lttv_trace_set, 1); + s->traces = g_ptr_array_new(); + s->attributes = g_ptr_array_new(); + s->a = lttv_attributes_new(); +} + +lttv_trace_set *lttv_trace_set_destroy(lttv_trace_set *s) +{ + int i, nb; + + for(i = 0 ; i < s->attributes->len ; i++) { + lttv_attributes_destroy((lttv_attributes *)s->attributes->pdata[i]); + } + g_ptr_array_free(s->attributes); + g_ptr_array_free(s->traces); + lttv_attributes_destroy(s->a); + return g_free(s); +} + +void lttv_trace_set_add(lttv_trace_set *s, lttv_trace *t) +{ + g_ptr_array_add(s,t); + g_ptr_array_add(s,lttv_attributes_new()); +} + +unsigned lttv_trace_set_number(lttv_trace_set *s) +{ + return s->traces.len; +} + + +lttv_trace *lttv_trace_set_get(lttv_trace_set *s, unsigned i) +{ + g_assert(s->traces->len <= i); + return s->traces.pdata[i]; +} + + +lttv_trace *lttv_trace_set_remove(lttv_trace_set *s, unsigned i) +{ + return g_ptr_array_remove_index(s->traces,i); + lttv_attributes_destroy(g_ptr_array_remove_index(s->attributes,i)); +} + + +/* A set of attributes is attached to each trace set, trace and tracefile + to store user defined data as needed. */ + +lttv_attributes *lttv_trace_set_attributes(lttv_trace_set *s) +{ + return s->a; +} + +lttv_attributes *lttv_trace_set_trace_attributes(lttv_trace_set *s, unsigned i) +{ + return t->a; +} + +lttv_attributes *lttv_tracefile_attributes(lttv_tracefile *tf) { + return (lttv_attributes *)s->attributes->pdata[i]; +} + + +static void lttv_analyse_trace(lttv_trace *t); + +static void lttv_analyse_tracefile(lttv_tracefile *t); + +lttv_trace_set_process(lttv_trace_set *s, ltt_time start, ltt_time end) +{ + int i, nb; + lttv_hooks *before, *after; + lttv_attributes *a; + ltt_trace *t; + lttv_filter *filter_data; + + a = lttv_trace_set_attributes(s); + before = (lttv_hooks*)lttv_attributes_get_pointer_pathname(a,"hooks/before"); + after = (lttv_hooks*)lttv_attributes_get_pointer_pathname(a,"hooks/after"); + nb = lttv_trace_set_number(s); + + lttv_hooks_call(before, s); + + for(i = 0; i < nb; i++) { + t = lttv_trace_set_get(s,i); + a = lttv_trace_set_trace_attributes(s,i); + lttv_analyse_trace(t, a, start, end); + } + + lttv_hooks_call(after, s); +} + + +static void lttv_analyse_trace(ltt_trace *t, lttv_attributes *a, + ltt_time start, ltt_time end) +{ + int i, nb_all_cpu, nb_per_cpu; + lttv_hooks *before, *after; + + before = (lttv_hooks*)lttv_attributes_get_pointer_pathname(a,"hooks/before"); + after = (lttv_hooks*)lttv_attributes_get_pointer_pathname(a,"hooks/after"); + + nb_all_cpu = ltt_trace_tracefile_number_all_cpu(t); + nb_per_cpu = ltt_trace_tracefile_number_per_cpu(t); + + lttv_hooks_call(before, t); + + for(i = 0; i < nb_all_cpu; i++) { + lttv_analyse_tracefile(ltt_trace_get_all_cpu(t,i), a, start, end); + } + + for(i = 0; i < nb_per_cpu; i++) { + lttv_analyse_tracefile(ltt_trace_get_per_cpu(t,i), a, start, end); + } + + lttv_hooks_call(after, t); +} + + +static void lttv_analyse_tracefile(ltt_tracefile *t, lttv_attributes *a, + ltt_time start, ltt_time end) +{ + ltt_event *event; + unsigned id; + lttv_hooks *before, *after, *event_hooks, *tracefile_check, *event_check; + lttv_hooks_by_id *event_hooks_by_id; + lttv_attributes *a; + + before = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a, + "hooks/tracefile/before"); + after = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a, + "hooks/tracefile/after"); + event_hooks = (lttv_hooks*)lttv_attributes_get_pointer_pathname(a, + "hooks/event/selected"); + event_hooks_by_id = (lttv_hooks_by_id*) + lttv_attributes_get_pointer_pathname(a, "hooks/event/byid"); + tracefile_check = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a, + "hooks/tracefile/check"); + event_check = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a, + "hooks/event/check"); + + lttv_hooks_call(before, t); + + if(lttv_hooks_call_check(tracefile_check,t) && + ( lttv_hooks_number(event_hooks) != 0 || + lttv_hooks_by_id_number(event_hooks_by_id) != 0) { + + ltt_tracefile_seek_time(t, start); + while((event = ltt_tracefile_read(t)) != NULL && + ltt_event_time(event) < end) { + if(lttv_hooks_call_check(event_check)) { + lttv_hooks_call(event_hooks,event); + lttv_hooks_by_id_call(event_hooks_by_id,event, + ltt_event_type_id(event)); + } + } + } + lttv_hooks_call(after, t); +} + + + diff --git a/ltt/branches/poly/lttv/traceSet.h b/ltt/branches/poly/lttv/traceSet.h new file mode 100644 index 00000000..60955bc7 --- /dev/null +++ b/ltt/branches/poly/lttv/traceSet.h @@ -0,0 +1,47 @@ +#ifndef TRACESET_H +#define TRACESET_H + +#include +#include + +/* 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 + -- 2.34.1