1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Michel Dagenais
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;
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.
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,
24 #include <lttv/module.h>
25 #include <lttv/stats.h>
26 #include <lttv/lttv.h>
27 #include <lttv/attribute.h>
28 #include <ltt/facility.h>
29 #include <ltt/trace.h>
30 #include <ltt/event.h>
34 #define MAX_64_HEX_STRING_LEN 19
37 LTTV_STATS_PROCESS_UNKNOWN
,
40 LTTV_STATS_MODE_TYPES
,
44 LTTV_STATS_EVENT_TYPES
,
46 LTTV_STATS_CUMULATIVE_CPU_TIME
,
47 LTTV_STATS_ELAPSED_TIME
,
49 LTTV_STATS_EVENTS_COUNT
,
52 LTTV_STATS_TRACEFILES
,
54 LTTV_STATS_BEFORE_HOOKS
,
55 LTTV_STATS_AFTER_HOOKS
;
58 find_event_tree(LttvTracefileStats
*tfcs
, GQuark pid_time
, guint cpu
,
60 GQuark mode
, GQuark sub_mode
, LttvAttribute
**events_tree
,
61 LttvAttribute
**event_types_tree
);
64 static void lttv_stats_init(LttvTracesetStats
*self
)
66 guint i
, j
, nb_trace
, nb_tracefile
;
72 LttvTracefileContext
*tfc
;
74 LttvTracefileContext
**tfs
;
75 LttvTracefileStats
*tfcs
;
77 LttTime timestamp
= {0,0};
85 LttvTraceset
*ts
= self
->parent
.parent
.ts
;
87 self
->stats
= lttv_attribute_find_subdir(
88 lttv_traceset_attribute(self
->parent
.parent
.ts
),
90 lttv_attribute_find(lttv_traceset_attribute(self
->parent
.parent
.ts
),
95 if(*(v
.v_uint
) == 1) {
96 g_assert(lttv_attribute_get_number(self
->stats
) == 0);
99 nb_trace
= lttv_traceset_number(ts
);
101 for(i
= 0 ; i
< nb_trace
; i
++) {
102 tc
= self
->parent
.parent
.traces
[i
];
103 tcs
= LTTV_TRACE_STATS(tc
);
105 tcs
->stats
= lttv_attribute_find_subdir(tcs
->parent
.parent
.t_a
,LTTV_STATS
);
106 tracefiles_stats
= lttv_attribute_find_subdir(tcs
->parent
.parent
.t_a
,
107 LTTV_STATS_TRACEFILES
);
108 lttv_attribute_find(tcs
->parent
.parent
.t_a
, LTTV_STATS_USE_COUNT
,
112 if(*(v
.v_uint
) == 1) {
113 g_assert(lttv_attribute_get_number(tcs
->stats
) == 0);
116 nb_tracefile
= tc
->tracefiles
->len
;
118 for(j
= 0 ; j
< nb_tracefile
; j
++) {
119 tfs
= &g_array_index(tc
->tracefiles
,
120 LttvTracefileContext
*, j
);
121 tfcs
= LTTV_TRACEFILE_STATS(*tfs
);
122 tfcs
->stats
= lttv_attribute_find_subdir(tracefiles_stats
,
123 ltt_tracefile_long_name(tfcs
->parent
.parent
.tf
));
124 guint cpu
= tfcs
->parent
.cpu
;
125 find_event_tree(tfcs
, LTTV_STATS_PROCESS_UNKNOWN
,
128 LTTV_STATE_MODE_UNKNOWN
,
129 LTTV_STATE_SUBMODE_UNKNOWN
, &tfcs
->current_events_tree
,
130 &tfcs
->current_event_types_tree
);
136 static void lttv_stats_fini(LttvTracesetStats
*self
)
138 guint i
, j
, nb_trace
, nb_tracefile
;
142 LttvTraceContext
*tc
;
146 LttvTracefileContext
*tfc
;
148 LttvTracefileStats
*tfcs
;
150 LttTime timestamp
= {0,0};
152 LttvAttributeValue v
;
154 LttvAttribute
*tracefiles_stats
;
156 lttv_attribute_find(self
->parent
.parent
.ts_a
, LTTV_STATS_USE_COUNT
,
160 if(*(v
.v_uint
) == 0) {
161 lttv_attribute_remove_by_name(self
->parent
.parent
.ts_a
, LTTV_STATS
);
165 ts
= self
->parent
.parent
.ts
;
166 nb_trace
= lttv_traceset_number(ts
);
168 for(i
= 0 ; i
< nb_trace
; i
++) {
169 tcs
= (LttvTraceStats
*)(tc
= (LTTV_TRACESET_CONTEXT(self
)->traces
[i
]));
171 lttv_attribute_find(tcs
->parent
.parent
.t_a
, LTTV_STATS_USE_COUNT
,
175 if(*(v
.v_uint
) == 0) {
176 lttv_attribute_remove_by_name(tcs
->parent
.parent
.t_a
,LTTV_STATS
);
177 tracefiles_stats
= lttv_attribute_find_subdir(tcs
->parent
.parent
.t_a
,
178 LTTV_STATS_TRACEFILES
);
179 lttv_attribute_remove_by_name(tcs
->parent
.parent
.t_a
,
180 LTTV_STATS_TRACEFILES
);
184 nb_tracefile
= tc
->tracefiles
->len
;
186 for(j
= 0 ; j
< nb_tracefile
; j
++) {
187 tfc
= g_array_index(tc
->tracefiles
,
188 LttvTracefileContext
*, j
);
189 tfcs
= (LttvTracefileStats
*)tfc
;
191 tfcs
->current_events_tree
= NULL
;
192 tfcs
->current_event_types_tree
= NULL
;
198 void lttv_stats_reset(LttvTracesetStats
*self
)
200 lttv_stats_fini(self
);
201 lttv_stats_init(self
);
207 init(LttvTracesetStats
*self
, LttvTraceset
*ts
)
209 LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE
))->
210 init((LttvTracesetContext
*)self
, ts
);
212 lttv_stats_init(self
);
217 fini(LttvTracesetStats
*self
)
219 lttv_stats_fini(self
);
221 LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE
))->
222 fini((LttvTracesetContext
*)self
);
226 static LttvTracesetContext
*
227 new_traceset_context(LttvTracesetContext
*self
)
229 return LTTV_TRACESET_CONTEXT(g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
));
233 static LttvTraceContext
*
234 new_trace_context(LttvTracesetContext
*self
)
236 return LTTV_TRACE_CONTEXT(g_object_new(LTTV_TRACE_STATS_TYPE
, NULL
));
240 static LttvTracefileContext
*
241 new_tracefile_context(LttvTracesetContext
*self
)
243 return LTTV_TRACEFILE_CONTEXT(g_object_new(LTTV_TRACEFILE_STATS_TYPE
, NULL
));
248 traceset_stats_instance_init (GTypeInstance
*instance
, gpointer g_class
)
254 traceset_stats_finalize (LttvTracesetStats
*self
)
256 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE
))->
257 finalize(G_OBJECT(self
));
262 traceset_stats_class_init (LttvTracesetContextClass
*klass
)
264 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
266 gobject_class
->finalize
= (void (*)(GObject
*self
)) traceset_stats_finalize
;
267 klass
->init
= (void (*)(LttvTracesetContext
*self
, LttvTraceset
*ts
))init
;
268 klass
->fini
= (void (*)(LttvTracesetContext
*self
))fini
;
269 klass
->new_traceset_context
= new_traceset_context
;
270 klass
->new_trace_context
= new_trace_context
;
271 klass
->new_tracefile_context
= new_tracefile_context
;
276 lttv_traceset_stats_get_type(void)
278 static GType type
= 0;
280 static const GTypeInfo info
= {
281 sizeof (LttvTracesetStatsClass
),
282 NULL
, /* base_init */
283 NULL
, /* base_finalize */
284 (GClassInitFunc
) traceset_stats_class_init
, /* class_init */
285 NULL
, /* class_finalize */
286 NULL
, /* class_data */
287 sizeof (LttvTracesetStats
),
289 (GInstanceInitFunc
) traceset_stats_instance_init
, /* instance_init */
290 NULL
/* Value handling */
293 type
= g_type_register_static (LTTV_TRACESET_STATE_TYPE
,
294 "LttvTracesetStatsType",
302 trace_stats_instance_init (GTypeInstance
*instance
, gpointer g_class
)
308 trace_stats_finalize (LttvTraceStats
*self
)
310 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACE_STATE_TYPE
))->
311 finalize(G_OBJECT(self
));
316 trace_stats_class_init (LttvTraceContextClass
*klass
)
318 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
320 gobject_class
->finalize
= (void (*)(GObject
*self
)) trace_stats_finalize
;
325 lttv_trace_stats_get_type(void)
327 static GType type
= 0;
329 static const GTypeInfo info
= {
330 sizeof (LttvTraceStatsClass
),
331 NULL
, /* base_init */
332 NULL
, /* base_finalize */
333 (GClassInitFunc
) trace_stats_class_init
, /* class_init */
334 NULL
, /* class_finalize */
335 NULL
, /* class_data */
336 sizeof (LttvTraceStats
),
338 (GInstanceInitFunc
) trace_stats_instance_init
, /* instance_init */
339 NULL
/* Value handling */
342 type
= g_type_register_static (LTTV_TRACE_STATE_TYPE
,
343 "LttvTraceStatsType", &info
, 0);
350 tracefile_stats_instance_init (GTypeInstance
*instance
, gpointer g_class
)
356 tracefile_stats_finalize (LttvTracefileStats
*self
)
358 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACEFILE_STATE_TYPE
))->
359 finalize(G_OBJECT(self
));
364 tracefile_stats_class_init (LttvTracefileStatsClass
*klass
)
366 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
368 gobject_class
->finalize
= (void (*)(GObject
*self
)) tracefile_stats_finalize
;
373 lttv_tracefile_stats_get_type(void)
375 static GType type
= 0;
377 static const GTypeInfo info
= {
378 sizeof (LttvTracefileStatsClass
),
379 NULL
, /* base_init */
380 NULL
, /* base_finalize */
381 (GClassInitFunc
) tracefile_stats_class_init
, /* class_init */
382 NULL
, /* class_finalize */
383 NULL
, /* class_data */
384 sizeof (LttvTracefileStats
),
386 (GInstanceInitFunc
) tracefile_stats_instance_init
, /* instance_init */
387 NULL
/* Value handling */
390 type
= g_type_register_static (LTTV_TRACEFILE_STATE_TYPE
,
391 "LttvTracefileStatsType", &info
, 0);
398 find_event_tree(LttvTracefileStats
*tfcs
,
404 LttvAttribute
**events_tree
,
405 LttvAttribute
**event_types_tree
)
407 LttvAttribute
*a
, *prev_a
;
408 gchar fstring
[MAX_64_HEX_STRING_LEN
];
411 ret
= snprintf(fstring
, MAX_64_HEX_STRING_LEN
-1,
412 "0x%llX", function
) > 0;
414 fstring
[MAX_64_HEX_STRING_LEN
-1] = '\0';
416 LttvTraceStats
*tcs
= (LttvTraceStats
*)tfcs
->parent
.parent
.t_context
;
417 a
= lttv_attribute_find_subdir(tcs
->stats
, LTTV_STATS_PROCESSES
);
418 a
= lttv_attribute_find_subdir(a
, pid_time
);
419 a
= lttv_attribute_find_subdir(a
, LTTV_STATS_CPU
);
420 a
= lttv_attribute_find_subdir_unnamed(a
, cpu
);
421 a
= lttv_attribute_find_subdir(a
, LTTV_STATS_FUNCTIONS
);
422 a
= lttv_attribute_find_subdir(a
, g_quark_from_string(fstring
));
423 a
= lttv_attribute_find_subdir(a
, LTTV_STATS_MODE_TYPES
);
424 a
= lttv_attribute_find_subdir(a
, mode
);
425 a
= lttv_attribute_find_subdir(a
, LTTV_STATS_SUBMODES
);
426 a
= lttv_attribute_find_subdir(a
, sub_mode
);
428 a
= lttv_attribute_find_subdir(a
, LTTV_STATS_EVENT_TYPES
);
429 *event_types_tree
= a
;
433 /* Update the trace event tree for the specified cpu */
434 static void update_trace_event_tree(LttvTracefileStats
*tfcs
, guint cpu
)
436 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
437 LttvProcessState
*process
= ts
->running_process
[cpu
];
438 LttvExecutionState
*es
= process
->state
;
440 find_event_tree(tfcs
, process
->pid_time
,
442 process
->current_function
,
443 es
->t
, es
->n
, &(tfcs
->current_events_tree
),
444 &(tfcs
->current_event_types_tree
));
447 static void update_event_tree(LttvTracefileStats
*tfcs
)
449 update_trace_event_tree(tfcs
, tfcs
->parent
.cpu
);
452 static void mode_change(LttvTracefileStats
*tfcs
)
454 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
455 guint cpu
= tfcs
->parent
.cpu
;
456 LttvProcessState
*process
= ts
->running_process
[cpu
];
457 LttvAttributeValue cpu_time
, cum_cpu_time
;
461 if(process
->state
->s
== LTTV_STATE_RUN
&&
462 process
->state
->t
!= LTTV_STATE_MODE_UNKNOWN
)
463 delta
= ltt_time_sub(tfcs
->parent
.parent
.timestamp
,
464 process
->state
->change
);
466 delta
= ltt_time_zero
;
468 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_STATS_CPU_TIME
,
469 LTTV_TIME
, &cpu_time
);
470 *(cpu_time
.v_time
) = ltt_time_add(*(cpu_time
.v_time
), delta
);
472 process
->state
->cum_cpu_time
= ltt_time_add(process
->state
->cum_cpu_time
,
476 /* Note : every mode_end must come with a cumulative cpu time update in the
478 static void mode_end(LttvTracefileStats
*tfcs
)
480 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
481 guint cpu
= tfcs
->parent
.cpu
;
482 LttvProcessState
*process
= ts
->running_process
[cpu
];
483 LttvAttributeValue elapsed_time
, cpu_time
, cum_cpu_time
;
487 /* FIXME put there in case of a missing update after a state modification */
488 //update_event_tree(tfcs);
490 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_STATS_ELAPSED_TIME
,
491 LTTV_TIME
, &elapsed_time
);
493 if(process
->state
->t
!= LTTV_STATE_MODE_UNKNOWN
)
494 delta
= ltt_time_sub(tfcs
->parent
.parent
.timestamp
,
495 process
->state
->entry
);
497 delta
= ltt_time_zero
;
499 *(elapsed_time
.v_time
) = ltt_time_add(*(elapsed_time
.v_time
), delta
);
501 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_STATS_CPU_TIME
,
502 LTTV_TIME
, &cpu_time
);
504 /* if it is a running mode, we must count its cpu time */
505 if(process
->state
->s
== LTTV_STATE_RUN
&&
506 process
->state
->t
!= LTTV_STATE_MODE_UNKNOWN
)
507 delta
= ltt_time_sub(tfcs
->parent
.parent
.timestamp
,
508 process
->state
->change
);
510 delta
= ltt_time_zero
;
512 *(cpu_time
.v_time
) = ltt_time_add(*(cpu_time
.v_time
), delta
);
513 process
->state
->cum_cpu_time
= ltt_time_add(process
->state
->cum_cpu_time
,
516 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_STATS_CUMULATIVE_CPU_TIME
,
517 LTTV_TIME
, &cum_cpu_time
);
518 *(cum_cpu_time
.v_time
) = ltt_time_add(*(cum_cpu_time
.v_time
),
519 process
->state
->cum_cpu_time
);
523 static void after_mode_end(LttvTracefileStats
*tfcs
)
525 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
526 guint cpu
= tfcs
->parent
.cpu
;
527 LttvProcessState
*process
= ts
->running_process
[cpu
];
528 LttvAttributeValue cum_cpu_time
;
530 LttTime nested_delta
;
532 nested_delta
= process
->state
->cum_cpu_time
;
533 process
->state
->cum_cpu_time
= ltt_time_zero
; /* For after traceset hook */
535 update_event_tree(tfcs
);
537 process
->state
->cum_cpu_time
= ltt_time_add(process
->state
->cum_cpu_time
,
541 static gboolean
before_syscall_entry(void *hook_data
, void *call_data
)
543 mode_change((LttvTracefileStats
*)call_data
);
548 static gboolean
after_syscall_entry(void *hook_data
, void *call_data
)
550 update_event_tree((LttvTracefileStats
*)call_data
);
555 gboolean
before_syscall_exit(void *hook_data
, void *call_data
)
557 mode_end((LttvTracefileStats
*)call_data
);
562 static gboolean
after_syscall_exit(void *hook_data
, void *call_data
)
564 after_mode_end((LttvTracefileStats
*)call_data
);
569 gboolean
before_trap_entry(void *hook_data
, void *call_data
)
571 mode_change((LttvTracefileStats
*)call_data
);
576 static gboolean
after_trap_entry(void *hook_data
, void *call_data
)
578 update_event_tree((LttvTracefileStats
*)call_data
);
583 gboolean
before_trap_exit(void *hook_data
, void *call_data
)
585 mode_end((LttvTracefileStats
*)call_data
);
590 gboolean
after_trap_exit(void *hook_data
, void *call_data
)
592 after_mode_end((LttvTracefileStats
*)call_data
);
597 gboolean
before_irq_entry(void *hook_data
, void *call_data
)
599 mode_change((LttvTracefileStats
*)call_data
);
603 gboolean
after_irq_entry(void *hook_data
, void *call_data
)
605 update_event_tree((LttvTracefileStats
*)call_data
);
610 gboolean
before_irq_exit(void *hook_data
, void *call_data
)
612 mode_end((LttvTracefileStats
*)call_data
);
617 gboolean
after_irq_exit(void *hook_data
, void *call_data
)
619 after_mode_end((LttvTracefileStats
*)call_data
);
624 gboolean
before_soft_irq_entry(void *hook_data
, void *call_data
)
626 mode_change((LttvTracefileStats
*)call_data
);
630 gboolean
after_soft_irq_entry(void *hook_data
, void *call_data
)
632 update_event_tree((LttvTracefileStats
*)call_data
);
637 gboolean
before_soft_irq_exit(void *hook_data
, void *call_data
)
639 mode_end((LttvTracefileStats
*)call_data
);
644 gboolean
after_soft_irq_exit(void *hook_data
, void *call_data
)
646 after_mode_end((LttvTracefileStats
*)call_data
);
650 gboolean
before_function_entry(void *hook_data
, void *call_data
)
652 mode_change((LttvTracefileStats
*)call_data
);
656 gboolean
after_function_entry(void *hook_data
, void *call_data
)
658 update_event_tree((LttvTracefileStats
*)call_data
);
662 gboolean
before_function_exit(void *hook_data
, void *call_data
)
664 mode_end((LttvTracefileStats
*)call_data
);
668 gboolean
after_function_exit(void *hook_data
, void *call_data
)
670 after_mode_end((LttvTracefileStats
*)call_data
);
675 gboolean
before_schedchange(void *hook_data
, void *call_data
)
677 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
679 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
681 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
683 LttvTraceHookByFacility
*thf
= (LttvTraceHookByFacility
*)hook_data
;
685 guint pid_in
, pid_out
;
689 pid_out
= ltt_event_get_unsigned(e
, thf
->f1
);
690 pid_in
= ltt_event_get_unsigned(e
, thf
->f2
);
691 state_out
= ltt_event_get_int(e
, thf
->f3
);
693 /* compute the time for the process to schedule out */
699 gboolean
after_schedchange(void *hook_data
, void *call_data
)
701 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
703 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
705 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
707 LttvTraceHookByFacility
*thf
= (LttvTraceHookByFacility
*)hook_data
;
709 guint pid_in
, pid_out
;
713 LttvProcessState
*process
;
715 pid_out
= ltt_event_get_unsigned(e
, thf
->f1
);
716 pid_in
= ltt_event_get_unsigned(e
, thf
->f2
);
717 state_out
= ltt_event_get_int(e
, thf
->f3
);
719 /* get the information for the process scheduled in */
720 guint cpu
= tfcs
->parent
.cpu
;
721 process
= ts
->running_process
[cpu
];
723 find_event_tree(tfcs
, process
->pid_time
,
725 process
->current_function
,
726 process
->state
->t
, process
->state
->n
, &(tfcs
->current_events_tree
),
727 &(tfcs
->current_event_types_tree
));
729 /* compute the time waiting for the process to schedule in */
735 gboolean
process_fork(void *hook_data
, void *call_data
)
737 /* nothing to do for now */
742 gboolean
process_exit(void *hook_data
, void *call_data
)
744 /* We should probably exit all modes here or we could do that at
749 gboolean
before_enum_process_state(void *hook_data
, void *call_data
)
752 /* Broken : adds up time in the current process doing the dump */
753 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
755 after_mode_end(tfcs
);
761 gboolean
after_enum_process_state(void *hook_data
, void *call_data
)
763 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
764 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
765 LttvTraceState
*ts
= (LttvTraceState
*)tfc
->t_context
;
768 nb_cpus
= ltt_trace_get_num_cpu(ts
->parent
.t
);
769 for(i
=0; i
<nb_cpus
; i
++) {
770 update_trace_event_tree(tfcs
, i
);
775 static gboolean
after_statedump_end(void *hook_data
, void *call_data
)
777 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
778 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
779 LttvTraceState
*ts
= (LttvTraceState
*)tfc
->t_context
;
782 nb_cpus
= ltt_trace_get_num_cpu(ts
->parent
.t
);
783 for(i
=0; i
<nb_cpus
; i
++) {
784 update_trace_event_tree(tfcs
, i
);
789 gboolean
process_free(void *hook_data
, void *call_data
)
794 gboolean
every_event(void *hook_data
, void *call_data
)
796 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
798 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
800 LttvAttributeValue v
;
802 /* The current branch corresponds to the tracefile/process/interrupt state.
803 Statistics are added within it, to count the number of events of this
804 type occuring in this context. A quark has been pre-allocated for each
805 event type and is used as name. */
807 lttv_attribute_find(tfcs
->current_event_types_tree
,
808 ltt_eventtype_name(ltt_event_eventtype(e
)),
814 static void lttv_stats_cleanup_process_state(LttvTraceState
*ts
,
815 LttvProcessState
*process
)
817 LttvTraceStats
*tcs
= (LttvTraceStats
*)ts
;
818 LttvTracesetContext
*tsc
= ts
->parent
.ts_context
;
820 LttvTracefileStats
**tfs
= (LttvTracefileStats
**)
821 &g_array_index(ts
->parent
.tracefiles
, LttvTracefileContext
*,
823 int cleanup_empty
= 0;
824 LttTime nested_delta
= ltt_time_zero
;
825 /* FIXME : ok, this is a hack. The time is infinite here :( */
826 LttTime save_time
= (*tfs
)->parent
.parent
.timestamp
;
828 ltt_trace_time_span_get(ts
->parent
.t
, &start
, &end
);
829 (*tfs
)->parent
.parent
.timestamp
= end
;
832 if(ltt_time_compare(process
->state
->cum_cpu_time
, ltt_time_zero
) != 0) {
833 find_event_tree(*tfs
, process
->pid_time
,
835 process
->current_function
,
836 process
->state
->t
, process
->state
->n
, &((*tfs
)->current_events_tree
),
837 &((*tfs
)->current_event_types_tree
));
839 nested_delta
= process
->state
->cum_cpu_time
;
841 cleanup_empty
= lttv_state_pop_state_cleanup(process
,
842 (LttvTracefileState
*)*tfs
);
843 process
->state
->cum_cpu_time
= ltt_time_add(process
->state
->cum_cpu_time
,
846 } while(cleanup_empty
!= 1);
848 (*tfs
)->parent
.parent
.timestamp
= save_time
;
851 /* For each cpu, for each of their stacked states,
852 * perform sum of needed values. */
853 static void lttv_stats_cleanup_state(LttvTraceStats
*tcs
)
855 LttvTraceState
*ts
= (LttvTraceState
*)tcs
;
858 nb_cpus
= ltt_trace_get_num_cpu(ts
->parent
.t
);
860 for(i
=0; i
<nb_cpus
; i
++) {
861 lttv_stats_cleanup_process_state(ts
, ts
->running_process
[i
]);
866 lttv_stats_sum_trace(LttvTraceStats
*self
, LttvAttribute
*ts_stats
)
868 LttvAttribute
*sum_container
= self
->stats
;
870 LttvAttributeType type
;
872 LttvAttributeValue value
;
874 LttvAttributeName name
;
882 int i
, j
, k
, l
, m
, nb_process
, nb_cpu
, nb_mode_type
, nb_submode
,
883 nb_event_type
, nf
, nb_functions
;
885 LttvAttribute
*main_tree
, *processes_tree
, *process_tree
, *cpus_tree
,
886 *cpu_tree
, *mode_tree
, *mode_types_tree
, *submodes_tree
,
887 *submode_tree
, *event_types_tree
, *mode_events_tree
,
890 *function_mode_types_tree
,
894 main_tree
= sum_container
;
896 lttv_attribute_find(sum_container
,
899 trace_is_summed
= *(value
.v_uint
);
902 /* First cleanup the state : sum all stalled information (never ending
905 lttv_stats_cleanup_state(self
);
907 processes_tree
= lttv_attribute_find_subdir(main_tree
,
908 LTTV_STATS_PROCESSES
);
909 nb_process
= lttv_attribute_get_number(processes_tree
);
911 for(i
= 0 ; i
< nb_process
; i
++) {
912 type
= lttv_attribute_get(processes_tree
, i
, &name
, &value
, &is_named
);
913 process_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
915 cpus_tree
= lttv_attribute_find_subdir(process_tree
, LTTV_STATS_CPU
);
916 nb_cpu
= lttv_attribute_get_number(cpus_tree
);
918 for(j
= 0 ; j
< nb_cpu
; j
++) {
919 type
= lttv_attribute_get(cpus_tree
, j
, &name
, &value
, &is_named
);
920 cpu_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
922 trace_cpu_tree
= lttv_attribute_find_subdir(main_tree
, LTTV_STATS_CPU
);
923 trace_cpu_tree
= lttv_attribute_find_subdir_unnamed(trace_cpu_tree
, name
);
924 cpu_functions_tree
= lttv_attribute_find_subdir(cpu_tree
,
925 LTTV_STATS_FUNCTIONS
);
926 nb_functions
= lttv_attribute_get_number(cpu_functions_tree
);
928 for(nf
=0; nf
< nb_functions
; nf
++) {
929 type
= lttv_attribute_get(cpu_functions_tree
, nf
, &name
, &value
,
931 function_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
932 function_mode_types_tree
= lttv_attribute_find_subdir(function_tree
,
933 LTTV_STATS_MODE_TYPES
);
934 nb_mode_type
= lttv_attribute_get_number(function_mode_types_tree
);
935 for(k
= 0 ; k
< nb_mode_type
; k
++) {
936 type
= lttv_attribute_get(function_mode_types_tree
, k
, &name
, &value
,
938 mode_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
940 submodes_tree
= lttv_attribute_find_subdir(mode_tree
,
941 LTTV_STATS_SUBMODES
);
942 mode_events_tree
= lttv_attribute_find_subdir(mode_tree
,
944 mode_types_tree
= lttv_attribute_find_subdir(mode_tree
,
945 LTTV_STATS_MODE_TYPES
);
947 nb_submode
= lttv_attribute_get_number(submodes_tree
);
949 for(l
= 0 ; l
< nb_submode
; l
++) {
950 type
= lttv_attribute_get(submodes_tree
, l
, &name
, &value
,
952 submode_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
954 event_types_tree
= lttv_attribute_find_subdir(submode_tree
,
955 LTTV_STATS_EVENT_TYPES
);
956 nb_event_type
= lttv_attribute_get_number(event_types_tree
);
959 for(m
= 0 ; m
< nb_event_type
; m
++) {
960 type
= lttv_attribute_get(event_types_tree
, m
, &name
, &value
,
962 sum
+= *(value
.v_uint
);
964 lttv_attribute_find(submode_tree
, LTTV_STATS_EVENTS_COUNT
,
966 *(value
.v_uint
) = sum
;
968 type
= lttv_attribute_get(submodes_tree
, l
, &name
, &value
,
970 submode_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
971 if(!trace_is_summed
) {
972 lttv_attribute_recursive_add(mode_events_tree
, event_types_tree
);
973 lttv_attribute_recursive_add(mode_types_tree
, submode_tree
);
976 if(!trace_is_summed
) {
977 lttv_attribute_recursive_add(function_tree
, mode_types_tree
);
980 if(!trace_is_summed
) {
981 lttv_attribute_recursive_add(cpu_tree
, function_tree
);
982 lttv_attribute_recursive_add(process_tree
, function_tree
);
983 lttv_attribute_recursive_add(trace_cpu_tree
, function_tree
);
984 lttv_attribute_recursive_add(main_tree
, function_tree
);
986 lttv_attribute_recursive_add(ts_stats
, function_tree
);
993 gboolean
lttv_stats_sum_traceset_hook(void *hook_data
, void *call_data
)
995 lttv_stats_sum_traceset((LttvTracesetStats
*)call_data
);
1000 lttv_stats_sum_traceset(LttvTracesetStats
*self
)
1002 LttvTraceset
*traceset
= self
->parent
.parent
.ts
;
1003 LttvAttribute
*sum_container
= self
->stats
;
1005 LttvTraceStats
*tcs
;
1009 LttvAttribute
*main_tree
;
1011 LttvAttributeValue value
;
1013 lttv_attribute_find(sum_container
, LTTV_STATS_SUMMED
,
1015 if(*(value
.v_uint
) != 0) return;
1016 *(value
.v_uint
) = 1;
1018 nb_trace
= lttv_traceset_number(traceset
);
1020 for(i
= 0 ; i
< nb_trace
; i
++) {
1021 tcs
= (LttvTraceStats
*)(self
->parent
.parent
.traces
[i
]);
1022 lttv_stats_sum_trace(tcs
, self
->stats
);
1023 // lttv_attribute_recursive_add(sum_container, tcs->stats);
1028 // Hook wrapper. call_data is a traceset context.
1029 gboolean
lttv_stats_hook_add_event_hooks(void *hook_data
, void *call_data
)
1031 LttvTracesetStats
*tss
= (LttvTracesetStats
*)call_data
;
1033 lttv_stats_add_event_hooks(tss
);
1038 void lttv_stats_add_event_hooks(LttvTracesetStats
*self
)
1040 LttvTraceset
*traceset
= self
->parent
.parent
.ts
;
1042 guint i
, j
, k
, l
, nb_trace
, nb_tracefile
;
1046 LttvTracefileStats
*tfs
;
1048 GArray
*hooks
, *before_hooks
, *after_hooks
;
1050 LttvTraceHook
*hook
;
1052 LttvTraceHookByFacility
*thf
;
1054 LttvAttributeValue val
;
1059 nb_trace
= lttv_traceset_number(traceset
);
1060 for(i
= 0 ; i
< nb_trace
; i
++) {
1061 ts
= (LttvTraceStats
*)self
->parent
.parent
.traces
[i
];
1063 /* Find the eventtype id for the following events and register the
1064 associated by id hooks. */
1066 hooks
= g_array_sized_new(FALSE
, FALSE
, sizeof(LttvTraceHook
), 12);
1067 g_array_set_size(hooks
, 12);
1070 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1071 LTT_FACILITY_KERNEL_ARCH
, LTT_EVENT_SYSCALL_ENTRY
,
1072 LTT_FIELD_SYSCALL_ID
, 0, 0,
1073 before_syscall_entry
, NULL
,
1074 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1077 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1078 LTT_FACILITY_KERNEL_ARCH
, LTT_EVENT_SYSCALL_EXIT
,
1080 before_syscall_exit
, NULL
,
1081 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1084 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1085 LTT_FACILITY_KERNEL
, LTT_EVENT_TRAP_ENTRY
,
1086 LTT_FIELD_TRAP_ID
, 0, 0,
1087 before_trap_entry
, NULL
,
1088 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1091 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1092 LTT_FACILITY_KERNEL
, LTT_EVENT_TRAP_EXIT
,
1094 before_trap_exit
, NULL
,
1095 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1098 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1099 LTT_FACILITY_KERNEL
, LTT_EVENT_IRQ_ENTRY
,
1100 LTT_FIELD_IRQ_ID
, 0, 0,
1101 before_irq_entry
, NULL
,
1102 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1105 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1106 LTT_FACILITY_KERNEL
, LTT_EVENT_IRQ_EXIT
,
1108 before_irq_exit
, NULL
,
1109 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1112 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1113 LTT_FACILITY_KERNEL
, LTT_EVENT_SOFT_IRQ_ENTRY
,
1114 LTT_FIELD_SOFT_IRQ_ID
, 0, 0,
1115 before_soft_irq_entry
, NULL
,
1116 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1119 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1120 LTT_FACILITY_KERNEL
, LTT_EVENT_SOFT_IRQ_EXIT
,
1122 before_soft_irq_exit
, NULL
,
1123 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1126 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1127 LTT_FACILITY_PROCESS
, LTT_EVENT_SCHEDCHANGE
,
1128 LTT_FIELD_OUT
, LTT_FIELD_IN
, LTT_FIELD_OUT_STATE
,
1129 before_schedchange
, NULL
,
1130 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1133 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1134 LTT_FACILITY_USER_GENERIC
, LTT_EVENT_FUNCTION_ENTRY
,
1135 LTT_FIELD_THIS_FN
, LTT_FIELD_CALL_SITE
, 0,
1136 before_function_entry
, NULL
,
1137 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1140 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1141 LTT_FACILITY_USER_GENERIC
, LTT_EVENT_FUNCTION_EXIT
,
1142 LTT_FIELD_THIS_FN
, LTT_FIELD_CALL_SITE
, 0,
1143 before_function_exit
, NULL
,
1144 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1147 /* statedump-related hooks */
1148 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1149 LTT_FACILITY_STATEDUMP
, LTT_EVENT_ENUM_PROCESS_STATE
,
1150 LTT_FIELD_PID
, LTT_FIELD_PARENT_PID
, LTT_FIELD_NAME
,
1151 before_enum_process_state
, NULL
,
1152 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1155 g_array_set_size(hooks
, hn
);
1157 before_hooks
= hooks
;
1159 hooks
= g_array_sized_new(FALSE
, FALSE
, sizeof(LttvTraceHook
), 16);
1160 g_array_set_size(hooks
, 16);
1163 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1164 LTT_FACILITY_KERNEL_ARCH
, LTT_EVENT_SYSCALL_ENTRY
,
1165 LTT_FIELD_SYSCALL_ID
, 0, 0,
1166 after_syscall_entry
, NULL
,
1167 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1170 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1171 LTT_FACILITY_KERNEL_ARCH
, LTT_EVENT_SYSCALL_EXIT
,
1173 after_syscall_exit
, NULL
,
1174 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1177 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1178 LTT_FACILITY_KERNEL
, LTT_EVENT_TRAP_ENTRY
,
1179 LTT_FIELD_TRAP_ID
, 0, 0,
1180 after_trap_entry
, NULL
,
1181 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1184 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1185 LTT_FACILITY_KERNEL
, LTT_EVENT_TRAP_EXIT
,
1187 after_trap_exit
, NULL
,
1188 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1191 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1192 LTT_FACILITY_KERNEL
, LTT_EVENT_IRQ_ENTRY
,
1193 LTT_FIELD_IRQ_ID
, 0, 0,
1194 after_irq_entry
, NULL
,
1195 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1198 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1199 LTT_FACILITY_KERNEL
, LTT_EVENT_IRQ_EXIT
,
1201 after_irq_exit
, NULL
,
1202 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1205 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1206 LTT_FACILITY_KERNEL
, LTT_EVENT_SOFT_IRQ_ENTRY
,
1207 LTT_FIELD_SOFT_IRQ_ID
, 0, 0,
1208 after_irq_entry
, NULL
,
1209 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1212 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1213 LTT_FACILITY_KERNEL
, LTT_EVENT_SOFT_IRQ_EXIT
,
1215 after_soft_irq_exit
, NULL
,
1216 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1219 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1220 LTT_FACILITY_PROCESS
, LTT_EVENT_SCHEDCHANGE
,
1221 LTT_FIELD_OUT
, LTT_FIELD_IN
, LTT_FIELD_OUT_STATE
,
1222 after_schedchange
, NULL
,
1223 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1226 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1227 LTT_FACILITY_PROCESS
, LTT_EVENT_FORK
,
1228 LTT_FIELD_PARENT_PID
, LTT_FIELD_CHILD_PID
, 0,
1230 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1233 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1234 LTT_FACILITY_PROCESS
, LTT_EVENT_EXIT
,
1235 LTT_FIELD_PID
, 0, 0,
1237 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1240 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1241 LTT_FACILITY_PROCESS
, LTT_EVENT_FREE
,
1242 LTT_FIELD_PID
, 0, 0,
1244 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1247 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1248 LTT_FACILITY_USER_GENERIC
, LTT_EVENT_FUNCTION_ENTRY
,
1249 LTT_FIELD_THIS_FN
, LTT_FIELD_CALL_SITE
, 0,
1250 after_function_entry
, NULL
,
1251 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1254 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1255 LTT_FACILITY_USER_GENERIC
, LTT_EVENT_FUNCTION_EXIT
,
1256 LTT_FIELD_THIS_FN
, LTT_FIELD_CALL_SITE
, 0,
1257 after_function_exit
, NULL
,
1258 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1261 /* statedump-related hooks */
1262 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1263 LTT_FACILITY_STATEDUMP
, LTT_EVENT_ENUM_PROCESS_STATE
,
1264 LTT_FIELD_PID
, LTT_FIELD_PARENT_PID
, LTT_FIELD_NAME
,
1265 after_enum_process_state
, NULL
,
1266 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1269 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1270 LTT_FACILITY_STATEDUMP
, LTT_EVENT_STATEDUMP_END
,
1272 after_statedump_end
, NULL
,
1273 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1276 g_array_set_size(hooks
, hn
);
1278 after_hooks
= hooks
;
1280 /* Add these hooks to each event_by_id hooks list */
1282 nb_tracefile
= ts
->parent
.parent
.tracefiles
->len
;
1284 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1285 tfs
= LTTV_TRACEFILE_STATS(g_array_index(ts
->parent
.parent
.tracefiles
,
1286 LttvTracefileContext
*, j
));
1287 lttv_hooks_add(tfs
->parent
.parent
.event
, every_event
, NULL
,
1290 for(k
= 0 ; k
< before_hooks
->len
; k
++) {
1291 hook
= &g_array_index(before_hooks
, LttvTraceHook
, k
);
1292 for(l
= 0; l
<hook
->fac_list
->len
;l
++) {
1293 thf
= g_array_index(hook
->fac_list
, LttvTraceHookByFacility
*, l
);
1295 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, thf
->id
),
1298 LTTV_PRIO_STATS_BEFORE_STATE
);
1301 for(k
= 0 ; k
< after_hooks
->len
; k
++) {
1302 hook
= &g_array_index(after_hooks
, LttvTraceHook
, k
);
1303 for(l
= 0; l
<hook
->fac_list
->len
;l
++) {
1304 thf
= g_array_index(hook
->fac_list
, LttvTraceHookByFacility
*, l
);
1306 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, thf
->id
),
1309 LTTV_PRIO_STATS_AFTER_STATE
);
1313 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_BEFORE_HOOKS
,
1314 LTTV_POINTER
, &val
);
1315 *(val
.v_pointer
) = before_hooks
;
1316 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_AFTER_HOOKS
,
1317 LTTV_POINTER
, &val
);
1318 *(val
.v_pointer
) = after_hooks
;
1322 // Hook wrapper. call_data is a traceset context.
1323 gboolean
lttv_stats_hook_remove_event_hooks(void *hook_data
, void *call_data
)
1325 LttvTracesetStats
*tss
= (LttvTracesetStats
*)call_data
;
1327 lttv_stats_remove_event_hooks(tss
);
1332 void lttv_stats_remove_event_hooks(LttvTracesetStats
*self
)
1334 LttvTraceset
*traceset
= self
->parent
.parent
.ts
;
1336 guint i
, j
, k
, l
, nb_trace
, nb_tracefile
;
1340 LttvTracefileStats
*tfs
;
1344 GArray
*before_hooks
, *after_hooks
;
1346 LttvTraceHook
*hook
;
1348 LttvTraceHookByFacility
*thf
;
1350 LttvAttributeValue val
;
1352 nb_trace
= lttv_traceset_number(traceset
);
1353 for(i
= 0 ; i
< nb_trace
; i
++) {
1354 ts
= (LttvTraceStats
*)self
->parent
.parent
.traces
[i
];
1355 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_BEFORE_HOOKS
,
1356 LTTV_POINTER
, &val
);
1357 before_hooks
= *(val
.v_pointer
);
1358 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_AFTER_HOOKS
,
1359 LTTV_POINTER
, &val
);
1360 after_hooks
= *(val
.v_pointer
);
1362 /* Remove these hooks from each event_by_id hooks list */
1364 nb_tracefile
= ts
->parent
.parent
.tracefiles
->len
;
1366 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1367 tfs
= LTTV_TRACEFILE_STATS(g_array_index(ts
->parent
.parent
.tracefiles
,
1368 LttvTracefileContext
*, j
));
1369 lttv_hooks_remove_data(tfs
->parent
.parent
.event
, every_event
,
1372 for(k
= 0 ; k
< before_hooks
->len
; k
++) {
1373 hook
= &g_array_index(before_hooks
, LttvTraceHook
, k
);
1374 for(l
= 0 ; l
< hook
->fac_list
->len
; l
++) {
1375 thf
= g_array_index(hook
->fac_list
, LttvTraceHookByFacility
*, l
);
1376 lttv_hooks_remove_data(
1377 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, thf
->id
),
1382 for(k
= 0 ; k
< after_hooks
->len
; k
++) {
1383 hook
= &g_array_index(after_hooks
, LttvTraceHook
, k
);
1384 for(l
= 0 ; l
< hook
->fac_list
->len
; l
++) {
1385 thf
= g_array_index(hook
->fac_list
, LttvTraceHookByFacility
*, l
);
1386 lttv_hooks_remove_data(
1387 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, thf
->id
),
1393 g_debug("lttv_stats_remove_event_hooks()");
1394 g_array_free(before_hooks
, TRUE
);
1395 g_array_free(after_hooks
, TRUE
);
1400 static void module_init()
1402 LTTV_STATS_PROCESS_UNKNOWN
= g_quark_from_string("unknown process");
1403 LTTV_STATS_PROCESSES
= g_quark_from_string("processes");
1404 LTTV_STATS_CPU
= g_quark_from_string("cpu");
1405 LTTV_STATS_MODE_TYPES
= g_quark_from_string("mode_types");
1406 LTTV_STATS_MODES
= g_quark_from_string("modes");
1407 LTTV_STATS_SUBMODES
= g_quark_from_string("submodes");
1408 LTTV_STATS_FUNCTIONS
= g_quark_from_string("functions");
1409 LTTV_STATS_EVENT_TYPES
= g_quark_from_string("event_types");
1410 LTTV_STATS_CPU_TIME
= g_quark_from_string("cpu time");
1411 LTTV_STATS_CUMULATIVE_CPU_TIME
= g_quark_from_string("cumulative cpu time (includes nested routines and modes)");
1412 LTTV_STATS_ELAPSED_TIME
= g_quark_from_string("elapsed time (includes per process waiting time)");
1413 LTTV_STATS_EVENTS
= g_quark_from_string("events");
1414 LTTV_STATS_EVENTS_COUNT
= g_quark_from_string("events count");
1415 LTTV_STATS_BEFORE_HOOKS
= g_quark_from_string("saved stats before hooks");
1416 LTTV_STATS_AFTER_HOOKS
= g_quark_from_string("saved stats after hooks");
1417 LTTV_STATS_USE_COUNT
= g_quark_from_string("stats_use_count");
1418 LTTV_STATS
= g_quark_from_string("statistics");
1419 LTTV_STATS_TRACEFILES
= g_quark_from_string("tracefiles statistics");
1420 LTTV_STATS_SUMMED
= g_quark_from_string("statistics summed");
1423 static void module_destroy()
1428 LTTV_MODULE("stats", "Compute processes statistics", \
1429 "Accumulate statistics for event types, processes and CPUs", \
1430 module_init
, module_destroy
, "state");
1432 /* Change the places where stats are called (create/read/write stats)
1434 Check for options in batchtest.c to reduce writing and see what tests are
1435 best candidates for performance analysis. Once OK, commit, move to main
1436 and run tests. Update the gui for statistics. */