1 /* The countEvents module accumulates data for various basic reports
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. */
7 void init(int argc
, char **argv
)
10 lttv_hooks
*before
, *after
;
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
);
25 lttv_hooks
*before
, *after
;
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
);
37 /* Insert the hooks before and after each trace and tracefile */
39 typedef struct _trace_context
{
41 struct cpu_context
*cpus
;
42 lttv_attributes
*processes
;
44 lttv_attributes
*event_counts
;
45 lttv_attributes
*trace_attributes
;
48 static bool countEvents_trace_set_before(void *hook_data
, void *call_data
)
55 s
= (lttv_trace_set
*)call_data
;
57 /* For each trace prepare the contexts and insert the hooks */
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
);
64 if(lttv_attributes_get_pointer_pathname(a
, "countEvents/context") != NULL
){
65 g_error("Recursive call to TextDump");
68 lttv_attributes_set_pointer_pathname(a
, "countEvents/context", c
);
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
);
86 /* Remove the hooks before and after each trace and tracefile, and for each
87 event. Print trace set level statistics. */
89 static bool countEvents_trace_set_after(void *hook_data
, void *call_data
)
96 s
= (lttv_trace_set
*)call_data
;
98 /* Get the file pointer */
100 fp
= (FILE *)lttv_attributes_get_pointer_pathname(ga
, "textDump/file");
102 /* For each trace remove the hooks */
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
,
109 lttv_attributes_set_pointer_pathname(a
, "textDump/context", NULL
);
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
);
124 /* Compute statistics for the complete trace set */
130 static bool countEvents_trace_before(void *hook_data
, void *call_data
)
135 c
= (trace_context
*)hook_data
;
136 t
= (ltt_trace
*)call_data
;
138 /* Initialize the context */
144 /* Print trace level statistics */
146 static bool countEvents_trace_after(void *hook_data
, void *call_data
)
151 c
= (trace_context
*)hook_data
;
152 t
= (ltt_trace
*)call_data
;
154 /* Sum events in different ways for the whole trace */
160 static bool countEvents_tracefile_before(void *hook_data
, void *call_data
)
165 c
= (trace_context
*)hook_data
;
166 tf
= (ltt_tracefile
*)call_data
;
168 /* Nothing special to do for now */
174 static bool countEvents_tracefile_after(void *hook_data
, void *call_data
)
179 c
= (trace_context
*)hook_data
;
180 tf
= (ltt_tracefile
*)call_data
;
182 /* Nothing special to do for now */
188 static bool countEvents_event(void *hook_data
, void *call_data
)
196 e
= (ltt_event
*)call_data
;
197 c
= (event_context
*)hook_data
;
199 eventtype
= ltt_event_eventtype_id(e
);
200 cpu
= ltt_event_cpu_id(e
);
201 time
= ltt_event_time(e
);
203 /* Accumulate the CPU time spent in that state */
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
);
211 lttv_sub_time_value(delta_time
, last_time
, time
);
212 lttv_add_time_valie(*total_time
, *total_time
, delta_time
);
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
219 switch(c
->eventtype_class
[eventtype
]) {
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 */
227 case LTTV_EVENT_SYSCALL_EXIT
:
228 pop_state(c
->cpu
, cpu
, KEY_SYSCALL
, time
);
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
);
236 case LTTV_EVENT_TRAP_EXIT
:
237 pop_state(c
->cpu
, cpu
, KEY_TRAP
, time
);
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
);
245 case LTTV_EVENT_IRQ_EXIT
:
246 pop_state(c
->cpu
, cpu
, KEY_IRQ
, time
);
253 /* The key already specifies the host, cpu, process and state, add the
254 event type and simply count one for the current event. */
256 lttv_key_index(key
,LTTV_KEY_TYPE
) = c
->eventtype_key
[eventtype
];
257 count
= lttv_attributes_get_integer(c
->main_attributes
, key
);