git-svn-id: http://ltt.polymtl.ca/svn@289 04897980-b3bd-0310-b5e0-8ef037075253
[lttv.git] / ltt / branches / poly / lttv / countEvents.c
CommitLineData
48f6f3c2 1/* The countEvents module accumulates data for various basic reports
2
3 Not only does it count the events for each event type, it also tracks
4 the current state (current process and user/system mode) in order to
5 categorize accordingly the event counts. */
6
7void init(int argc, char **argv)
8{
9 lttv_attributes *a;
10 lttv_hooks *before, *after;
11
12 a = lttv_global_attributes();
13 before = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,
14 "hooks/trace_set/before");
15 after = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,
16 "hooks/trace_set/after");
17 lttv_hooks_add(before, countEvents_trace_set_before, NULL);
18 lttv_hooks_add(after, countEvents_trace_set_after, NULL);
19}
20
21
22void destroy()
23{
24 lttv_attributes *a;
25 lttv_hooks *before, *after;
26
27 a = lttv_global_attributes();
28 before = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,
29 "hooks/trace_set/before");
30 after = (lttv_hooks *)lttv_attributes_get_pointer_pathname(a,
31 "hooks/trace_set/after");
32 lttv_hooks_remove(before, countEvents_trace_set_before, NULL);
33 lttv_hooks_remove(after, countEvents_trace_set_after, NULL);
34}
35
36
37/* Insert the hooks before and after each trace and tracefile */
38
39typedef struct _trace_context {
40 unsigned nb_cpu;
41 struct cpu_context *cpus;
42 lttv_attributes *processes;
43 lttv_key *key;
44 lttv_attributes *event_counts;
45 lttv_attributes *trace_attributes;
46} trace_context;
47
48static bool countEvents_trace_set_before(void *hook_data, void *call_data)
49{
50 int i, j, nb, nbtf;
51 lttv_trace_set *s;
52 lttv_attributes *a;
53 trace_context *c;
54
55 s = (lttv_trace_set *)call_data;
56
57 /* For each trace prepare the contexts and insert the hooks */
58
59 nb = lttv_trace_set_number(s);
60 for(i = 0 ; i < nb ; i++) {
61 c = g_new(trace_context);
62 a = lttv_trace_set_trace_attributes(s, i);
63
64 if(lttv_attributes_get_pointer_pathname(a, "countEvents/context") != NULL){
65 g_error("Recursive call to TextDump");
66 }
67
68 lttv_attributes_set_pointer_pathname(a, "countEvents/context", c);
69
70 h = lttv_attributes_get_hooks(a, "hooks/before");
71 lttv_hooks_add(h, countEvents_trace_before, c);
72 h = lttv_attributes_get_hooks(a, "hooks/after");
73 lttv_hooks_add(h, countEvents_trace_after, c);
74 h = lttv_attributes_get_hooks(a, "hooks/tacefile/before");
75 lttv_hooks_add(h, countEvents_tracefile_before, c);
76 h = lttv_attributes_get_hooks(a, "hooks/tracefile/after");
77 lttv_hooks_add(h, countEvents_tracefile_after, c);
78 h = lttv_attributes_get_hooks(a, "hooks/event/selected");
79 lttv_hooks_add(h, couneEvents_event, c);
80 }
81
82 return TRUE;
83}
84
85
86/* Remove the hooks before and after each trace and tracefile, and for each
87 event. Print trace set level statistics. */
88
89static bool countEvents_trace_set_after(void *hook_data, void *call_data)
90{
91 int i, j, nb, nbtf;
92 lttv_trace_set *s;
93 lttv_attributes *a;
94 trace_context *c;
95
96 s = (lttv_trace_set *)call_data;
97
98 /* Get the file pointer */
99
100 fp = (FILE *)lttv_attributes_get_pointer_pathname(ga, "textDump/file");
101
102 /* For each trace remove the hooks */
103
104 nb = lttv_trace_set_number(s);
105 for(i = 0 ; i < nb ; i++) {
106 a = lttv_trace_set_trace_attributes(s, i);
107 c = (trace_context *)lttv_attributes_get_pointer_pathname(a,
108 "textDump/context");
109 lttv_attributes_set_pointer_pathname(a, "textDump/context", NULL);
110
111 h = lttv_attributes_get_hooks(a, "hooks/before");
112 lttv_hooks_remove(h, countEvents_trace_before, c);
113 h = lttv_attributes_get_hooks(a, "hooks/after");
114 lttv_hooks_remove(h, countEvents_trace_after, c);
115 h = lttv_attributes_get_hooks(a, "hooks/tacefile/before");
116 lttv_hooks_remove(h, countEvents_tracefile_before, c);
117 h = lttv_attributes_get_hooks(a, "hooks/tracefile/after");
118 lttv_hooks_remove(h, countEvents_tracefile_after, c);
119 h = lttv_attributes_get_hooks(a, "hooks/event/selected");
120 lttv_hooks_remove(h, countEvents_event, c);
121 g_free(c);
122 }
123
124 /* Compute statistics for the complete trace set */
125
126 return TRUE;
127}
128
129
130static bool countEvents_trace_before(void *hook_data, void *call_data)
131{
132 ltt_trace *t;
133 trace_context *c;
134
135 c = (trace_context *)hook_data;
136 t = (ltt_trace *)call_data;
137
138 /* Initialize the context */
139
140 return TRUE;
141}
142
143
144/* Print trace level statistics */
145
146static bool countEvents_trace_after(void *hook_data, void *call_data)
147{
148 ltt_trace *t;
149 trace_context *c;
150
151 c = (trace_context *)hook_data;
152 t = (ltt_trace *)call_data;
153
154 /* Sum events in different ways for the whole trace */
155
156 return TRUE;
157}
158
159
160static bool countEvents_tracefile_before(void *hook_data, void *call_data)
161{
162 ltt_tracefile *tf;
163 trace_context *c;
164
165 c = (trace_context *)hook_data;
166 tf = (ltt_tracefile *)call_data;
167
168 /* Nothing special to do for now */
169
170 return TRUE;
171}
172
173
174static bool countEvents_tracefile_after(void *hook_data, void *call_data)
175{
176 ltt_tracefile *tf;
177 trace_context *c;
178
179 c = (trace_context *)hook_data;
180 tf = (ltt_tracefile *)call_data;
181
182 /* Nothing special to do for now */
183
184 return TRUE;
185}
186
187
188static bool countEvents_event(void *hook_data, void *call_data)
189{
190 ltt_event *e;
191 trace_context *c;
192 unsigned cpu;
193 unsigned eventtype;
194 ltt_time t;
195
196 e = (ltt_event *)call_data;
197 c = (event_context *)hook_data;
198
199 eventtype = ltt_event_eventtype_id(e);
200 cpu = ltt_event_cpu_id(e);
201 time = ltt_event_time(e);
202
203 /* Accumulate the CPU time spent in that state */
204
205 key = c->cpu[cpu].key;
206 last_time = c->cpu[cpu].last_time;
207 c->cpu[cpu].last_time; = time;
208 lttv_key_index(key,LTTV_KEY_TYPE) = KEY_CPU;
209 total_time = lttv_attributes_time_get(c->main_attributes, key);
210
211 lttv_sub_time_value(delta_time, last_time, time);
212 lttv_add_time_valie(*total_time, *total_time, delta_time);
213
214 /* Some events indicate a state change to remember (syscall goes from user to
215 system mode, open assigns a new file to a file descriptor, exec changes
216 the memory map for the text section...) or have additional statistics
217 gathered. */
218
219 switch(c->eventtype_class[eventtype]) {
220
221 case LTTV_EVENT_SYSCALL_ENTRY:
222 n = ltt_event_get_unsigned(e,c->syscall_field)
223 push_state(c, cpu, KEY_SYSCALL, n, time);
224 /* For page faults it may be interesting to note waiting on which file */
225 break;
226
227 case LTTV_EVENT_SYSCALL_EXIT:
228 pop_state(c->cpu, cpu, KEY_SYSCALL, time);
229 break;
230
231 case LTTV_EVENT_TRAP_ENTRY:
232 n = ltt_event_get_unsigned(e,c->trap_field)
233 push_state(c, cpu, KEY_TRAP, n, time);
234 break;
235
236 case LTTV_EVENT_TRAP_EXIT:
237 pop_state(c->cpu, cpu, KEY_TRAP, time);
238 break;
239
240 case LTTV_EVENT_IRQ_ENTRY:
241 n = ltt_event_get_unsigned(e,c->irq_field)
242 push_state(c, cpu, KEY_IRQ, n, time);
243 break;
244
245 case LTTV_EVENT_IRQ_EXIT:
246 pop_state(c->cpu, cpu, KEY_IRQ, time);
247 break;
248
249
250 default:
251 }
252
253 /* The key already specifies the host, cpu, process and state, add the
254 event type and simply count one for the current event. */
255
256 lttv_key_index(key,LTTV_KEY_TYPE) = c->eventtype_key[eventtype];
257 count = lttv_attributes_get_integer(c->main_attributes, key);
258 (*count)++;
259
260 return TRUE;
261}
This page took 0.032113 seconds and 4 git commands to generate.