update compat
[lttv.git] / ltt / branches / poly / lttv / lttv / stats.c
CommitLineData
9c312311 1/* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Michel Dagenais
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
16 * MA 02111-1307, USA.
17 */
18
4e4d11b3 19#ifdef HAVE_CONFIG_H
20#include <config.h>
21#endif
b445142a 22
9f797243 23#include <stdio.h>
08b1c66e 24#include <lttv/module.h>
b445142a 25#include <lttv/stats.h>
2a2fa4f0 26#include <lttv/lttv.h>
f95bc830 27#include <lttv/attribute.h>
b445142a 28#include <ltt/facility.h>
29#include <ltt/trace.h>
30#include <ltt/event.h>
826f1ab2 31#include <ltt/type.h>
b445142a 32
9f797243 33#define BUF_SIZE 256
14236daa 34#define MAX_64_HEX_STRING_LEN 19
9f797243 35
b445142a 36GQuark
37 LTTV_STATS_PROCESS_UNKNOWN,
38 LTTV_STATS_PROCESSES,
39 LTTV_STATS_CPU,
40 LTTV_STATS_MODE_TYPES,
41 LTTV_STATS_MODES,
42 LTTV_STATS_SUBMODES,
302efbad 43 LTTV_STATS_FUNCTIONS,
b445142a 44 LTTV_STATS_EVENT_TYPES,
45 LTTV_STATS_CPU_TIME,
46 LTTV_STATS_ELAPSED_TIME,
47 LTTV_STATS_EVENTS,
f95bc830 48 LTTV_STATS_EVENTS_COUNT,
49 LTTV_STATS_USE_COUNT,
50 LTTV_STATS,
51 LTTV_STATS_TRACEFILES,
22b165e9 52 LTTV_STATS_SUMMED,
b445142a 53 LTTV_STATS_BEFORE_HOOKS,
54 LTTV_STATS_AFTER_HOOKS;
55
b445142a 56static void
c0cb4d12 57find_event_tree(LttvTracefileStats *tfcs, GQuark pid_time, guint cpu,
14236daa 58 guint64 function,
b445142a 59 GQuark mode, GQuark sub_mode, LttvAttribute **events_tree,
60 LttvAttribute **event_types_tree);
61
d730b5c8 62
63static void lttv_stats_init(LttvTracesetStats *self)
b445142a 64{
dbb7bb09 65 guint i, j, nb_trace, nb_tracefile;
b445142a 66
67 LttvTraceContext *tc;
68
69 LttvTraceStats *tcs;
70
71 LttvTracefileContext *tfc;
72
3c9bb8b1 73 LttvTracefileContext **tfs;
b445142a 74 LttvTracefileStats *tfcs;
75
76 LttTime timestamp = {0,0};
77
f95bc830 78 LttvAttributeValue v;
79
80 LttvAttribute
81 *stats_tree,
82 *tracefiles_stats;
83
d730b5c8 84 LttvTraceset *ts = self->parent.parent.ts;
b445142a 85
d3e01c7a 86 self->stats = lttv_attribute_find_subdir(
87 lttv_traceset_attribute(self->parent.parent.ts),
88 LTTV_STATS);
89 lttv_attribute_find(lttv_traceset_attribute(self->parent.parent.ts),
90 LTTV_STATS_USE_COUNT,
91 LTTV_UINT, &v);
f95bc830 92
0bd2f89c 93 (*(v.v_uint))++;
f95bc830 94 if(*(v.v_uint) == 1) {
95 g_assert(lttv_attribute_get_number(self->stats) == 0);
96 }
97
b445142a 98 nb_trace = lttv_traceset_number(ts);
99
100 for(i = 0 ; i < nb_trace ; i++) {
021eeb41 101 tc = self->parent.parent.traces[i];
102 tcs = LTTV_TRACE_STATS(tc);
f95bc830 103
104 tcs->stats = lttv_attribute_find_subdir(tcs->parent.parent.t_a,LTTV_STATS);
105 tracefiles_stats = lttv_attribute_find_subdir(tcs->parent.parent.t_a,
106 LTTV_STATS_TRACEFILES);
107 lttv_attribute_find(tcs->parent.parent.t_a, LTTV_STATS_USE_COUNT,
108 LTTV_UINT, &v);
109
0bd2f89c 110 (*(v.v_uint))++;
f95bc830 111 if(*(v.v_uint) == 1) {
112 g_assert(lttv_attribute_get_number(tcs->stats) == 0);
113 }
b445142a 114
eed2ef37 115 nb_tracefile = tc->tracefiles->len;
b445142a 116
dbb7bb09 117 for(j = 0 ; j < nb_tracefile ; j++) {
3c9bb8b1 118 tfs = &g_array_index(tc->tracefiles,
119 LttvTracefileContext*, j);
120 tfcs = LTTV_TRACEFILE_STATS(*tfs);
f95bc830 121 tfcs->stats = lttv_attribute_find_subdir(tracefiles_stats,
348c6ba8 122 ltt_tracefile_long_name(tfcs->parent.parent.tf));
c0cb4d12 123 guint cpu = tfcs->parent.cpu;
b445142a 124 find_event_tree(tfcs, LTTV_STATS_PROCESS_UNKNOWN,
c0cb4d12 125 cpu,
14236daa 126 0x0ULL,
348c6ba8 127 LTTV_STATE_MODE_UNKNOWN,
b445142a 128 LTTV_STATE_SUBMODE_UNKNOWN, &tfcs->current_events_tree,
129 &tfcs->current_event_types_tree);
130 }
131 }
d730b5c8 132
b445142a 133}
134
d730b5c8 135static void lttv_stats_fini(LttvTracesetStats *self)
b445142a 136{
137 guint i, j, nb_trace, nb_tracefile;
138
139 LttvTraceset *ts;
140
141 LttvTraceContext *tc;
142
143 LttvTraceStats *tcs;
144
145 LttvTracefileContext *tfc;
146
147 LttvTracefileStats *tfcs;
148
149 LttTime timestamp = {0,0};
150
f95bc830 151 LttvAttributeValue v;
152
153 LttvAttribute *tracefiles_stats;
154
155 lttv_attribute_find(self->parent.parent.ts_a, LTTV_STATS_USE_COUNT,
156 LTTV_UINT, &v);
0bd2f89c 157 (*(v.v_uint))--;
f95bc830 158
159 if(*(v.v_uint) == 0) {
160 lttv_attribute_remove_by_name(self->parent.parent.ts_a, LTTV_STATS);
f95bc830 161 }
162 self->stats = NULL;
163
b445142a 164 ts = self->parent.parent.ts;
165 nb_trace = lttv_traceset_number(ts);
166
167 for(i = 0 ; i < nb_trace ; i++) {
f95bc830 168 tcs = (LttvTraceStats *)(tc = (LTTV_TRACESET_CONTEXT(self)->traces[i]));
169
170 lttv_attribute_find(tcs->parent.parent.t_a, LTTV_STATS_USE_COUNT,
171 LTTV_UINT, &v);
0bd2f89c 172 (*(v.v_uint))--;
f95bc830 173
174 if(*(v.v_uint) == 0) {
175 lttv_attribute_remove_by_name(tcs->parent.parent.t_a,LTTV_STATS);
f95bc830 176 tracefiles_stats = lttv_attribute_find_subdir(tcs->parent.parent.t_a,
177 LTTV_STATS_TRACEFILES);
178 lttv_attribute_remove_by_name(tcs->parent.parent.t_a,
179 LTTV_STATS_TRACEFILES);
f95bc830 180 }
181 tcs->stats = NULL;
b445142a 182
eed2ef37 183 nb_tracefile = tc->tracefiles->len;
b445142a 184
b445142a 185 for(j = 0 ; j < nb_tracefile ; j++) {
cb03932a 186 tfc = g_array_index(tc->tracefiles,
187 LttvTracefileContext*, j);
359b2948 188 tfcs = (LttvTracefileStats *)tfc;
f95bc830 189 tfcs->stats = NULL;
b445142a 190 tfcs->current_events_tree = NULL;
191 tfcs->current_event_types_tree = NULL;
192 }
193 }
d730b5c8 194}
195
196
197void lttv_stats_reset(LttvTracesetStats *self)
198{
199 lttv_stats_fini(self);
200 lttv_stats_init(self);
201}
202
203
204
205static void
206init(LttvTracesetStats *self, LttvTraceset *ts)
207{
208 LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))->
209 init((LttvTracesetContext *)self, ts);
210
211 lttv_stats_init(self);
212}
213
214
215static void
216fini(LttvTracesetStats *self)
217{
218 lttv_stats_fini(self);
219
b445142a 220 LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))->
221 fini((LttvTracesetContext *)self);
222}
223
224
225static LttvTracesetContext *
226new_traceset_context(LttvTracesetContext *self)
227{
228 return LTTV_TRACESET_CONTEXT(g_object_new(LTTV_TRACESET_STATS_TYPE, NULL));
229}
230
231
232static LttvTraceContext *
233new_trace_context(LttvTracesetContext *self)
234{
235 return LTTV_TRACE_CONTEXT(g_object_new(LTTV_TRACE_STATS_TYPE, NULL));
236}
237
238
239static LttvTracefileContext *
240new_tracefile_context(LttvTracesetContext *self)
241{
242 return LTTV_TRACEFILE_CONTEXT(g_object_new(LTTV_TRACEFILE_STATS_TYPE, NULL));
243}
244
245
246static void
247traceset_stats_instance_init (GTypeInstance *instance, gpointer g_class)
248{
249}
250
251
252static void
253traceset_stats_finalize (LttvTracesetStats *self)
254{
255 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))->
256 finalize(G_OBJECT(self));
257}
258
259
260static void
261traceset_stats_class_init (LttvTracesetContextClass *klass)
262{
263 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
264
265 gobject_class->finalize = (void (*)(GObject *self)) traceset_stats_finalize;
266 klass->init = (void (*)(LttvTracesetContext *self, LttvTraceset *ts))init;
267 klass->fini = (void (*)(LttvTracesetContext *self))fini;
268 klass->new_traceset_context = new_traceset_context;
269 klass->new_trace_context = new_trace_context;
270 klass->new_tracefile_context = new_tracefile_context;
271}
272
273
274GType
275lttv_traceset_stats_get_type(void)
276{
277 static GType type = 0;
278 if (type == 0) {
279 static const GTypeInfo info = {
280 sizeof (LttvTracesetStatsClass),
281 NULL, /* base_init */
282 NULL, /* base_finalize */
283 (GClassInitFunc) traceset_stats_class_init, /* class_init */
284 NULL, /* class_finalize */
285 NULL, /* class_data */
dbb7bb09 286 sizeof (LttvTracesetStats),
b445142a 287 0, /* n_preallocs */
00e74b69 288 (GInstanceInitFunc) traceset_stats_instance_init, /* instance_init */
289 NULL /* Value handling */
b445142a 290 };
291
00e74b69 292 type = g_type_register_static (LTTV_TRACESET_STATE_TYPE,
293 "LttvTracesetStatsType",
294 &info, 0);
b445142a 295 }
296 return type;
297}
298
299
300static void
301trace_stats_instance_init (GTypeInstance *instance, gpointer g_class)
302{
303}
304
305
306static void
307trace_stats_finalize (LttvTraceStats *self)
308{
309 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACE_STATE_TYPE))->
310 finalize(G_OBJECT(self));
311}
312
313
314static void
315trace_stats_class_init (LttvTraceContextClass *klass)
316{
317 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
318
319 gobject_class->finalize = (void (*)(GObject *self)) trace_stats_finalize;
320}
321
322
323GType
324lttv_trace_stats_get_type(void)
325{
326 static GType type = 0;
327 if (type == 0) {
328 static const GTypeInfo info = {
329 sizeof (LttvTraceStatsClass),
330 NULL, /* base_init */
331 NULL, /* base_finalize */
332 (GClassInitFunc) trace_stats_class_init, /* class_init */
333 NULL, /* class_finalize */
334 NULL, /* class_data */
335 sizeof (LttvTraceStats),
336 0, /* n_preallocs */
00e74b69 337 (GInstanceInitFunc) trace_stats_instance_init, /* instance_init */
338 NULL /* Value handling */
b445142a 339 };
340
341 type = g_type_register_static (LTTV_TRACE_STATE_TYPE,
342 "LttvTraceStatsType", &info, 0);
343 }
344 return type;
345}
346
347
348static void
349tracefile_stats_instance_init (GTypeInstance *instance, gpointer g_class)
350{
351}
352
353
354static void
355tracefile_stats_finalize (LttvTracefileStats *self)
356{
357 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACEFILE_STATE_TYPE))->
358 finalize(G_OBJECT(self));
359}
360
361
362static void
363tracefile_stats_class_init (LttvTracefileStatsClass *klass)
364{
365 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
366
367 gobject_class->finalize = (void (*)(GObject *self)) tracefile_stats_finalize;
368}
369
370
371GType
372lttv_tracefile_stats_get_type(void)
373{
374 static GType type = 0;
375 if (type == 0) {
376 static const GTypeInfo info = {
377 sizeof (LttvTracefileStatsClass),
378 NULL, /* base_init */
379 NULL, /* base_finalize */
380 (GClassInitFunc) tracefile_stats_class_init, /* class_init */
381 NULL, /* class_finalize */
382 NULL, /* class_data */
383 sizeof (LttvTracefileStats),
384 0, /* n_preallocs */
00e74b69 385 (GInstanceInitFunc) tracefile_stats_instance_init, /* instance_init */
386 NULL /* Value handling */
b445142a 387 };
388
389 type = g_type_register_static (LTTV_TRACEFILE_STATE_TYPE,
390 "LttvTracefileStatsType", &info, 0);
391 }
392 return type;
393}
394
395
396static void
00e74b69 397find_event_tree(LttvTracefileStats *tfcs,
398 GQuark pid_time,
c0cb4d12 399 guint cpu,
14236daa 400 guint64 function,
00e74b69 401 GQuark mode,
402 GQuark sub_mode,
403 LttvAttribute **events_tree,
404 LttvAttribute **event_types_tree)
b445142a 405{
c0cb4d12 406 LttvAttribute *a, *prev_a;
14236daa 407 gchar fstring[MAX_64_HEX_STRING_LEN];
408
409 g_assert(snprintf(fstring, MAX_64_HEX_STRING_LEN-1,
410 "0x%llX", function) > 0);
411 fstring[MAX_64_HEX_STRING_LEN-1] = '\0';
b445142a 412
3c9bb8b1 413 LttvTraceStats *tcs = (LttvTraceStats*)tfcs->parent.parent.t_context;
b445142a 414 a = lttv_attribute_find_subdir(tcs->stats, LTTV_STATS_PROCESSES);
00e74b69 415 a = lttv_attribute_find_subdir(a, pid_time);
b445142a 416 a = lttv_attribute_find_subdir(a, LTTV_STATS_CPU);
c0cb4d12 417 a = lttv_attribute_find_subdir_unnamed(a, cpu);
14236daa 418 a = lttv_attribute_find_subdir(a, LTTV_STATS_FUNCTIONS);
419 a = lttv_attribute_find_subdir(a, g_quark_from_string(fstring));
b445142a 420 a = lttv_attribute_find_subdir(a, LTTV_STATS_MODE_TYPES);
00e74b69 421 a = lttv_attribute_find_subdir(a, mode);
b445142a 422 a = lttv_attribute_find_subdir(a, LTTV_STATS_SUBMODES);
00e74b69 423 a = lttv_attribute_find_subdir(a, sub_mode);
b445142a 424 *events_tree = a;
425 a = lttv_attribute_find_subdir(a, LTTV_STATS_EVENT_TYPES);
426 *event_types_tree = a;
427}
428
429
430static void update_event_tree(LttvTracefileStats *tfcs)
431{
348c6ba8 432 LttvTraceState *ts = (LttvTraceState *)tfcs->parent.parent.t_context;
ae3d0f50 433 guint cpu = tfcs->parent.cpu;
348c6ba8 434 LttvProcessState *process = ts->running_process[cpu];
435 LttvExecutionState *es = process->state;
b445142a 436
348c6ba8 437 find_event_tree(tfcs, process->pid_time,
c0cb4d12 438 cpu,
14236daa 439 process->current_function,
b445142a 440 es->t, es->n, &(tfcs->current_events_tree),
441 &(tfcs->current_event_types_tree));
442}
443
444
445static void mode_change(LttvTracefileStats *tfcs)
446{
348c6ba8 447 LttvTraceState *ts = (LttvTraceState *)tfcs->parent.parent.t_context;
ae3d0f50 448 guint cpu = tfcs->parent.cpu;
348c6ba8 449 LttvProcessState *process = ts->running_process[cpu];
b445142a 450 LttvAttributeValue cpu_time;
451
452 LttTime delta;
453
454 lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CPU_TIME,
455 LTTV_TIME, &cpu_time);
308711e5 456 delta = ltt_time_sub(tfcs->parent.parent.timestamp,
348c6ba8 457 process->state->change);
308711e5 458 *(cpu_time.v_time) = ltt_time_add(*(cpu_time.v_time), delta);
b445142a 459}
460
461
462static void mode_end(LttvTracefileStats *tfcs)
463{
348c6ba8 464 LttvTraceState *ts = (LttvTraceState *)tfcs->parent.parent.t_context;
ae3d0f50 465 guint cpu = tfcs->parent.cpu;
348c6ba8 466 LttvProcessState *process = ts->running_process[cpu];
b445142a 467 LttvAttributeValue elapsed_time, cpu_time;
468
469 LttTime delta;
470
471 lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_ELAPSED_TIME,
472 LTTV_TIME, &elapsed_time);
308711e5 473 delta = ltt_time_sub(tfcs->parent.parent.timestamp,
348c6ba8 474 process->state->entry);
308711e5 475 *(elapsed_time.v_time) = ltt_time_add(*(elapsed_time.v_time), delta);
b445142a 476
477 lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CPU_TIME,
478 LTTV_TIME, &cpu_time);
308711e5 479 delta = ltt_time_sub(tfcs->parent.parent.timestamp,
348c6ba8 480 process->state->change);
308711e5 481 *(cpu_time.v_time) = ltt_time_add(*(cpu_time.v_time), delta);
b445142a 482}
483
484
485static gboolean before_syscall_entry(void *hook_data, void *call_data)
486{
487 mode_change((LttvTracefileStats *)call_data);
488 return FALSE;
489}
490
491
492static gboolean after_syscall_entry(void *hook_data, void *call_data)
493{
494 update_event_tree((LttvTracefileStats *)call_data);
495 return FALSE;
496}
497
498
499gboolean before_syscall_exit(void *hook_data, void *call_data)
500{
501 mode_end((LttvTracefileStats *)call_data);
502 return FALSE;
503}
504
505
506static gboolean after_syscall_exit(void *hook_data, void *call_data)
507{
508 update_event_tree((LttvTracefileStats *)call_data);
509 return FALSE;
510}
511
512
513gboolean before_trap_entry(void *hook_data, void *call_data)
514{
515 mode_change((LttvTracefileStats *)call_data);
516 return FALSE;
517}
518
519
520static gboolean after_trap_entry(void *hook_data, void *call_data)
521{
522 update_event_tree((LttvTracefileStats *)call_data);
523 return FALSE;
524}
525
526
527gboolean before_trap_exit(void *hook_data, void *call_data)
528{
529 mode_end((LttvTracefileStats *)call_data);
530 return FALSE;
531}
532
533
534gboolean after_trap_exit(void *hook_data, void *call_data)
535{
536 update_event_tree((LttvTracefileStats *)call_data);
537 return FALSE;
538}
539
540
541gboolean before_irq_entry(void *hook_data, void *call_data)
542{
543 mode_change((LttvTracefileStats *)call_data);
544 return FALSE;
545}
546
b445142a 547gboolean after_irq_entry(void *hook_data, void *call_data)
548{
549 update_event_tree((LttvTracefileStats *)call_data);
550 return FALSE;
551}
552
553
554gboolean before_irq_exit(void *hook_data, void *call_data)
555{
556 mode_end((LttvTracefileStats *)call_data);
557 return FALSE;
558}
559
560
561gboolean after_irq_exit(void *hook_data, void *call_data)
562{
563 update_event_tree((LttvTracefileStats *)call_data);
564 return FALSE;
565}
566
567
faf074a3 568gboolean before_soft_irq_entry(void *hook_data, void *call_data)
569{
570 mode_change((LttvTracefileStats *)call_data);
571 return FALSE;
572}
573
574gboolean after_soft_irq_entry(void *hook_data, void *call_data)
575{
576 update_event_tree((LttvTracefileStats *)call_data);
577 return FALSE;
578}
579
580
581gboolean before_soft_irq_exit(void *hook_data, void *call_data)
582{
583 mode_end((LttvTracefileStats *)call_data);
584 return FALSE;
585}
586
587
588gboolean after_soft_irq_exit(void *hook_data, void *call_data)
589{
590 update_event_tree((LttvTracefileStats *)call_data);
591 return FALSE;
592}
593
14236daa 594gboolean before_function_entry(void *hook_data, void *call_data)
595{
596 mode_end((LttvTracefileStats *)call_data);
597 return FALSE;
598}
599
600gboolean after_function_entry(void *hook_data, void *call_data)
601{
602 update_event_tree((LttvTracefileStats *)call_data);
603 return FALSE;
604}
605
606gboolean before_function_exit(void *hook_data, void *call_data)
607{
608 mode_end((LttvTracefileStats *)call_data);
609 return FALSE;
610}
611
612gboolean after_function_exit(void *hook_data, void *call_data)
613{
614 update_event_tree((LttvTracefileStats *)call_data);
615 return FALSE;
616}
617
faf074a3 618
b445142a 619gboolean before_schedchange(void *hook_data, void *call_data)
620{
b445142a 621 LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
622
348c6ba8 623 LttvTraceState *ts = (LttvTraceState*)tfcs->parent.parent.t_context;
624
eed2ef37 625 LttEvent *e = ltt_tracefile_get_event(tfcs->parent.parent.tf);
626
d052ffc3 627 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
eed2ef37 628
d7cf605c 629 guint pid_in, pid_out;
630
631 gint state_out;
b445142a 632
633 LttvProcessState *process;
634
eed2ef37 635 pid_out = ltt_event_get_unsigned(e, thf->f1);
636 pid_in = ltt_event_get_unsigned(e, thf->f2);
d7cf605c 637 state_out = ltt_event_get_int(e, thf->f3);
b445142a 638
639 /* compute the time for the process to schedule out */
640
641 mode_change(tfcs);
642
643 /* get the information for the process scheduled in */
644
348c6ba8 645 process = lttv_state_find_process_or_create(ts,
646 ANY_CPU, pid_in, &tfcs->parent.parent.timestamp);
b445142a 647
c0cb4d12 648 guint cpu = tfcs->parent.cpu;
649
348c6ba8 650 find_event_tree(tfcs, process->pid_time,
c0cb4d12 651 cpu,
14236daa 652 process->current_function,
b445142a 653 process->state->t, process->state->n, &(tfcs->current_events_tree),
654 &(tfcs->current_event_types_tree));
655
656 /* compute the time waiting for the process to schedule in */
657
658 mode_change(tfcs);
659 return FALSE;
660}
661
662
663gboolean process_fork(void *hook_data, void *call_data)
664{
665 /* nothing to do for now */
666 return FALSE;
667}
668
669
670gboolean process_exit(void *hook_data, void *call_data)
671{
672 /* We should probably exit all modes here or we could do that at
673 schedule out. */
674 return FALSE;
675}
676
eed2ef37 677gboolean process_free(void *hook_data, void *call_data)
678{
679 return FALSE;
680}
b445142a 681
682gboolean every_event(void *hook_data, void *call_data)
683{
684 LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
685
eed2ef37 686 LttEvent *e = ltt_tracefile_get_event(tfcs->parent.parent.tf);
687
b445142a 688 LttvAttributeValue v;
689
690 /* The current branch corresponds to the tracefile/process/interrupt state.
691 Statistics are added within it, to count the number of events of this
692 type occuring in this context. A quark has been pre-allocated for each
693 event type and is used as name. */
694
695 lttv_attribute_find(tfcs->current_event_types_tree,
eed2ef37 696 ltt_eventtype_name(ltt_event_eventtype(e)),
b445142a 697 LTTV_UINT, &v);
698 (*(v.v_uint))++;
699 return FALSE;
700}
701
702
f95bc830 703void
69374af5 704lttv_stats_sum_trace(LttvTraceStats *self, LttvAttribute *ts_stats)
b445142a 705{
d3e01c7a 706 LttvAttribute *sum_container = self->stats;
b445142a 707
b445142a 708 LttvAttributeType type;
709
710 LttvAttributeValue value;
711
712 LttvAttributeName name;
713
c0cb4d12 714 gboolean is_named;
715
b445142a 716 unsigned sum;
717
69374af5 718 int trace_is_summed;
719
f95bc830 720 int i, j, k, l, m, nb_process, nb_cpu, nb_mode_type, nb_submode,
3813c77b 721 nb_event_type, nf, nb_functions;
b445142a 722
723 LttvAttribute *main_tree, *processes_tree, *process_tree, *cpus_tree,
724 *cpu_tree, *mode_tree, *mode_types_tree, *submodes_tree,
725 *submode_tree, *event_types_tree, *mode_events_tree,
3813c77b 726 *cpu_functions_tree,
727 *function_tree,
728 *function_mode_types_tree,
729 *trace_cpu_tree;
f95bc830 730
d3e01c7a 731 main_tree = sum_container;
f95bc830 732
d3e01c7a 733 lttv_attribute_find(sum_container,
734 LTTV_STATS_SUMMED,
735 LTTV_UINT, &value);
69374af5 736 trace_is_summed = *(value.v_uint);
f95bc830 737 *(value.v_uint) = 1;
738
739 processes_tree = lttv_attribute_find_subdir(main_tree,
d3e01c7a 740 LTTV_STATS_PROCESSES);
f95bc830 741 nb_process = lttv_attribute_get_number(processes_tree);
742
743 for(i = 0 ; i < nb_process ; i++) {
c0cb4d12 744 type = lttv_attribute_get(processes_tree, i, &name, &value, &is_named);
f95bc830 745 process_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
746
747 cpus_tree = lttv_attribute_find_subdir(process_tree, LTTV_STATS_CPU);
f95bc830 748 nb_cpu = lttv_attribute_get_number(cpus_tree);
749
750 for(j = 0 ; j < nb_cpu ; j++) {
c0cb4d12 751 type = lttv_attribute_get(cpus_tree, j, &name, &value, &is_named);
f95bc830 752 cpu_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
753
f95bc830 754 trace_cpu_tree = lttv_attribute_find_subdir(main_tree, LTTV_STATS_CPU);
c0cb4d12 755 trace_cpu_tree = lttv_attribute_find_subdir_unnamed(trace_cpu_tree, name);
3813c77b 756 cpu_functions_tree = lttv_attribute_find_subdir(cpu_tree,
757 LTTV_STATS_FUNCTIONS);
758 nb_functions = lttv_attribute_get_number(cpu_functions_tree);
759
760 for(nf=0; nf < nb_functions; nf++) {
c0cb4d12 761 type = lttv_attribute_get(cpu_functions_tree, nf, &name, &value,
762 &is_named);
3813c77b 763 function_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
764 function_mode_types_tree = lttv_attribute_find_subdir(function_tree,
765 LTTV_STATS_MODE_TYPES);
766 nb_mode_type = lttv_attribute_get_number(function_mode_types_tree);
767 for(k = 0 ; k < nb_mode_type ; k++) {
c0cb4d12 768 type = lttv_attribute_get(function_mode_types_tree, k, &name, &value,
769 &is_named);
3813c77b 770 mode_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
771
772 submodes_tree = lttv_attribute_find_subdir(mode_tree,
773 LTTV_STATS_SUBMODES);
774 mode_events_tree = lttv_attribute_find_subdir(mode_tree,
775 LTTV_STATS_EVENTS);
776 mode_types_tree = lttv_attribute_find_subdir(mode_tree,
777 LTTV_STATS_MODE_TYPES);
778
779 nb_submode = lttv_attribute_get_number(submodes_tree);
780
781 for(l = 0 ; l < nb_submode ; l++) {
c0cb4d12 782 type = lttv_attribute_get(submodes_tree, l, &name, &value,
783 &is_named);
3813c77b 784 submode_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
785
786 event_types_tree = lttv_attribute_find_subdir(submode_tree,
787 LTTV_STATS_EVENT_TYPES);
788 nb_event_type = lttv_attribute_get_number(event_types_tree);
789
790 sum = 0;
791 for(m = 0 ; m < nb_event_type ; m++) {
c0cb4d12 792 type = lttv_attribute_get(event_types_tree, m, &name, &value,
793 &is_named);
3813c77b 794 sum += *(value.v_uint);
795 }
796 lttv_attribute_find(submode_tree, LTTV_STATS_EVENTS_COUNT,
797 LTTV_UINT, &value);
798 *(value.v_uint) = sum;
799
c0cb4d12 800 type = lttv_attribute_get(submodes_tree, l, &name, &value,
801 &is_named);
3813c77b 802 submode_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
69374af5 803 if(!trace_is_summed) {
804 lttv_attribute_recursive_add(mode_events_tree, event_types_tree);
805 lttv_attribute_recursive_add(mode_types_tree, submode_tree);
806 }
3813c77b 807 }
69374af5 808 if(!trace_is_summed) {
69374af5 809 lttv_attribute_recursive_add(function_tree, mode_types_tree);
810 }
3813c77b 811 }
65c2c8a0 812 if(!trace_is_summed) {
813 lttv_attribute_recursive_add(cpu_tree, function_tree);
814 lttv_attribute_recursive_add(process_tree, function_tree);
815 lttv_attribute_recursive_add(trace_cpu_tree, function_tree);
816 lttv_attribute_recursive_add(main_tree, function_tree);
817 }
818 lttv_attribute_recursive_add(ts_stats, function_tree);
69374af5 819 }
b445142a 820 }
f95bc830 821 }
822}
823
824
d3e01c7a 825gboolean lttv_stats_sum_traceset_hook(void *hook_data, void *call_data)
826{
827 lttv_stats_sum_traceset((LttvTracesetStats *)call_data);
828 return 0;
829}
830
f95bc830 831void
832lttv_stats_sum_traceset(LttvTracesetStats *self)
833{
834 LttvTraceset *traceset = self->parent.parent.ts;
d3e01c7a 835 LttvAttribute *sum_container = self->stats;
f95bc830 836
837 LttvTraceStats *tcs;
838
839 int i, nb_trace;
840
3813c77b 841 LttvAttribute *main_tree;
f95bc830 842
843 LttvAttributeValue value;
844
d3e01c7a 845 lttv_attribute_find(sum_container, LTTV_STATS_SUMMED,
f95bc830 846 LTTV_UINT, &value);
847 if(*(value.v_uint) != 0) return;
848 *(value.v_uint) = 1;
849
f95bc830 850 nb_trace = lttv_traceset_number(traceset);
851
852 for(i = 0 ; i < nb_trace ; i++) {
853 tcs = (LttvTraceStats *)(self->parent.parent.traces[i]);
69374af5 854 lttv_stats_sum_trace(tcs, self->stats);
855 // lttv_attribute_recursive_add(sum_container, tcs->stats);
b445142a 856 }
b445142a 857}
858
859
d3e01c7a 860// Hook wrapper. call_data is a traceset context.
00e74b69 861gboolean lttv_stats_hook_add_event_hooks(void *hook_data, void *call_data)
d3e01c7a 862{
863 LttvTracesetStats *tss = (LttvTracesetStats*)call_data;
864
865 lttv_stats_add_event_hooks(tss);
866
867 return 0;
868}
869
00e74b69 870void lttv_stats_add_event_hooks(LttvTracesetStats *self)
b445142a 871{
872 LttvTraceset *traceset = self->parent.parent.ts;
873
eed2ef37 874 guint i, j, k, l, nb_trace, nb_tracefile;
b445142a 875
b445142a 876 LttvTraceStats *ts;
877
878 LttvTracefileStats *tfs;
879
b445142a 880 GArray *hooks, *before_hooks, *after_hooks;
881
eed2ef37 882 LttvTraceHook *hook;
883
884 LttvTraceHookByFacility *thf;
b445142a 885
886 LttvAttributeValue val;
887
9d239bd9 888 gint ret;
2501204d 889 gint hn;
9d239bd9 890
b445142a 891 nb_trace = lttv_traceset_number(traceset);
892 for(i = 0 ; i < nb_trace ; i++) {
893 ts = (LttvTraceStats *)self->parent.parent.traces[i];
894
895 /* Find the eventtype id for the following events and register the
896 associated by id hooks. */
897
14236daa 898 hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 11);
899 g_array_set_size(hooks, 11);
2501204d 900 hn=0;
b445142a 901
9d239bd9 902 ret = lttv_trace_find_hook(ts->parent.parent.t,
f5d7967f 903 LTT_FACILITY_KERNEL_ARCH, LTT_EVENT_SYSCALL_ENTRY,
eed2ef37 904 LTT_FIELD_SYSCALL_ID, 0, 0,
2c82c4dc 905 before_syscall_entry, NULL,
2501204d 906 &g_array_index(hooks, LttvTraceHook, hn++));
907 if(ret) hn--;
b445142a 908
9d239bd9 909 ret = lttv_trace_find_hook(ts->parent.parent.t,
f5d7967f 910 LTT_FACILITY_KERNEL_ARCH, LTT_EVENT_SYSCALL_EXIT,
eed2ef37 911 0, 0, 0,
2c82c4dc 912 before_syscall_exit, NULL,
2501204d 913 &g_array_index(hooks, LttvTraceHook, hn++));
914 if(ret) hn--;
b445142a 915
9d239bd9 916 ret = lttv_trace_find_hook(ts->parent.parent.t,
eed2ef37 917 LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_ENTRY,
918 LTT_FIELD_TRAP_ID, 0, 0,
2c82c4dc 919 before_trap_entry, NULL,
2501204d 920 &g_array_index(hooks, LttvTraceHook, hn++));
921 if(ret) hn--;
b445142a 922
9d239bd9 923 ret = lttv_trace_find_hook(ts->parent.parent.t,
eed2ef37 924 LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_EXIT,
925 0, 0, 0,
2c82c4dc 926 before_trap_exit, NULL,
2501204d 927 &g_array_index(hooks, LttvTraceHook, hn++));
928 if(ret) hn--;
eed2ef37 929
9d239bd9 930 ret = lttv_trace_find_hook(ts->parent.parent.t,
eed2ef37 931 LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_ENTRY,
932 LTT_FIELD_IRQ_ID, 0, 0,
2c82c4dc 933 before_irq_entry, NULL,
2501204d 934 &g_array_index(hooks, LttvTraceHook, hn++));
935 if(ret) hn--;
eed2ef37 936
9d239bd9 937 ret = lttv_trace_find_hook(ts->parent.parent.t,
eed2ef37 938 LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_EXIT,
939 0, 0, 0,
2c82c4dc 940 before_irq_exit, NULL,
2501204d 941 &g_array_index(hooks, LttvTraceHook, hn++));
942 if(ret) hn--;
eed2ef37 943
faf074a3 944 ret = lttv_trace_find_hook(ts->parent.parent.t,
945 LTT_FACILITY_KERNEL, LTT_EVENT_SOFT_IRQ_ENTRY,
946 LTT_FIELD_SOFT_IRQ_ID, 0, 0,
947 before_soft_irq_entry, NULL,
2501204d 948 &g_array_index(hooks, LttvTraceHook, hn++));
949 if(ret) hn--;
faf074a3 950
951 ret = lttv_trace_find_hook(ts->parent.parent.t,
952 LTT_FACILITY_KERNEL, LTT_EVENT_SOFT_IRQ_EXIT,
953 0, 0, 0,
954 before_soft_irq_exit, NULL,
2501204d 955 &g_array_index(hooks, LttvTraceHook, hn++));
956 if(ret) hn--;
faf074a3 957
9d239bd9 958 ret = lttv_trace_find_hook(ts->parent.parent.t,
eed2ef37 959 LTT_FACILITY_PROCESS, LTT_EVENT_SCHEDCHANGE,
960 LTT_FIELD_OUT, LTT_FIELD_IN, LTT_FIELD_OUT_STATE,
2c82c4dc 961 before_schedchange, NULL,
2501204d 962 &g_array_index(hooks, LttvTraceHook, hn++));
963 if(ret) hn--;
14236daa 964
965 ret = lttv_trace_find_hook(ts->parent.parent.t,
966 LTT_FACILITY_USER_GENERIC, LTT_EVENT_FUNCTION_ENTRY,
967 LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE, 0,
968 before_function_entry, NULL,
969 &g_array_index(hooks, LttvTraceHook, hn++));
970 if(ret) hn--;
971
972 ret = lttv_trace_find_hook(ts->parent.parent.t,
973 LTT_FACILITY_USER_GENERIC, LTT_EVENT_FUNCTION_EXIT,
974 LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE, 0,
975 before_function_exit, NULL,
976 &g_array_index(hooks, LttvTraceHook, hn++));
977 if(ret) hn--;
978
2501204d 979 g_array_set_size(hooks, hn);
b445142a 980
981 before_hooks = hooks;
982
14236daa 983 hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 13);
984 g_array_set_size(hooks, 13);
2501204d 985 hn=0;
b445142a 986
9d239bd9 987 ret = lttv_trace_find_hook(ts->parent.parent.t,
f5d7967f 988 LTT_FACILITY_KERNEL_ARCH, LTT_EVENT_SYSCALL_ENTRY,
eed2ef37 989 LTT_FIELD_SYSCALL_ID, 0, 0,
2c82c4dc 990 after_syscall_entry, NULL,
2501204d 991 &g_array_index(hooks, LttvTraceHook, hn++));
992 if(ret) hn--;
b445142a 993
9d239bd9 994 ret = lttv_trace_find_hook(ts->parent.parent.t,
f5d7967f 995 LTT_FACILITY_KERNEL_ARCH, LTT_EVENT_SYSCALL_EXIT,
eed2ef37 996 0, 0, 0,
2c82c4dc 997 after_syscall_exit, NULL,
2501204d 998 &g_array_index(hooks, LttvTraceHook, hn++));
999 if(ret) hn--;
b445142a 1000
9d239bd9 1001 ret = lttv_trace_find_hook(ts->parent.parent.t,
eed2ef37 1002 LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_ENTRY,
1003 LTT_FIELD_TRAP_ID, 0, 0,
2c82c4dc 1004 after_trap_entry, NULL,
2501204d 1005 &g_array_index(hooks, LttvTraceHook, hn++));
1006 if(ret) hn--;
eed2ef37 1007
9d239bd9 1008 ret = lttv_trace_find_hook(ts->parent.parent.t,
eed2ef37 1009 LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_EXIT,
1010 0, 0, 0,
2c82c4dc 1011 after_trap_exit, NULL,
2501204d 1012 &g_array_index(hooks, LttvTraceHook, hn++));
1013 if(ret) hn--;
b445142a 1014
9d239bd9 1015 ret = lttv_trace_find_hook(ts->parent.parent.t,
eed2ef37 1016 LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_ENTRY,
1017 LTT_FIELD_IRQ_ID, 0, 0,
2c82c4dc 1018 after_irq_entry, NULL,
2501204d 1019 &g_array_index(hooks, LttvTraceHook, hn++));
1020 if(ret) hn--;
b445142a 1021
9d239bd9 1022 ret = lttv_trace_find_hook(ts->parent.parent.t,
eed2ef37 1023 LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_EXIT,
1024 0, 0, 0,
2c82c4dc 1025 after_irq_exit, NULL,
2501204d 1026 &g_array_index(hooks, LttvTraceHook, hn++));
1027 if(ret) hn--;
b445142a 1028
faf074a3 1029 ret = lttv_trace_find_hook(ts->parent.parent.t,
1030 LTT_FACILITY_KERNEL, LTT_EVENT_SOFT_IRQ_ENTRY,
1031 LTT_FIELD_SOFT_IRQ_ID, 0, 0,
1032 after_irq_entry, NULL,
2501204d 1033 &g_array_index(hooks, LttvTraceHook, hn++));
1034 if(ret) hn--;
faf074a3 1035
1036 ret = lttv_trace_find_hook(ts->parent.parent.t,
1037 LTT_FACILITY_KERNEL, LTT_EVENT_SOFT_IRQ_EXIT,
1038 0, 0, 0,
1039 after_soft_irq_exit, NULL,
2501204d 1040 &g_array_index(hooks, LttvTraceHook, hn++));
1041 if(ret) hn--;
b445142a 1042
9d239bd9 1043 ret = lttv_trace_find_hook(ts->parent.parent.t,
eed2ef37 1044 LTT_FACILITY_PROCESS, LTT_EVENT_FORK,
1045 LTT_FIELD_PARENT_PID, LTT_FIELD_CHILD_PID, 0,
2c82c4dc 1046 process_fork, NULL,
2501204d 1047 &g_array_index(hooks, LttvTraceHook, hn++));
1048 if(ret) hn--;
b445142a 1049
9d239bd9 1050 ret = lttv_trace_find_hook(ts->parent.parent.t,
eed2ef37 1051 LTT_FACILITY_PROCESS, LTT_EVENT_EXIT,
1052 LTT_FIELD_PID, 0, 0,
2c82c4dc 1053 process_exit, NULL,
2501204d 1054 &g_array_index(hooks, LttvTraceHook, hn++));
1055 if(ret) hn--;
eed2ef37 1056
9d239bd9 1057 ret = lttv_trace_find_hook(ts->parent.parent.t,
eed2ef37 1058 LTT_FACILITY_PROCESS, LTT_EVENT_FREE,
1059 LTT_FIELD_PID, 0, 0,
2c82c4dc 1060 process_free, NULL,
2501204d 1061 &g_array_index(hooks, LttvTraceHook, hn++));
1062 if(ret) hn--;
eed2ef37 1063
14236daa 1064 ret = lttv_trace_find_hook(ts->parent.parent.t,
1065 LTT_FACILITY_USER_GENERIC, LTT_EVENT_FUNCTION_ENTRY,
1066 LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE, 0,
1067 after_function_entry, NULL,
1068 &g_array_index(hooks, LttvTraceHook, hn++));
1069 if(ret) hn--;
1070
1071 ret = lttv_trace_find_hook(ts->parent.parent.t,
1072 LTT_FACILITY_USER_GENERIC, LTT_EVENT_FUNCTION_EXIT,
1073 LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE, 0,
1074 after_function_exit, NULL,
1075 &g_array_index(hooks, LttvTraceHook, hn++));
1076 if(ret) hn--;
1077
2501204d 1078 g_array_set_size(hooks, hn);
b445142a 1079
1080 after_hooks = hooks;
1081
359b2948 1082 /* Add these hooks to each event_by_id hooks list */
b445142a 1083
eed2ef37 1084 nb_tracefile = ts->parent.parent.tracefiles->len;
b445142a 1085
dbb7bb09 1086 for(j = 0 ; j < nb_tracefile ; j++) {
d7cf605c 1087 tfs = LTTV_TRACEFILE_STATS(g_array_index(ts->parent.parent.tracefiles,
1088 LttvTracefileContext*, j));
359b2948 1089 lttv_hooks_add(tfs->parent.parent.event, every_event, NULL,
1090 LTTV_PRIO_DEFAULT);
b445142a 1091
1092 for(k = 0 ; k < before_hooks->len ; k++) {
eed2ef37 1093 hook = &g_array_index(before_hooks, LttvTraceHook, k);
1094 for(l = 0; l<hook->fac_list->len;l++) {
1095 thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
1096 lttv_hooks_add(
1097 lttv_hooks_by_id_find(tfs->parent.parent.event_by_id, thf->id),
1098 thf->h,
d052ffc3 1099 thf,
eed2ef37 1100 LTTV_PRIO_STATS_BEFORE_STATE);
1101 }
b445142a 1102 }
1103 for(k = 0 ; k < after_hooks->len ; k++) {
eed2ef37 1104 hook = &g_array_index(after_hooks, LttvTraceHook, k);
1105 for(l = 0; l<hook->fac_list->len;l++) {
1106 thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
1107 lttv_hooks_add(
1108 lttv_hooks_by_id_find(tfs->parent.parent.event_by_id, thf->id),
1109 thf->h,
d052ffc3 1110 thf,
eed2ef37 1111 LTTV_PRIO_STATS_AFTER_STATE);
1112 }
b445142a 1113 }
1114 }
1115 lttv_attribute_find(self->parent.parent.a, LTTV_STATS_BEFORE_HOOKS,
1116 LTTV_POINTER, &val);
1117 *(val.v_pointer) = before_hooks;
1118 lttv_attribute_find(self->parent.parent.a, LTTV_STATS_AFTER_HOOKS,
1119 LTTV_POINTER, &val);
1120 *(val.v_pointer) = after_hooks;
1121 }
b445142a 1122}
1123
d3e01c7a 1124// Hook wrapper. call_data is a traceset context.
00e74b69 1125gboolean lttv_stats_hook_remove_event_hooks(void *hook_data, void *call_data)
d3e01c7a 1126{
1127 LttvTracesetStats *tss = (LttvTracesetStats*)call_data;
1128
1129 lttv_stats_remove_event_hooks(tss);
1130
1131 return 0;
1132}
b445142a 1133
00e74b69 1134void lttv_stats_remove_event_hooks(LttvTracesetStats *self)
b445142a 1135{
1136 LttvTraceset *traceset = self->parent.parent.ts;
1137
eed2ef37 1138 guint i, j, k, l, nb_trace, nb_tracefile;
b445142a 1139
1140 LttvTraceStats *ts;
1141
1142 LttvTracefileStats *tfs;
1143
1144 void *hook_data;
1145
1146 GArray *before_hooks, *after_hooks;
1147
eed2ef37 1148 LttvTraceHook *hook;
1149
1150 LttvTraceHookByFacility *thf;
b445142a 1151
1152 LttvAttributeValue val;
1153
1154 nb_trace = lttv_traceset_number(traceset);
1155 for(i = 0 ; i < nb_trace ; i++) {
ae80b609 1156 ts = (LttvTraceStats*)self->parent.parent.traces[i];
b445142a 1157 lttv_attribute_find(self->parent.parent.a, LTTV_STATS_BEFORE_HOOKS,
1158 LTTV_POINTER, &val);
1159 before_hooks = *(val.v_pointer);
1160 lttv_attribute_find(self->parent.parent.a, LTTV_STATS_AFTER_HOOKS,
1161 LTTV_POINTER, &val);
1162 after_hooks = *(val.v_pointer);
1163
359b2948 1164 /* Remove these hooks from each event_by_id hooks list */
b445142a 1165
eed2ef37 1166 nb_tracefile = ts->parent.parent.tracefiles->len;
b445142a 1167
dbb7bb09 1168 for(j = 0 ; j < nb_tracefile ; j++) {
cb03932a 1169 tfs = LTTV_TRACEFILE_STATS(g_array_index(ts->parent.parent.tracefiles,
1170 LttvTracefileContext*, j));
359b2948 1171 lttv_hooks_remove_data(tfs->parent.parent.event, every_event,
b445142a 1172 NULL);
1173
1174 for(k = 0 ; k < before_hooks->len ; k++) {
eed2ef37 1175 hook = &g_array_index(before_hooks, LttvTraceHook, k);
1176 for(l = 0 ; l < hook->fac_list->len ; l++) {
1177 thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
1178 lttv_hooks_remove_data(
1179 lttv_hooks_by_id_find(tfs->parent.parent.event_by_id, thf->id),
1180 thf->h,
d052ffc3 1181 thf);
eed2ef37 1182 }
b445142a 1183 }
1184 for(k = 0 ; k < after_hooks->len ; k++) {
eed2ef37 1185 hook = &g_array_index(after_hooks, LttvTraceHook, k);
1186 for(l = 0 ; l < hook->fac_list->len ; l++) {
1187 thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
1188 lttv_hooks_remove_data(
1189 lttv_hooks_by_id_find(tfs->parent.parent.event_by_id, thf->id),
1190 thf->h,
d052ffc3 1191 thf);
eed2ef37 1192 }
b445142a 1193 }
1194 }
2a2fa4f0 1195 g_debug("lttv_stats_remove_event_hooks()");
b445142a 1196 g_array_free(before_hooks, TRUE);
1197 g_array_free(after_hooks, TRUE);
1198 }
9f797243 1199}
08b1c66e 1200
1201
1202static void module_init()
1203{
1204 LTTV_STATS_PROCESS_UNKNOWN = g_quark_from_string("unknown process");
1205 LTTV_STATS_PROCESSES = g_quark_from_string("processes");
1206 LTTV_STATS_CPU = g_quark_from_string("cpu");
1207 LTTV_STATS_MODE_TYPES = g_quark_from_string("mode_types");
1208 LTTV_STATS_MODES = g_quark_from_string("modes");
1209 LTTV_STATS_SUBMODES = g_quark_from_string("submodes");
14236daa 1210 LTTV_STATS_FUNCTIONS = g_quark_from_string("functions");
08b1c66e 1211 LTTV_STATS_EVENT_TYPES = g_quark_from_string("event_types");
1212 LTTV_STATS_CPU_TIME = g_quark_from_string("cpu time");
1213 LTTV_STATS_ELAPSED_TIME = g_quark_from_string("elapsed time");
1214 LTTV_STATS_EVENTS = g_quark_from_string("events");
1215 LTTV_STATS_EVENTS_COUNT = g_quark_from_string("events count");
1216 LTTV_STATS_BEFORE_HOOKS = g_quark_from_string("saved stats before hooks");
1217 LTTV_STATS_AFTER_HOOKS = g_quark_from_string("saved stats after hooks");
f95bc830 1218 LTTV_STATS_USE_COUNT = g_quark_from_string("stats_use_count");
1219 LTTV_STATS = g_quark_from_string("statistics");
1220 LTTV_STATS_TRACEFILES = g_quark_from_string("tracefiles statistics");
1221 LTTV_STATS_SUMMED = g_quark_from_string("statistics summed");
08b1c66e 1222}
1223
1224static void module_destroy()
1225{
1226}
1227
1228
1229LTTV_MODULE("stats", "Compute processes statistics", \
1230 "Accumulate statistics for event types, processes and CPUs", \
1231 module_init, module_destroy, "state");
f95bc830 1232
1233/* Change the places where stats are called (create/read/write stats)
1234
1235 Check for options in batchtest.c to reduce writing and see what tests are
1236 best candidates for performance analysis. Once OK, commit, move to main
1237 and run tests. Update the gui for statistics. */
This page took 0.095712 seconds and 4 git commands to generate.