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 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_STATS_ELAPSED_TIME
,
488 LTTV_TIME
, &elapsed_time
);
490 if(process
->state
->t
!= LTTV_STATE_MODE_UNKNOWN
)
491 delta
= ltt_time_sub(tfcs
->parent
.parent
.timestamp
,
492 process
->state
->entry
);
494 delta
= ltt_time_zero
;
496 *(elapsed_time
.v_time
) = ltt_time_add(*(elapsed_time
.v_time
), delta
);
498 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_STATS_CPU_TIME
,
499 LTTV_TIME
, &cpu_time
);
501 /* if it is a running mode, we must count its cpu time */
502 if(process
->state
->s
== LTTV_STATE_RUN
&&
503 process
->state
->t
!= LTTV_STATE_MODE_UNKNOWN
)
504 delta
= ltt_time_sub(tfcs
->parent
.parent
.timestamp
,
505 process
->state
->change
);
507 delta
= ltt_time_zero
;
509 *(cpu_time
.v_time
) = ltt_time_add(*(cpu_time
.v_time
), delta
);
510 process
->state
->cum_cpu_time
= ltt_time_add(process
->state
->cum_cpu_time
,
513 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_STATS_CUMULATIVE_CPU_TIME
,
514 LTTV_TIME
, &cum_cpu_time
);
515 *(cum_cpu_time
.v_time
) = ltt_time_add(*(cum_cpu_time
.v_time
),
516 process
->state
->cum_cpu_time
);
520 static void after_mode_end(LttvTracefileStats
*tfcs
)
522 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
523 guint cpu
= tfcs
->parent
.cpu
;
524 LttvProcessState
*process
= ts
->running_process
[cpu
];
525 LttvAttributeValue cum_cpu_time
;
527 LttTime nested_delta
;
529 nested_delta
= process
->state
->cum_cpu_time
;
530 process
->state
->cum_cpu_time
= ltt_time_zero
; /* For after traceset hook */
532 update_event_tree(tfcs
);
534 process
->state
->cum_cpu_time
= ltt_time_add(process
->state
->cum_cpu_time
,
538 static gboolean
before_syscall_entry(void *hook_data
, void *call_data
)
540 mode_change((LttvTracefileStats
*)call_data
);
545 static gboolean
after_syscall_entry(void *hook_data
, void *call_data
)
547 update_event_tree((LttvTracefileStats
*)call_data
);
552 gboolean
before_syscall_exit(void *hook_data
, void *call_data
)
554 mode_end((LttvTracefileStats
*)call_data
);
559 static gboolean
after_syscall_exit(void *hook_data
, void *call_data
)
561 after_mode_end((LttvTracefileStats
*)call_data
);
566 gboolean
before_trap_entry(void *hook_data
, void *call_data
)
568 mode_change((LttvTracefileStats
*)call_data
);
573 static gboolean
after_trap_entry(void *hook_data
, void *call_data
)
575 update_event_tree((LttvTracefileStats
*)call_data
);
580 gboolean
before_trap_exit(void *hook_data
, void *call_data
)
582 mode_end((LttvTracefileStats
*)call_data
);
587 gboolean
after_trap_exit(void *hook_data
, void *call_data
)
589 after_mode_end((LttvTracefileStats
*)call_data
);
594 gboolean
before_irq_entry(void *hook_data
, void *call_data
)
596 mode_change((LttvTracefileStats
*)call_data
);
600 gboolean
after_irq_entry(void *hook_data
, void *call_data
)
602 update_event_tree((LttvTracefileStats
*)call_data
);
607 gboolean
before_irq_exit(void *hook_data
, void *call_data
)
609 mode_end((LttvTracefileStats
*)call_data
);
614 gboolean
after_irq_exit(void *hook_data
, void *call_data
)
616 after_mode_end((LttvTracefileStats
*)call_data
);
621 gboolean
before_soft_irq_entry(void *hook_data
, void *call_data
)
623 mode_change((LttvTracefileStats
*)call_data
);
627 gboolean
after_soft_irq_entry(void *hook_data
, void *call_data
)
629 update_event_tree((LttvTracefileStats
*)call_data
);
634 gboolean
before_soft_irq_exit(void *hook_data
, void *call_data
)
636 mode_end((LttvTracefileStats
*)call_data
);
641 gboolean
after_soft_irq_exit(void *hook_data
, void *call_data
)
643 after_mode_end((LttvTracefileStats
*)call_data
);
647 gboolean
before_function_entry(void *hook_data
, void *call_data
)
649 mode_change((LttvTracefileStats
*)call_data
);
653 gboolean
after_function_entry(void *hook_data
, void *call_data
)
655 update_event_tree((LttvTracefileStats
*)call_data
);
659 gboolean
before_function_exit(void *hook_data
, void *call_data
)
661 mode_end((LttvTracefileStats
*)call_data
);
665 gboolean
after_function_exit(void *hook_data
, void *call_data
)
667 after_mode_end((LttvTracefileStats
*)call_data
);
672 gboolean
before_schedchange(void *hook_data
, void *call_data
)
674 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
676 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
678 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
680 LttvTraceHookByFacility
*thf
= (LttvTraceHookByFacility
*)hook_data
;
682 guint pid_in
, pid_out
;
686 pid_out
= ltt_event_get_unsigned(e
, thf
->f1
);
687 pid_in
= ltt_event_get_unsigned(e
, thf
->f2
);
688 state_out
= ltt_event_get_int(e
, thf
->f3
);
690 /* compute the time for the process to schedule out */
697 gboolean
after_schedchange(void *hook_data
, void *call_data
)
699 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
701 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
703 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
705 LttvTraceHookByFacility
*thf
= (LttvTraceHookByFacility
*)hook_data
;
707 guint pid_in
, pid_out
;
711 LttvProcessState
*process
;
713 pid_out
= ltt_event_get_unsigned(e
, thf
->f1
);
714 pid_in
= ltt_event_get_unsigned(e
, thf
->f2
);
715 state_out
= ltt_event_get_int(e
, thf
->f3
);
717 /* get the information for the process scheduled in */
718 guint cpu
= tfcs
->parent
.cpu
;
719 process
= ts
->running_process
[cpu
];
721 find_event_tree(tfcs
, process
->pid_time
,
723 process
->current_function
,
724 process
->state
->t
, process
->state
->n
, &(tfcs
->current_events_tree
),
725 &(tfcs
->current_event_types_tree
));
727 /* compute the time waiting for the process to schedule in */
733 gboolean
process_fork(void *hook_data
, void *call_data
)
735 /* nothing to do for now */
740 gboolean
process_exit(void *hook_data
, void *call_data
)
742 /* We should probably exit all modes here or we could do that at
747 gboolean
before_enum_process_state(void *hook_data
, void *call_data
)
750 /* Broken : adds up time in the current process doing the dump */
751 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
753 after_mode_end(tfcs
);
759 gboolean
after_enum_process_state(void *hook_data
, void *call_data
)
761 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
762 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
763 LttvTraceState
*ts
= (LttvTraceState
*)tfc
->t_context
;
766 nb_cpus
= ltt_trace_get_num_cpu(ts
->parent
.t
);
767 for(i
=0; i
<nb_cpus
; i
++) {
768 update_trace_event_tree(tfcs
, i
);
773 static gboolean
after_statedump_end(void *hook_data
, void *call_data
)
775 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
776 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
777 LttvTraceState
*ts
= (LttvTraceState
*)tfc
->t_context
;
780 nb_cpus
= ltt_trace_get_num_cpu(ts
->parent
.t
);
781 for(i
=0; i
<nb_cpus
; i
++) {
782 update_trace_event_tree(tfcs
, i
);
787 gboolean
process_free(void *hook_data
, void *call_data
)
792 gboolean
every_event(void *hook_data
, void *call_data
)
794 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
796 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
798 LttvAttributeValue v
;
800 /* The current branch corresponds to the tracefile/process/interrupt state.
801 Statistics are added within it, to count the number of events of this
802 type occuring in this context. A quark has been pre-allocated for each
803 event type and is used as name. */
805 lttv_attribute_find(tfcs
->current_event_types_tree
,
806 ltt_eventtype_name(ltt_event_eventtype(e
)),
812 static void lttv_stats_cleanup_process_state(LttvTraceState
*ts
,
813 LttvProcessState
*process
)
815 LttvTraceStats
*tcs
= (LttvTraceStats
*)ts
;
816 LttvTracesetContext
*tsc
= ts
->parent
.ts_context
;
818 LttvTracefileStats
**tfs
= (LttvTracefileStats
**)
819 &g_array_index(ts
->parent
.tracefiles
, LttvTracefileContext
*,
821 int cleanup_empty
= 0;
822 LttTime nested_delta
= ltt_time_zero
;
823 /* FIXME : ok, this is a hack. The time is infinite here :( */
824 LttTime save_time
= (*tfs
)->parent
.parent
.timestamp
;
826 ltt_trace_time_span_get(ts
->parent
.t
, &start
, &end
);
827 (*tfs
)->parent
.parent
.timestamp
= end
;
830 if(ltt_time_compare(process
->state
->cum_cpu_time
, ltt_time_zero
) != 0) {
831 find_event_tree(*tfs
, process
->pid_time
,
833 process
->current_function
,
834 process
->state
->t
, process
->state
->n
, &((*tfs
)->current_events_tree
),
835 &((*tfs
)->current_event_types_tree
));
837 nested_delta
= process
->state
->cum_cpu_time
;
839 cleanup_empty
= lttv_state_pop_state_cleanup(process
,
840 (LttvTracefileState
*)*tfs
);
841 process
->state
->cum_cpu_time
= ltt_time_add(process
->state
->cum_cpu_time
,
844 } while(cleanup_empty
!= 1);
846 (*tfs
)->parent
.parent
.timestamp
= save_time
;
849 /* For each cpu, for each of their stacked states,
850 * perform sum of needed values. */
851 static void lttv_stats_cleanup_state(LttvTraceStats
*tcs
)
853 LttvTraceState
*ts
= (LttvTraceState
*)tcs
;
856 nb_cpus
= ltt_trace_get_num_cpu(ts
->parent
.t
);
858 for(i
=0; i
<nb_cpus
; i
++) {
859 lttv_stats_cleanup_process_state(ts
, ts
->running_process
[i
]);
861 /* Does not work correctly FIXME. */
862 //g_hash_table_foreach(ts->processes, lttv_stats_cleanup_process_state,
867 lttv_stats_sum_trace(LttvTraceStats
*self
, LttvAttribute
*ts_stats
)
869 LttvAttribute
*sum_container
= self
->stats
;
871 LttvAttributeType type
;
873 LttvAttributeValue value
;
875 LttvAttributeName name
;
883 int i
, j
, k
, l
, m
, nb_process
, nb_cpu
, nb_mode_type
, nb_submode
,
884 nb_event_type
, nf
, nb_functions
;
886 LttvAttribute
*main_tree
, *processes_tree
, *process_tree
, *cpus_tree
,
887 *cpu_tree
, *mode_tree
, *mode_types_tree
, *submodes_tree
,
888 *submode_tree
, *event_types_tree
, *mode_events_tree
,
891 *function_mode_types_tree
,
895 main_tree
= sum_container
;
897 lttv_attribute_find(sum_container
,
900 trace_is_summed
= *(value
.v_uint
);
903 /* First cleanup the state : sum all stalled information (never ending
906 lttv_stats_cleanup_state(self
);
908 processes_tree
= lttv_attribute_find_subdir(main_tree
,
909 LTTV_STATS_PROCESSES
);
910 nb_process
= lttv_attribute_get_number(processes_tree
);
912 for(i
= 0 ; i
< nb_process
; i
++) {
913 type
= lttv_attribute_get(processes_tree
, i
, &name
, &value
, &is_named
);
914 process_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
916 cpus_tree
= lttv_attribute_find_subdir(process_tree
, LTTV_STATS_CPU
);
917 nb_cpu
= lttv_attribute_get_number(cpus_tree
);
919 for(j
= 0 ; j
< nb_cpu
; j
++) {
920 type
= lttv_attribute_get(cpus_tree
, j
, &name
, &value
, &is_named
);
921 cpu_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
923 trace_cpu_tree
= lttv_attribute_find_subdir(main_tree
, LTTV_STATS_CPU
);
924 trace_cpu_tree
= lttv_attribute_find_subdir_unnamed(trace_cpu_tree
, name
);
925 cpu_functions_tree
= lttv_attribute_find_subdir(cpu_tree
,
926 LTTV_STATS_FUNCTIONS
);
927 nb_functions
= lttv_attribute_get_number(cpu_functions_tree
);
929 for(nf
=0; nf
< nb_functions
; nf
++) {
930 type
= lttv_attribute_get(cpu_functions_tree
, nf
, &name
, &value
,
932 function_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
933 function_mode_types_tree
= lttv_attribute_find_subdir(function_tree
,
934 LTTV_STATS_MODE_TYPES
);
935 nb_mode_type
= lttv_attribute_get_number(function_mode_types_tree
);
936 for(k
= 0 ; k
< nb_mode_type
; k
++) {
937 type
= lttv_attribute_get(function_mode_types_tree
, k
, &name
, &value
,
939 mode_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
941 submodes_tree
= lttv_attribute_find_subdir(mode_tree
,
942 LTTV_STATS_SUBMODES
);
943 mode_events_tree
= lttv_attribute_find_subdir(mode_tree
,
945 mode_types_tree
= lttv_attribute_find_subdir(mode_tree
,
946 LTTV_STATS_MODE_TYPES
);
948 nb_submode
= lttv_attribute_get_number(submodes_tree
);
950 for(l
= 0 ; l
< nb_submode
; l
++) {
951 type
= lttv_attribute_get(submodes_tree
, l
, &name
, &value
,
953 submode_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
955 event_types_tree
= lttv_attribute_find_subdir(submode_tree
,
956 LTTV_STATS_EVENT_TYPES
);
957 nb_event_type
= lttv_attribute_get_number(event_types_tree
);
960 for(m
= 0 ; m
< nb_event_type
; m
++) {
961 type
= lttv_attribute_get(event_types_tree
, m
, &name
, &value
,
963 sum
+= *(value
.v_uint
);
965 lttv_attribute_find(submode_tree
, LTTV_STATS_EVENTS_COUNT
,
967 *(value
.v_uint
) = sum
;
969 type
= lttv_attribute_get(submodes_tree
, l
, &name
, &value
,
971 submode_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
972 if(!trace_is_summed
) {
973 lttv_attribute_recursive_add(mode_events_tree
, event_types_tree
);
974 lttv_attribute_recursive_add(mode_types_tree
, submode_tree
);
977 if(!trace_is_summed
) {
978 lttv_attribute_recursive_add(function_tree
, mode_types_tree
);
981 if(!trace_is_summed
) {
982 lttv_attribute_recursive_add(cpu_tree
, function_tree
);
983 lttv_attribute_recursive_add(process_tree
, function_tree
);
984 lttv_attribute_recursive_add(trace_cpu_tree
, function_tree
);
985 lttv_attribute_recursive_add(main_tree
, function_tree
);
987 lttv_attribute_recursive_add(ts_stats
, function_tree
);
994 gboolean
lttv_stats_sum_traceset_hook(void *hook_data
, void *call_data
)
996 lttv_stats_sum_traceset((LttvTracesetStats
*)call_data
);
1001 lttv_stats_sum_traceset(LttvTracesetStats
*self
)
1003 LttvTraceset
*traceset
= self
->parent
.parent
.ts
;
1004 LttvAttribute
*sum_container
= self
->stats
;
1006 LttvTraceStats
*tcs
;
1010 LttvAttribute
*main_tree
;
1012 LttvAttributeValue value
;
1014 lttv_attribute_find(sum_container
, LTTV_STATS_SUMMED
,
1016 if(*(value
.v_uint
) != 0) return;
1017 *(value
.v_uint
) = 1;
1019 nb_trace
= lttv_traceset_number(traceset
);
1021 for(i
= 0 ; i
< nb_trace
; i
++) {
1022 tcs
= (LttvTraceStats
*)(self
->parent
.parent
.traces
[i
]);
1023 lttv_stats_sum_trace(tcs
, self
->stats
);
1024 // lttv_attribute_recursive_add(sum_container, tcs->stats);
1029 // Hook wrapper. call_data is a traceset context.
1030 gboolean
lttv_stats_hook_add_event_hooks(void *hook_data
, void *call_data
)
1032 LttvTracesetStats
*tss
= (LttvTracesetStats
*)call_data
;
1034 lttv_stats_add_event_hooks(tss
);
1039 void lttv_stats_add_event_hooks(LttvTracesetStats
*self
)
1041 LttvTraceset
*traceset
= self
->parent
.parent
.ts
;
1043 guint i
, j
, k
, l
, nb_trace
, nb_tracefile
;
1047 LttvTracefileStats
*tfs
;
1049 GArray
*hooks
, *before_hooks
, *after_hooks
;
1051 LttvTraceHook
*hook
;
1053 LttvTraceHookByFacility
*thf
;
1055 LttvAttributeValue val
;
1060 nb_trace
= lttv_traceset_number(traceset
);
1061 for(i
= 0 ; i
< nb_trace
; i
++) {
1062 ts
= (LttvTraceStats
*)self
->parent
.parent
.traces
[i
];
1064 /* Find the eventtype id for the following events and register the
1065 associated by id hooks. */
1067 hooks
= g_array_sized_new(FALSE
, FALSE
, sizeof(LttvTraceHook
), 12);
1068 g_array_set_size(hooks
, 12);
1071 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1072 LTT_FACILITY_KERNEL_ARCH
, LTT_EVENT_SYSCALL_ENTRY
,
1073 LTT_FIELD_SYSCALL_ID
, 0, 0,
1074 before_syscall_entry
, NULL
,
1075 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1078 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1079 LTT_FACILITY_KERNEL_ARCH
, LTT_EVENT_SYSCALL_EXIT
,
1081 before_syscall_exit
, NULL
,
1082 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1085 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1086 LTT_FACILITY_KERNEL
, LTT_EVENT_TRAP_ENTRY
,
1087 LTT_FIELD_TRAP_ID
, 0, 0,
1088 before_trap_entry
, NULL
,
1089 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1092 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1093 LTT_FACILITY_KERNEL
, LTT_EVENT_TRAP_EXIT
,
1095 before_trap_exit
, NULL
,
1096 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1099 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1100 LTT_FACILITY_KERNEL
, LTT_EVENT_IRQ_ENTRY
,
1101 LTT_FIELD_IRQ_ID
, 0, 0,
1102 before_irq_entry
, NULL
,
1103 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1106 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1107 LTT_FACILITY_KERNEL
, LTT_EVENT_IRQ_EXIT
,
1109 before_irq_exit
, NULL
,
1110 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1113 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1114 LTT_FACILITY_KERNEL
, LTT_EVENT_SOFT_IRQ_ENTRY
,
1115 LTT_FIELD_SOFT_IRQ_ID
, 0, 0,
1116 before_soft_irq_entry
, NULL
,
1117 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1120 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1121 LTT_FACILITY_KERNEL
, LTT_EVENT_SOFT_IRQ_EXIT
,
1123 before_soft_irq_exit
, NULL
,
1124 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1127 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1128 LTT_FACILITY_PROCESS
, LTT_EVENT_SCHEDCHANGE
,
1129 LTT_FIELD_OUT
, LTT_FIELD_IN
, LTT_FIELD_OUT_STATE
,
1130 before_schedchange
, NULL
,
1131 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1134 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1135 LTT_FACILITY_USER_GENERIC
, LTT_EVENT_FUNCTION_ENTRY
,
1136 LTT_FIELD_THIS_FN
, LTT_FIELD_CALL_SITE
, 0,
1137 before_function_entry
, NULL
,
1138 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1141 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1142 LTT_FACILITY_USER_GENERIC
, LTT_EVENT_FUNCTION_EXIT
,
1143 LTT_FIELD_THIS_FN
, LTT_FIELD_CALL_SITE
, 0,
1144 before_function_exit
, NULL
,
1145 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1148 /* statedump-related hooks */
1149 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1150 LTT_FACILITY_STATEDUMP
, LTT_EVENT_ENUM_PROCESS_STATE
,
1151 LTT_FIELD_PID
, LTT_FIELD_PARENT_PID
, LTT_FIELD_NAME
,
1152 before_enum_process_state
, NULL
,
1153 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1156 g_array_set_size(hooks
, hn
);
1158 before_hooks
= hooks
;
1160 hooks
= g_array_sized_new(FALSE
, FALSE
, sizeof(LttvTraceHook
), 16);
1161 g_array_set_size(hooks
, 16);
1164 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1165 LTT_FACILITY_KERNEL_ARCH
, LTT_EVENT_SYSCALL_ENTRY
,
1166 LTT_FIELD_SYSCALL_ID
, 0, 0,
1167 after_syscall_entry
, NULL
,
1168 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1171 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1172 LTT_FACILITY_KERNEL_ARCH
, LTT_EVENT_SYSCALL_EXIT
,
1174 after_syscall_exit
, NULL
,
1175 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1178 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1179 LTT_FACILITY_KERNEL
, LTT_EVENT_TRAP_ENTRY
,
1180 LTT_FIELD_TRAP_ID
, 0, 0,
1181 after_trap_entry
, NULL
,
1182 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1185 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1186 LTT_FACILITY_KERNEL
, LTT_EVENT_TRAP_EXIT
,
1188 after_trap_exit
, NULL
,
1189 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1192 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1193 LTT_FACILITY_KERNEL
, LTT_EVENT_IRQ_ENTRY
,
1194 LTT_FIELD_IRQ_ID
, 0, 0,
1195 after_irq_entry
, NULL
,
1196 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1199 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1200 LTT_FACILITY_KERNEL
, LTT_EVENT_IRQ_EXIT
,
1202 after_irq_exit
, NULL
,
1203 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1206 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1207 LTT_FACILITY_KERNEL
, LTT_EVENT_SOFT_IRQ_ENTRY
,
1208 LTT_FIELD_SOFT_IRQ_ID
, 0, 0,
1209 after_irq_entry
, NULL
,
1210 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1213 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1214 LTT_FACILITY_KERNEL
, LTT_EVENT_SOFT_IRQ_EXIT
,
1216 after_soft_irq_exit
, NULL
,
1217 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1220 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1221 LTT_FACILITY_PROCESS
, LTT_EVENT_SCHEDCHANGE
,
1222 LTT_FIELD_OUT
, LTT_FIELD_IN
, LTT_FIELD_OUT_STATE
,
1223 after_schedchange
, NULL
,
1224 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1227 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1228 LTT_FACILITY_PROCESS
, LTT_EVENT_FORK
,
1229 LTT_FIELD_PARENT_PID
, LTT_FIELD_CHILD_PID
, 0,
1231 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1234 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1235 LTT_FACILITY_PROCESS
, LTT_EVENT_EXIT
,
1236 LTT_FIELD_PID
, 0, 0,
1238 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1241 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1242 LTT_FACILITY_PROCESS
, LTT_EVENT_FREE
,
1243 LTT_FIELD_PID
, 0, 0,
1245 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1248 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1249 LTT_FACILITY_USER_GENERIC
, LTT_EVENT_FUNCTION_ENTRY
,
1250 LTT_FIELD_THIS_FN
, LTT_FIELD_CALL_SITE
, 0,
1251 after_function_entry
, NULL
,
1252 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1255 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1256 LTT_FACILITY_USER_GENERIC
, LTT_EVENT_FUNCTION_EXIT
,
1257 LTT_FIELD_THIS_FN
, LTT_FIELD_CALL_SITE
, 0,
1258 after_function_exit
, NULL
,
1259 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1262 /* statedump-related hooks */
1263 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1264 LTT_FACILITY_STATEDUMP
, LTT_EVENT_ENUM_PROCESS_STATE
,
1265 LTT_FIELD_PID
, LTT_FIELD_PARENT_PID
, LTT_FIELD_NAME
,
1266 after_enum_process_state
, NULL
,
1267 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1270 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1271 LTT_FACILITY_STATEDUMP
, LTT_EVENT_STATEDUMP_END
,
1273 after_statedump_end
, NULL
,
1274 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1277 g_array_set_size(hooks
, hn
);
1279 after_hooks
= hooks
;
1281 /* Add these hooks to each event_by_id hooks list */
1283 nb_tracefile
= ts
->parent
.parent
.tracefiles
->len
;
1285 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1286 tfs
= LTTV_TRACEFILE_STATS(g_array_index(ts
->parent
.parent
.tracefiles
,
1287 LttvTracefileContext
*, j
));
1288 lttv_hooks_add(tfs
->parent
.parent
.event
, every_event
, NULL
,
1291 for(k
= 0 ; k
< before_hooks
->len
; k
++) {
1292 hook
= &g_array_index(before_hooks
, LttvTraceHook
, k
);
1293 for(l
= 0; l
<hook
->fac_list
->len
;l
++) {
1294 thf
= g_array_index(hook
->fac_list
, LttvTraceHookByFacility
*, l
);
1296 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, thf
->id
),
1299 LTTV_PRIO_STATS_BEFORE_STATE
);
1302 for(k
= 0 ; k
< after_hooks
->len
; k
++) {
1303 hook
= &g_array_index(after_hooks
, LttvTraceHook
, k
);
1304 for(l
= 0; l
<hook
->fac_list
->len
;l
++) {
1305 thf
= g_array_index(hook
->fac_list
, LttvTraceHookByFacility
*, l
);
1307 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, thf
->id
),
1310 LTTV_PRIO_STATS_AFTER_STATE
);
1314 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_BEFORE_HOOKS
,
1315 LTTV_POINTER
, &val
);
1316 *(val
.v_pointer
) = before_hooks
;
1317 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_AFTER_HOOKS
,
1318 LTTV_POINTER
, &val
);
1319 *(val
.v_pointer
) = after_hooks
;
1323 // Hook wrapper. call_data is a traceset context.
1324 gboolean
lttv_stats_hook_remove_event_hooks(void *hook_data
, void *call_data
)
1326 LttvTracesetStats
*tss
= (LttvTracesetStats
*)call_data
;
1328 lttv_stats_remove_event_hooks(tss
);
1333 void lttv_stats_remove_event_hooks(LttvTracesetStats
*self
)
1335 LttvTraceset
*traceset
= self
->parent
.parent
.ts
;
1337 guint i
, j
, k
, l
, nb_trace
, nb_tracefile
;
1341 LttvTracefileStats
*tfs
;
1345 GArray
*before_hooks
, *after_hooks
;
1347 LttvTraceHook
*hook
;
1349 LttvTraceHookByFacility
*thf
;
1351 LttvAttributeValue val
;
1353 nb_trace
= lttv_traceset_number(traceset
);
1354 for(i
= 0 ; i
< nb_trace
; i
++) {
1355 ts
= (LttvTraceStats
*)self
->parent
.parent
.traces
[i
];
1356 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_BEFORE_HOOKS
,
1357 LTTV_POINTER
, &val
);
1358 before_hooks
= *(val
.v_pointer
);
1359 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_AFTER_HOOKS
,
1360 LTTV_POINTER
, &val
);
1361 after_hooks
= *(val
.v_pointer
);
1363 /* Remove these hooks from each event_by_id hooks list */
1365 nb_tracefile
= ts
->parent
.parent
.tracefiles
->len
;
1367 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1368 tfs
= LTTV_TRACEFILE_STATS(g_array_index(ts
->parent
.parent
.tracefiles
,
1369 LttvTracefileContext
*, j
));
1370 lttv_hooks_remove_data(tfs
->parent
.parent
.event
, every_event
,
1373 for(k
= 0 ; k
< before_hooks
->len
; k
++) {
1374 hook
= &g_array_index(before_hooks
, LttvTraceHook
, k
);
1375 for(l
= 0 ; l
< hook
->fac_list
->len
; l
++) {
1376 thf
= g_array_index(hook
->fac_list
, LttvTraceHookByFacility
*, l
);
1377 lttv_hooks_remove_data(
1378 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, thf
->id
),
1383 for(k
= 0 ; k
< after_hooks
->len
; k
++) {
1384 hook
= &g_array_index(after_hooks
, LttvTraceHook
, k
);
1385 for(l
= 0 ; l
< hook
->fac_list
->len
; l
++) {
1386 thf
= g_array_index(hook
->fac_list
, LttvTraceHookByFacility
*, l
);
1387 lttv_hooks_remove_data(
1388 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, thf
->id
),
1394 g_debug("lttv_stats_remove_event_hooks()");
1395 g_array_free(before_hooks
, TRUE
);
1396 g_array_free(after_hooks
, TRUE
);
1401 static void module_init()
1403 LTTV_STATS_PROCESS_UNKNOWN
= g_quark_from_string("unknown process");
1404 LTTV_STATS_PROCESSES
= g_quark_from_string("processes");
1405 LTTV_STATS_CPU
= g_quark_from_string("cpu");
1406 LTTV_STATS_MODE_TYPES
= g_quark_from_string("mode_types");
1407 LTTV_STATS_MODES
= g_quark_from_string("modes");
1408 LTTV_STATS_SUBMODES
= g_quark_from_string("submodes");
1409 LTTV_STATS_FUNCTIONS
= g_quark_from_string("functions");
1410 LTTV_STATS_EVENT_TYPES
= g_quark_from_string("event_types");
1411 LTTV_STATS_CPU_TIME
= g_quark_from_string("cpu time");
1412 LTTV_STATS_CUMULATIVE_CPU_TIME
= g_quark_from_string("cumulative cpu time (includes nested routines and modes)");
1413 LTTV_STATS_ELAPSED_TIME
= g_quark_from_string("elapsed time (includes per process waiting time)");
1414 LTTV_STATS_EVENTS
= g_quark_from_string("events");
1415 LTTV_STATS_EVENTS_COUNT
= g_quark_from_string("events count");
1416 LTTV_STATS_BEFORE_HOOKS
= g_quark_from_string("saved stats before hooks");
1417 LTTV_STATS_AFTER_HOOKS
= g_quark_from_string("saved stats after hooks");
1418 LTTV_STATS_USE_COUNT
= g_quark_from_string("stats_use_count");
1419 LTTV_STATS
= g_quark_from_string("statistics");
1420 LTTV_STATS_TRACEFILES
= g_quark_from_string("tracefiles statistics");
1421 LTTV_STATS_SUMMED
= g_quark_from_string("statistics summed");
1424 static void module_destroy()
1429 LTTV_MODULE("stats", "Compute processes statistics", \
1430 "Accumulate statistics for event types, processes and CPUs", \
1431 module_init
, module_destroy
, "state");
1433 /* Change the places where stats are called (create/read/write stats)
1435 Check for options in batchtest.c to reduce writing and see what tests are
1436 best candidates for performance analysis. Once OK, commit, move to main
1437 and run tests. Update the gui for statistics. */