3 Analyse: loop over events, either one tracefile after another or
4 simultaneously by increasing time over all tracefiles.
6 Process: create the process_state structure and register for all state
7 changing events to update the process_state.
9 Stats: create an lttv_attributes to receive statistics. Offer functions
10 to specify statistics gathering (event types, specific field as int,
11 specific field as histogram...); this is used for syscalls and for
12 bytes read and written. Eventually factor out the type of
13 state and key positions (disk state, ethernet state...)
16 select based on match, sort based on compare function/key order,
17 sum based on equality of truncated key
20 key to base the sort on, by decreasing order of preference
23 for each key component, accept as is, only accept x, combine with previous.
32 typedef struct _stats_hook_data
{
35 GHashTable
*processes
;
36 lttv_string_id current_process
;
38 lttv_string_id current_state
;
42 /* Process state is wait, user, system, trap, irq */
44 /* before, after, print, free */
46 /* The accumulated statistics are:
50 The hierarchical key contains:
52 system/cpu/process/state/type/id
54 where state is one of user, system, irq, trap or wait, and type is one
55 of eventtype, syscall, and id is specific to each category (event id,
58 print per system/state/substate/eventid (sum over process/cpu)
59 print per system/cpu/state/substate/eventid (sum over process)
60 print per system/process/state/substate/eventid (sum over cpu)
62 number of events of each type
65 lttv_basicStats_before(lttv_trace_set
*s
)
67 int i
, j
, nb_trace
, nb_tracefile
;
71 stats_hook_data
*hook_data
, *old
;
73 nb_trace
= lttv_trace_set_number(s
);
75 for(i
= 0 ; i
< nb_trace
; i
++) {
76 t
= lttv_trace_set_get(s
,i
);
77 nb_tracefile
= lttv_trace_number(t
);
79 hook_data
= lttv_basicStats_new();
80 a
= lttv_trace_attributes(t
);
81 old
= (stats_hook_data
*)lttv_attributes_get_pointer_pathname(a
,
83 lttv_basicStats_destroy(old
);
84 lttv_attributes_set_pointer_pathname(a
,"stats/basic",hook_data
);
86 for(j
= 0 ; j
< nb_tracefile
; j
++) {
87 tf
= lttv_trace_get(t
,j
);
88 a
= lttv_tracefile_attributes(tf
);
89 h
= (lttv_hooks
*)lttv_attributes_get_pointer_pathname(a
,"hooks/event");
90 lttv_hooks_add(h
, compute_stats
, hook_data
);
95 lttv_basicStats_after(lttv_trace_set
*s
)
97 int i
, j
, nb_trace
, nb_tracefile
;
101 stats_hook_data
*hook_data
;
103 nb_trace
= lttv_trace_set_number(s
);
105 for(i
= 0 ; i
< nb_trace
; i
++) {
106 t
= lttv_trace_set_get(s
,i
);
107 nb_tracefile
= lttv_trace_number(t
);
109 hook_data
= (stats_hook_data
*)lttv_attributes_get_pointer_pathname(a
,
112 for(j
= 0 ; j
< nb_tracefile
; j
++) {
113 tf
= lttv_trace_get(t
,j
);
114 a
= lttv_tracefile_attributes(tf
);
115 h
= (lttv_hooks
*)lttv_attributes_get_pointer_pathname(a
,"hooks/event");
116 lttv_hooks_remove(h
, compute_stats
, hook_data
);
119 lttv_basicStats_destroy(hook_data
);
126 compute time in that state
...
128 For processes remember the command name
...
130 Compute bytes read
/written
...
132 static void compute_eventtype_id_stats(void *hook_data
, void *call_data
)
137 d
= (stats_hook_data
*)hook_data
;
138 e
= (ltt_event
*)call_data
;
140 lttv_key_index(d
->key
,4) = string_id_EventType
;
141 lttv_key_index(d
->key
,5) = string_id_unsigned(ltt_event_eventtype_id(e
));
142 (*lttv_attributes_get_integer(d
->a
,d
->key
))++;
145 /* The field for which a sum is required is expressed as eventtype/field */
147 typedef struct _field_sum_data
{
150 lttv_string_id type_name
;
151 lttv_string_id id_name
;
154 lttv_basicStats_sum_integer_field_before(lttv_trace_set
*s
, char *field_path
,
155 char *type_name
, char *id_name
)
157 int i
, j
, nb_trace
, nb_tracefile
;
162 stats_hook_data
*stats_data
;
163 field_sum_data
*hook_data
;
166 nb_trace
= lttv_trace_set_number(s
);
168 for(i
= 0 ; i
< nb_trace
; i
++) {
169 t
= lttv_trace_set_get(s
,i
);
170 nb_tracefile
= lttv_trace_number(t
);
172 a
= lttv_trace_attributes(t
);
173 stats_data
= (stats_hook_data
*)lttv_attributes_get_pointer_pathname(a
,
176 for(j
= 0 ; j
< nb_tracefile
; j
++) {
177 tf
= lttv_trace_get(t
,j
);
178 a
= lttv_tracefile_attributes(tf
);
179 hook_data
= g_new(field_sum_data
);
180 hook_data
->d
= stats_data
;
181 hook_data
->f
= lttv_tracefile_eventtype_field_pathname(
182 lttv_tracefile_ltt_tracefile(tf
), field_path
, &id
);
183 hook_data
->type_name
= type_name
;
184 hook_data
->id_name
= id_name
;
185 h
= (lttv_hooks_by_id
*)lttv_attributes_get_pointer_pathname(a
,
187 if(id_name
!= NULL
) {
188 lttv_hooks_add(h
, compute_integer_field_sum
, hook_data
);
191 lttv_hooks_add(h
, compute_integer_field_histogram
, hook_data
);
197 static void compute_integer_field_sum(void *hook_data
, void *call_data
)
202 d
= (field_sum_data
*)hook_data
;
203 e
= (ltt_event
*)call_data
;
205 lttv_key_index(d
->key
,4) = d
->type_name
;
206 lttv_key_index(d
->key
,5) = d
->id_name
;
207 (*lttv_attributes_get_integer(d
->a
,d
->key
)) +=
208 ltt_event_get_unsigned(e
,d
->f
);
211 static void compute_integer_field_histogram(void *hook_data
, void *call_data
)
216 d
= (field_sum_data
*)hook_data
;
217 e
= (ltt_event
*)call_data
;
219 lttv_key_index(d
->key
,4) = d
->type_name
;
220 lttv_key_index(d
->key
,5)= string_id_unsigned(ltt_event_get_unsigned(e
,d
->f
));
221 (*lttv_attributes_get_integer(d
->a
,d
->key
))++;
225 stats_hook_data
*lttv_basicStats_new()
227 g_new(stats_hook_data
,1);
228 hook_data
->a
= lttv_attributes_new();
229 hook_data
->key
= lttv_key_new();
230 id
= lttv_string_id("");
231 for j
= 0 ; j
< 6 ; j
++) lttv_key_append(hook_data
->key
,id
);
232 hook_data
->processes
= g_hash_table_new(g_int_hash
,g_int_equal
);
233 hook_data
->init_done
= FALSE
;
236 stats_hook_data
*lttv_basicStats_destroy(stats_hook_data
*hook_data
)
238 lttv_attributes_destroy(hook_data
->a
);
239 lttv_key_destroy(hook_data
->key
);
240 lttv_process_state_destroy(hook_data
->processes
);