80 columns formatting
[lttv.git] / ltt / branches / poly / lttv / plugins / basicStats.c
CommitLineData
59121f0c 1/*
2
3Analyse: loop over events, either one tracefile after another or
4 simultaneously by increasing time over all tracefiles.
5
6Process: create the process_state structure and register for all state
7 changing events to update the process_state.
8
9Stats: 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...)
14
15Operations on stats:
16 select based on match, sort based on compare function/key order,
17 sum based on equality of truncated key
18
19Sort order:
20 key to base the sort on, by decreasing order of preference
21
22Match/combine:
23 for each key component, accept as is, only accept x, combine with previous.
24
25Print stats:
26 print hierarchically
27
28
29*/
30
31
32typedef struct _stats_hook_data {
33 lttv_attributes *a;
34 lttv_key *key;
35 GHashTable *processes;
36 lttv_string_id current_process;
37 GArray *state;
38 lttv_string_id current_state;
39 bool init_done;
40} stats_hook_data;
41
42/* Process state is wait, user, system, trap, irq */
43
44/* before, after, print, free */
45
46/* The accumulated statistics are:
47
48for each trace:
49
50 The hierarchical key contains:
51
52 system/cpu/process/state/type/id
53
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,
56 syscall number...).
57
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)
61
62 number of events of each type
63*/
64
65lttv_basicStats_before(lttv_trace_set *s)
66{
67 int i, j, nb_trace, nb_tracefile;
68 lttv_trace *t;
69 lttv_tracefile *tf;
70 lttv_attributes *a;
71 stats_hook_data *hook_data, *old;
72
73 nb_trace = lttv_trace_set_number(s);
74
75 for(i = 0 ; i < nb_trace ; i++) {
76 t = lttv_trace_set_get(s,i);
77 nb_tracefile = lttv_trace_number(t);
78
79 hook_data = lttv_basicStats_new();
80 a = lttv_trace_attributes(t);
81 old = (stats_hook_data *)lttv_attributes_get_pointer_pathname(a,
82 "stats/basic");
83 lttv_basicStats_destroy(old);
84 lttv_attributes_set_pointer_pathname(a,"stats/basic",hook_data);
85
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);
91 }
92 }
93}
94
95lttv_basicStats_after(lttv_trace_set *s)
96{
97 int i, j, nb_trace, nb_tracefile;
98 lttv_trace *t;
99 lttv_tracefile *tf;
100 lttv_attributes *a;
101 stats_hook_data *hook_data;
102
103 nb_trace = lttv_trace_set_number(s);
104
105 for(i = 0 ; i < nb_trace ; i++) {
106 t = lttv_trace_set_get(s,i);
107 nb_tracefile = lttv_trace_number(t);
108
109 hook_data = (stats_hook_data *)lttv_attributes_get_pointer_pathname(a,
110 "stats/basic");
111
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);
117 }
118
119 lttv_basicStats_destroy(hook_data);
120 }
121}
122
123
124update_state
125
126compute time in that state...
127
128For processes remember the command name...
129
130Compute bytes read/written...
131
132static void compute_eventtype_id_stats(void *hook_data, void *call_data)
133{
134 stats_hook_data *d;
135 ltt_event *e;
136
137 d = (stats_hook_data *)hook_data;
138 e = (ltt_event *)call_data;
139
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))++;
143}
144
145/* The field for which a sum is required is expressed as eventtype/field */
146
147typedef struct _field_sum_data {
148 stats_hook_data *d;
149 ltt_field *f;
150 lttv_string_id type_name;
151 lttv_string_id id_name;
152} field_sum_data;
153
154lttv_basicStats_sum_integer_field_before(lttv_trace_set *s, char *field_path,
155 char *type_name, char *id_name)
156{
157 int i, j, nb_trace, nb_tracefile;
158 lttv_trace *t;
159 lttv_tracefile *tf;
160 lttv_attributes *a;
161 lttv_hooks_by_id h;
162 stats_hook_data *stats_data;
163 field_sum_data *hook_data;
164 unsigned id;
165
166 nb_trace = lttv_trace_set_number(s);
167
168 for(i = 0 ; i < nb_trace ; i++) {
169 t = lttv_trace_set_get(s,i);
170 nb_tracefile = lttv_trace_number(t);
171
172 a = lttv_trace_attributes(t);
173 stats_data = (stats_hook_data *)lttv_attributes_get_pointer_pathname(a,
174 "stats/basic");
175
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,
186 "hooks/eventid");
187 if(id_name != NULL) {
188 lttv_hooks_add(h, compute_integer_field_sum, hook_data);
189 }
190 else {
191 lttv_hooks_add(h, compute_integer_field_histogram, hook_data);
192 }
193 }
194 }
195}
196
197static void compute_integer_field_sum(void *hook_data, void *call_data)
198{
199 field_sum_data *d;
200 ltt_event *e;
201
202 d = (field_sum_data *)hook_data;
203 e = (ltt_event *)call_data;
204
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);
209}
210
211static void compute_integer_field_histogram(void *hook_data, void *call_data)
212{
213 field_sum_data *d;
214 ltt_event *e;
215
216 d = (field_sum_data *)hook_data;
217 e = (ltt_event *)call_data;
218
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))++;
222}
223
224
225stats_hook_data *lttv_basicStats_new()
226{
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;
234}
235
236stats_hook_data *lttv_basicStats_destroy(stats_hook_data *hook_data)
237{
238 lttv_attributes_destroy(hook_data->a);
239 lttv_key_destroy(hook_data->key);
240 lttv_process_state_destroy(hook_data->processes);
241 g_free(hook_data);
242 return NULL;
243}
244
245
246
This page took 0.030829 seconds and 4 git commands to generate.