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 static void update_event_tree(LttvTracefileStats
*tfcs
)
435 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
436 guint cpu
= tfcs
->parent
.cpu
;
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
));
448 static void mode_change(LttvTracefileStats
*tfcs
)
450 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
451 guint cpu
= tfcs
->parent
.cpu
;
452 LttvProcessState
*process
= ts
->running_process
[cpu
];
453 LttvAttributeValue cpu_time
, cum_cpu_time
;
457 delta
= ltt_time_sub(tfcs
->parent
.parent
.timestamp
,
458 process
->state
->change
);
460 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_STATS_CPU_TIME
,
461 LTTV_TIME
, &cpu_time
);
462 *(cpu_time
.v_time
) = ltt_time_add(*(cpu_time
.v_time
), delta
);
464 process
->state
->cum_cpu_time
= ltt_time_add(process
->state
->cum_cpu_time
,
468 /* Note : every mode_end must come with a cumulative cpu time update in the
470 static void mode_end(LttvTracefileStats
*tfcs
)
472 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
473 guint cpu
= tfcs
->parent
.cpu
;
474 LttvProcessState
*process
= ts
->running_process
[cpu
];
475 LttvAttributeValue elapsed_time
, cpu_time
, cum_cpu_time
;
479 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_STATS_ELAPSED_TIME
,
480 LTTV_TIME
, &elapsed_time
);
481 delta
= ltt_time_sub(tfcs
->parent
.parent
.timestamp
,
482 process
->state
->entry
);
483 *(elapsed_time
.v_time
) = ltt_time_add(*(elapsed_time
.v_time
), delta
);
485 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_STATS_CPU_TIME
,
486 LTTV_TIME
, &cpu_time
);
487 delta
= ltt_time_sub(tfcs
->parent
.parent
.timestamp
,
488 process
->state
->change
);
489 *(cpu_time
.v_time
) = ltt_time_add(*(cpu_time
.v_time
), delta
);
490 process
->state
->cum_cpu_time
= ltt_time_add(process
->state
->cum_cpu_time
,
493 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_STATS_CUMULATIVE_CPU_TIME
,
494 LTTV_TIME
, &cum_cpu_time
);
495 *(cum_cpu_time
.v_time
) = ltt_time_add(*(cum_cpu_time
.v_time
),
496 process
->state
->cum_cpu_time
);
500 static void after_mode_end(LttvTracefileStats
*tfcs
)
502 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
503 guint cpu
= tfcs
->parent
.cpu
;
504 LttvProcessState
*process
= ts
->running_process
[cpu
];
505 LttvAttributeValue cum_cpu_time
;
507 LttTime nested_delta
;
509 nested_delta
= process
->state
->cum_cpu_time
;
510 process
->state
->cum_cpu_time
= ltt_time_zero
; /* For after traceset hook */
512 update_event_tree(tfcs
);
514 process
->state
->cum_cpu_time
= ltt_time_add(process
->state
->cum_cpu_time
,
518 static gboolean
before_syscall_entry(void *hook_data
, void *call_data
)
520 mode_change((LttvTracefileStats
*)call_data
);
525 static gboolean
after_syscall_entry(void *hook_data
, void *call_data
)
527 update_event_tree((LttvTracefileStats
*)call_data
);
532 gboolean
before_syscall_exit(void *hook_data
, void *call_data
)
534 mode_end((LttvTracefileStats
*)call_data
);
539 static gboolean
after_syscall_exit(void *hook_data
, void *call_data
)
541 after_mode_end((LttvTracefileStats
*)call_data
);
546 gboolean
before_trap_entry(void *hook_data
, void *call_data
)
548 mode_change((LttvTracefileStats
*)call_data
);
553 static gboolean
after_trap_entry(void *hook_data
, void *call_data
)
555 update_event_tree((LttvTracefileStats
*)call_data
);
560 gboolean
before_trap_exit(void *hook_data
, void *call_data
)
562 mode_end((LttvTracefileStats
*)call_data
);
567 gboolean
after_trap_exit(void *hook_data
, void *call_data
)
569 after_mode_end((LttvTracefileStats
*)call_data
);
574 gboolean
before_irq_entry(void *hook_data
, void *call_data
)
576 mode_change((LttvTracefileStats
*)call_data
);
580 gboolean
after_irq_entry(void *hook_data
, void *call_data
)
582 update_event_tree((LttvTracefileStats
*)call_data
);
587 gboolean
before_irq_exit(void *hook_data
, void *call_data
)
589 mode_end((LttvTracefileStats
*)call_data
);
594 gboolean
after_irq_exit(void *hook_data
, void *call_data
)
596 after_mode_end((LttvTracefileStats
*)call_data
);
601 gboolean
before_soft_irq_entry(void *hook_data
, void *call_data
)
603 mode_change((LttvTracefileStats
*)call_data
);
607 gboolean
after_soft_irq_entry(void *hook_data
, void *call_data
)
609 update_event_tree((LttvTracefileStats
*)call_data
);
614 gboolean
before_soft_irq_exit(void *hook_data
, void *call_data
)
616 mode_end((LttvTracefileStats
*)call_data
);
621 gboolean
after_soft_irq_exit(void *hook_data
, void *call_data
)
623 after_mode_end((LttvTracefileStats
*)call_data
);
627 gboolean
before_function_entry(void *hook_data
, void *call_data
)
629 mode_change((LttvTracefileStats
*)call_data
);
633 gboolean
after_function_entry(void *hook_data
, void *call_data
)
635 update_event_tree((LttvTracefileStats
*)call_data
);
639 gboolean
before_function_exit(void *hook_data
, void *call_data
)
641 mode_end((LttvTracefileStats
*)call_data
);
645 gboolean
after_function_exit(void *hook_data
, void *call_data
)
647 after_mode_end((LttvTracefileStats
*)call_data
);
652 gboolean
before_schedchange(void *hook_data
, void *call_data
)
654 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
656 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
658 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
660 LttvTraceHookByFacility
*thf
= (LttvTraceHookByFacility
*)hook_data
;
662 guint pid_in
, pid_out
;
666 pid_out
= ltt_event_get_unsigned(e
, thf
->f1
);
667 pid_in
= ltt_event_get_unsigned(e
, thf
->f2
);
668 state_out
= ltt_event_get_int(e
, thf
->f3
);
670 /* compute the time for the process to schedule out */
677 gboolean
after_schedchange(void *hook_data
, void *call_data
)
679 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
681 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
683 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
685 LttvTraceHookByFacility
*thf
= (LttvTraceHookByFacility
*)hook_data
;
687 guint pid_in
, pid_out
;
691 LttvProcessState
*process
;
693 pid_out
= ltt_event_get_unsigned(e
, thf
->f1
);
694 pid_in
= ltt_event_get_unsigned(e
, thf
->f2
);
695 state_out
= ltt_event_get_int(e
, thf
->f3
);
697 /* get the information for the process scheduled in */
698 guint cpu
= tfcs
->parent
.cpu
;
699 process
= ts
->running_process
[cpu
];
701 find_event_tree(tfcs
, process
->pid_time
,
703 process
->current_function
,
704 process
->state
->t
, process
->state
->n
, &(tfcs
->current_events_tree
),
705 &(tfcs
->current_event_types_tree
));
707 /* compute the time waiting for the process to schedule in */
713 gboolean
process_fork(void *hook_data
, void *call_data
)
715 /* nothing to do for now */
720 gboolean
process_exit(void *hook_data
, void *call_data
)
722 /* We should probably exit all modes here or we could do that at
727 gboolean
before_enum_process_state(void *hook_data
, void *call_data
)
729 mode_end((LttvTracefileStats
*)call_data
);
730 after_mode_end((LttvTracefileStats
*)call_data
);
731 mode_change((LttvTracefileStats
*)call_data
);
735 gboolean
after_enum_process_state(void *hook_data
, void *call_data
)
737 update_event_tree((LttvTracefileStats
*)call_data
);
741 gboolean
process_free(void *hook_data
, void *call_data
)
746 gboolean
every_event(void *hook_data
, void *call_data
)
748 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
750 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
752 LttvAttributeValue v
;
754 /* The current branch corresponds to the tracefile/process/interrupt state.
755 Statistics are added within it, to count the number of events of this
756 type occuring in this context. A quark has been pre-allocated for each
757 event type and is used as name. */
759 lttv_attribute_find(tfcs
->current_event_types_tree
,
760 ltt_eventtype_name(ltt_event_eventtype(e
)),
766 static void lttv_stats_cleanup_process_state(gpointer key
, gpointer value
,
769 LttvTraceStats
*tcs
= (LttvTraceStats
*)user_data
;
770 LttvTraceState
*ts
= (LttvTraceState
*)user_data
;
771 LttvTracesetContext
*tsc
= ts
->parent
.ts_context
;
772 LttvProcessState
*process
= (LttvProcessState
*)value
;
774 LttvTracefileStats
**tfs
= (LttvTracefileStats
**)
775 &g_array_index(ts
->parent
.tracefiles
, LttvTracefileContext
*,
777 int cleanup_empty
= 0;
778 LttTime nested_delta
= ltt_time_zero
;
779 /* FIXME : ok, this is a hack. The time is infinite here :( */
780 LttTime save_time
= (*tfs
)->parent
.parent
.timestamp
;
782 ltt_trace_time_span_get(ts
->parent
.t
, &start
, &end
);
783 (*tfs
)->parent
.parent
.timestamp
= end
;
786 if(ltt_time_compare(process
->state
->cum_cpu_time
, ltt_time_zero
) != 0) {
787 find_event_tree(*tfs
, process
->pid_time
,
789 process
->current_function
,
790 process
->state
->t
, process
->state
->n
, &((*tfs
)->current_events_tree
),
791 &((*tfs
)->current_event_types_tree
));
792 /* if it is a running mode, we must count its cpu time */
793 if(process
->state
->s
== LTTV_STATE_RUN
)
795 nested_delta
= process
->state
->cum_cpu_time
;
797 cleanup_empty
= lttv_state_pop_state_cleanup(process
,
798 (LttvTracefileState
*)*tfs
);
799 process
->state
->cum_cpu_time
= ltt_time_add(process
->state
->cum_cpu_time
,
802 } while(cleanup_empty
!= 1);
804 (*tfs
)->parent
.parent
.timestamp
= save_time
;
807 /* For each process in the state, for each of their stacked states,
808 * perform sum of needed values. */
809 static void lttv_stats_cleanup_state(LttvTraceStats
*tcs
)
811 LttvTraceState
*ts
= (LttvTraceState
*)tcs
;
813 /* Does not work correctly FIXME. */
814 g_hash_table_foreach(ts
->processes
, lttv_stats_cleanup_process_state
,
819 lttv_stats_sum_trace(LttvTraceStats
*self
, LttvAttribute
*ts_stats
)
821 LttvAttribute
*sum_container
= self
->stats
;
823 LttvAttributeType type
;
825 LttvAttributeValue value
;
827 LttvAttributeName name
;
835 int i
, j
, k
, l
, m
, nb_process
, nb_cpu
, nb_mode_type
, nb_submode
,
836 nb_event_type
, nf
, nb_functions
;
838 LttvAttribute
*main_tree
, *processes_tree
, *process_tree
, *cpus_tree
,
839 *cpu_tree
, *mode_tree
, *mode_types_tree
, *submodes_tree
,
840 *submode_tree
, *event_types_tree
, *mode_events_tree
,
843 *function_mode_types_tree
,
847 main_tree
= sum_container
;
849 lttv_attribute_find(sum_container
,
852 trace_is_summed
= *(value
.v_uint
);
855 /* First cleanup the state : sum all stalled information (never ending
858 lttv_stats_cleanup_state(self
);
860 processes_tree
= lttv_attribute_find_subdir(main_tree
,
861 LTTV_STATS_PROCESSES
);
862 nb_process
= lttv_attribute_get_number(processes_tree
);
864 for(i
= 0 ; i
< nb_process
; i
++) {
865 type
= lttv_attribute_get(processes_tree
, i
, &name
, &value
, &is_named
);
866 process_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
868 cpus_tree
= lttv_attribute_find_subdir(process_tree
, LTTV_STATS_CPU
);
869 nb_cpu
= lttv_attribute_get_number(cpus_tree
);
871 for(j
= 0 ; j
< nb_cpu
; j
++) {
872 type
= lttv_attribute_get(cpus_tree
, j
, &name
, &value
, &is_named
);
873 cpu_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
875 trace_cpu_tree
= lttv_attribute_find_subdir(main_tree
, LTTV_STATS_CPU
);
876 trace_cpu_tree
= lttv_attribute_find_subdir_unnamed(trace_cpu_tree
, name
);
877 cpu_functions_tree
= lttv_attribute_find_subdir(cpu_tree
,
878 LTTV_STATS_FUNCTIONS
);
879 nb_functions
= lttv_attribute_get_number(cpu_functions_tree
);
881 for(nf
=0; nf
< nb_functions
; nf
++) {
882 type
= lttv_attribute_get(cpu_functions_tree
, nf
, &name
, &value
,
884 function_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
885 function_mode_types_tree
= lttv_attribute_find_subdir(function_tree
,
886 LTTV_STATS_MODE_TYPES
);
887 nb_mode_type
= lttv_attribute_get_number(function_mode_types_tree
);
888 for(k
= 0 ; k
< nb_mode_type
; k
++) {
889 type
= lttv_attribute_get(function_mode_types_tree
, k
, &name
, &value
,
891 mode_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
893 submodes_tree
= lttv_attribute_find_subdir(mode_tree
,
894 LTTV_STATS_SUBMODES
);
895 mode_events_tree
= lttv_attribute_find_subdir(mode_tree
,
897 mode_types_tree
= lttv_attribute_find_subdir(mode_tree
,
898 LTTV_STATS_MODE_TYPES
);
900 nb_submode
= lttv_attribute_get_number(submodes_tree
);
902 for(l
= 0 ; l
< nb_submode
; l
++) {
903 type
= lttv_attribute_get(submodes_tree
, l
, &name
, &value
,
905 submode_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
907 event_types_tree
= lttv_attribute_find_subdir(submode_tree
,
908 LTTV_STATS_EVENT_TYPES
);
909 nb_event_type
= lttv_attribute_get_number(event_types_tree
);
912 for(m
= 0 ; m
< nb_event_type
; m
++) {
913 type
= lttv_attribute_get(event_types_tree
, m
, &name
, &value
,
915 sum
+= *(value
.v_uint
);
917 lttv_attribute_find(submode_tree
, LTTV_STATS_EVENTS_COUNT
,
919 *(value
.v_uint
) = sum
;
921 type
= lttv_attribute_get(submodes_tree
, l
, &name
, &value
,
923 submode_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
924 if(!trace_is_summed
) {
925 lttv_attribute_recursive_add(mode_events_tree
, event_types_tree
);
926 lttv_attribute_recursive_add(mode_types_tree
, submode_tree
);
929 if(!trace_is_summed
) {
930 lttv_attribute_recursive_add(function_tree
, mode_types_tree
);
933 if(!trace_is_summed
) {
934 lttv_attribute_recursive_add(cpu_tree
, function_tree
);
935 lttv_attribute_recursive_add(process_tree
, function_tree
);
936 lttv_attribute_recursive_add(trace_cpu_tree
, function_tree
);
937 lttv_attribute_recursive_add(main_tree
, function_tree
);
939 lttv_attribute_recursive_add(ts_stats
, function_tree
);
946 gboolean
lttv_stats_sum_traceset_hook(void *hook_data
, void *call_data
)
948 lttv_stats_sum_traceset((LttvTracesetStats
*)call_data
);
953 lttv_stats_sum_traceset(LttvTracesetStats
*self
)
955 LttvTraceset
*traceset
= self
->parent
.parent
.ts
;
956 LttvAttribute
*sum_container
= self
->stats
;
962 LttvAttribute
*main_tree
;
964 LttvAttributeValue value
;
966 lttv_attribute_find(sum_container
, LTTV_STATS_SUMMED
,
968 if(*(value
.v_uint
) != 0) return;
971 nb_trace
= lttv_traceset_number(traceset
);
973 for(i
= 0 ; i
< nb_trace
; i
++) {
974 tcs
= (LttvTraceStats
*)(self
->parent
.parent
.traces
[i
]);
975 lttv_stats_sum_trace(tcs
, self
->stats
);
976 // lttv_attribute_recursive_add(sum_container, tcs->stats);
981 // Hook wrapper. call_data is a traceset context.
982 gboolean
lttv_stats_hook_add_event_hooks(void *hook_data
, void *call_data
)
984 LttvTracesetStats
*tss
= (LttvTracesetStats
*)call_data
;
986 lttv_stats_add_event_hooks(tss
);
991 void lttv_stats_add_event_hooks(LttvTracesetStats
*self
)
993 LttvTraceset
*traceset
= self
->parent
.parent
.ts
;
995 guint i
, j
, k
, l
, nb_trace
, nb_tracefile
;
999 LttvTracefileStats
*tfs
;
1001 GArray
*hooks
, *before_hooks
, *after_hooks
;
1003 LttvTraceHook
*hook
;
1005 LttvTraceHookByFacility
*thf
;
1007 LttvAttributeValue val
;
1012 nb_trace
= lttv_traceset_number(traceset
);
1013 for(i
= 0 ; i
< nb_trace
; i
++) {
1014 ts
= (LttvTraceStats
*)self
->parent
.parent
.traces
[i
];
1016 /* Find the eventtype id for the following events and register the
1017 associated by id hooks. */
1019 hooks
= g_array_sized_new(FALSE
, FALSE
, sizeof(LttvTraceHook
), 12);
1020 g_array_set_size(hooks
, 12);
1023 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1024 LTT_FACILITY_KERNEL_ARCH
, LTT_EVENT_SYSCALL_ENTRY
,
1025 LTT_FIELD_SYSCALL_ID
, 0, 0,
1026 before_syscall_entry
, NULL
,
1027 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1030 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1031 LTT_FACILITY_KERNEL_ARCH
, LTT_EVENT_SYSCALL_EXIT
,
1033 before_syscall_exit
, NULL
,
1034 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1037 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1038 LTT_FACILITY_KERNEL
, LTT_EVENT_TRAP_ENTRY
,
1039 LTT_FIELD_TRAP_ID
, 0, 0,
1040 before_trap_entry
, NULL
,
1041 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1044 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1045 LTT_FACILITY_KERNEL
, LTT_EVENT_TRAP_EXIT
,
1047 before_trap_exit
, NULL
,
1048 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1051 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1052 LTT_FACILITY_KERNEL
, LTT_EVENT_IRQ_ENTRY
,
1053 LTT_FIELD_IRQ_ID
, 0, 0,
1054 before_irq_entry
, NULL
,
1055 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1058 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1059 LTT_FACILITY_KERNEL
, LTT_EVENT_IRQ_EXIT
,
1061 before_irq_exit
, NULL
,
1062 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1065 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1066 LTT_FACILITY_KERNEL
, LTT_EVENT_SOFT_IRQ_ENTRY
,
1067 LTT_FIELD_SOFT_IRQ_ID
, 0, 0,
1068 before_soft_irq_entry
, NULL
,
1069 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1072 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1073 LTT_FACILITY_KERNEL
, LTT_EVENT_SOFT_IRQ_EXIT
,
1075 before_soft_irq_exit
, NULL
,
1076 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1079 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1080 LTT_FACILITY_PROCESS
, LTT_EVENT_SCHEDCHANGE
,
1081 LTT_FIELD_OUT
, LTT_FIELD_IN
, LTT_FIELD_OUT_STATE
,
1082 before_schedchange
, NULL
,
1083 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1086 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1087 LTT_FACILITY_USER_GENERIC
, LTT_EVENT_FUNCTION_ENTRY
,
1088 LTT_FIELD_THIS_FN
, LTT_FIELD_CALL_SITE
, 0,
1089 before_function_entry
, NULL
,
1090 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1093 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1094 LTT_FACILITY_USER_GENERIC
, LTT_EVENT_FUNCTION_EXIT
,
1095 LTT_FIELD_THIS_FN
, LTT_FIELD_CALL_SITE
, 0,
1096 before_function_exit
, NULL
,
1097 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1100 /* statedump-related hooks */
1101 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1102 LTT_FACILITY_STATEDUMP
, LTT_EVENT_ENUM_PROCESS_STATE
,
1103 LTT_FIELD_PID
, LTT_FIELD_PARENT_PID
, LTT_FIELD_NAME
,
1104 before_enum_process_state
, NULL
,
1105 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1108 g_array_set_size(hooks
, hn
);
1110 before_hooks
= hooks
;
1112 hooks
= g_array_sized_new(FALSE
, FALSE
, sizeof(LttvTraceHook
), 15);
1113 g_array_set_size(hooks
, 15);
1116 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1117 LTT_FACILITY_KERNEL_ARCH
, LTT_EVENT_SYSCALL_ENTRY
,
1118 LTT_FIELD_SYSCALL_ID
, 0, 0,
1119 after_syscall_entry
, NULL
,
1120 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1123 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1124 LTT_FACILITY_KERNEL_ARCH
, LTT_EVENT_SYSCALL_EXIT
,
1126 after_syscall_exit
, NULL
,
1127 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1130 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1131 LTT_FACILITY_KERNEL
, LTT_EVENT_TRAP_ENTRY
,
1132 LTT_FIELD_TRAP_ID
, 0, 0,
1133 after_trap_entry
, NULL
,
1134 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1137 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1138 LTT_FACILITY_KERNEL
, LTT_EVENT_TRAP_EXIT
,
1140 after_trap_exit
, NULL
,
1141 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1144 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1145 LTT_FACILITY_KERNEL
, LTT_EVENT_IRQ_ENTRY
,
1146 LTT_FIELD_IRQ_ID
, 0, 0,
1147 after_irq_entry
, NULL
,
1148 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1151 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1152 LTT_FACILITY_KERNEL
, LTT_EVENT_IRQ_EXIT
,
1154 after_irq_exit
, NULL
,
1155 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1158 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1159 LTT_FACILITY_KERNEL
, LTT_EVENT_SOFT_IRQ_ENTRY
,
1160 LTT_FIELD_SOFT_IRQ_ID
, 0, 0,
1161 after_irq_entry
, NULL
,
1162 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1165 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1166 LTT_FACILITY_KERNEL
, LTT_EVENT_SOFT_IRQ_EXIT
,
1168 after_soft_irq_exit
, NULL
,
1169 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1172 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1173 LTT_FACILITY_PROCESS
, LTT_EVENT_SCHEDCHANGE
,
1174 LTT_FIELD_OUT
, LTT_FIELD_IN
, LTT_FIELD_OUT_STATE
,
1175 after_schedchange
, NULL
,
1176 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1179 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1180 LTT_FACILITY_PROCESS
, LTT_EVENT_FORK
,
1181 LTT_FIELD_PARENT_PID
, LTT_FIELD_CHILD_PID
, 0,
1183 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1186 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1187 LTT_FACILITY_PROCESS
, LTT_EVENT_EXIT
,
1188 LTT_FIELD_PID
, 0, 0,
1190 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1193 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1194 LTT_FACILITY_PROCESS
, LTT_EVENT_FREE
,
1195 LTT_FIELD_PID
, 0, 0,
1197 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1200 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1201 LTT_FACILITY_USER_GENERIC
, LTT_EVENT_FUNCTION_ENTRY
,
1202 LTT_FIELD_THIS_FN
, LTT_FIELD_CALL_SITE
, 0,
1203 after_function_entry
, NULL
,
1204 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1207 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1208 LTT_FACILITY_USER_GENERIC
, LTT_EVENT_FUNCTION_EXIT
,
1209 LTT_FIELD_THIS_FN
, LTT_FIELD_CALL_SITE
, 0,
1210 after_function_exit
, NULL
,
1211 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1214 /* statedump-related hooks */
1215 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1216 LTT_FACILITY_STATEDUMP
, LTT_EVENT_ENUM_PROCESS_STATE
,
1217 LTT_FIELD_PID
, LTT_FIELD_PARENT_PID
, LTT_FIELD_NAME
,
1218 after_enum_process_state
, NULL
,
1219 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1222 g_array_set_size(hooks
, hn
);
1224 after_hooks
= hooks
;
1226 /* Add these hooks to each event_by_id hooks list */
1228 nb_tracefile
= ts
->parent
.parent
.tracefiles
->len
;
1230 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1231 tfs
= LTTV_TRACEFILE_STATS(g_array_index(ts
->parent
.parent
.tracefiles
,
1232 LttvTracefileContext
*, j
));
1233 lttv_hooks_add(tfs
->parent
.parent
.event
, every_event
, NULL
,
1236 for(k
= 0 ; k
< before_hooks
->len
; k
++) {
1237 hook
= &g_array_index(before_hooks
, LttvTraceHook
, k
);
1238 for(l
= 0; l
<hook
->fac_list
->len
;l
++) {
1239 thf
= g_array_index(hook
->fac_list
, LttvTraceHookByFacility
*, l
);
1241 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, thf
->id
),
1244 LTTV_PRIO_STATS_BEFORE_STATE
);
1247 for(k
= 0 ; k
< after_hooks
->len
; k
++) {
1248 hook
= &g_array_index(after_hooks
, LttvTraceHook
, k
);
1249 for(l
= 0; l
<hook
->fac_list
->len
;l
++) {
1250 thf
= g_array_index(hook
->fac_list
, LttvTraceHookByFacility
*, l
);
1252 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, thf
->id
),
1255 LTTV_PRIO_STATS_AFTER_STATE
);
1259 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_BEFORE_HOOKS
,
1260 LTTV_POINTER
, &val
);
1261 *(val
.v_pointer
) = before_hooks
;
1262 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_AFTER_HOOKS
,
1263 LTTV_POINTER
, &val
);
1264 *(val
.v_pointer
) = after_hooks
;
1268 // Hook wrapper. call_data is a traceset context.
1269 gboolean
lttv_stats_hook_remove_event_hooks(void *hook_data
, void *call_data
)
1271 LttvTracesetStats
*tss
= (LttvTracesetStats
*)call_data
;
1273 lttv_stats_remove_event_hooks(tss
);
1278 void lttv_stats_remove_event_hooks(LttvTracesetStats
*self
)
1280 LttvTraceset
*traceset
= self
->parent
.parent
.ts
;
1282 guint i
, j
, k
, l
, nb_trace
, nb_tracefile
;
1286 LttvTracefileStats
*tfs
;
1290 GArray
*before_hooks
, *after_hooks
;
1292 LttvTraceHook
*hook
;
1294 LttvTraceHookByFacility
*thf
;
1296 LttvAttributeValue val
;
1298 nb_trace
= lttv_traceset_number(traceset
);
1299 for(i
= 0 ; i
< nb_trace
; i
++) {
1300 ts
= (LttvTraceStats
*)self
->parent
.parent
.traces
[i
];
1301 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_BEFORE_HOOKS
,
1302 LTTV_POINTER
, &val
);
1303 before_hooks
= *(val
.v_pointer
);
1304 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_AFTER_HOOKS
,
1305 LTTV_POINTER
, &val
);
1306 after_hooks
= *(val
.v_pointer
);
1308 /* Remove these hooks from each event_by_id hooks list */
1310 nb_tracefile
= ts
->parent
.parent
.tracefiles
->len
;
1312 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1313 tfs
= LTTV_TRACEFILE_STATS(g_array_index(ts
->parent
.parent
.tracefiles
,
1314 LttvTracefileContext
*, j
));
1315 lttv_hooks_remove_data(tfs
->parent
.parent
.event
, every_event
,
1318 for(k
= 0 ; k
< before_hooks
->len
; k
++) {
1319 hook
= &g_array_index(before_hooks
, LttvTraceHook
, k
);
1320 for(l
= 0 ; l
< hook
->fac_list
->len
; l
++) {
1321 thf
= g_array_index(hook
->fac_list
, LttvTraceHookByFacility
*, l
);
1322 lttv_hooks_remove_data(
1323 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, thf
->id
),
1328 for(k
= 0 ; k
< after_hooks
->len
; k
++) {
1329 hook
= &g_array_index(after_hooks
, LttvTraceHook
, k
);
1330 for(l
= 0 ; l
< hook
->fac_list
->len
; l
++) {
1331 thf
= g_array_index(hook
->fac_list
, LttvTraceHookByFacility
*, l
);
1332 lttv_hooks_remove_data(
1333 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, thf
->id
),
1339 g_debug("lttv_stats_remove_event_hooks()");
1340 g_array_free(before_hooks
, TRUE
);
1341 g_array_free(after_hooks
, TRUE
);
1346 static void module_init()
1348 LTTV_STATS_PROCESS_UNKNOWN
= g_quark_from_string("unknown process");
1349 LTTV_STATS_PROCESSES
= g_quark_from_string("processes");
1350 LTTV_STATS_CPU
= g_quark_from_string("cpu");
1351 LTTV_STATS_MODE_TYPES
= g_quark_from_string("mode_types");
1352 LTTV_STATS_MODES
= g_quark_from_string("modes");
1353 LTTV_STATS_SUBMODES
= g_quark_from_string("submodes");
1354 LTTV_STATS_FUNCTIONS
= g_quark_from_string("functions");
1355 LTTV_STATS_EVENT_TYPES
= g_quark_from_string("event_types");
1356 LTTV_STATS_CPU_TIME
= g_quark_from_string("cpu time");
1357 LTTV_STATS_CUMULATIVE_CPU_TIME
= g_quark_from_string("cumulative cpu time (includes nested routines and modes)");
1358 LTTV_STATS_ELAPSED_TIME
= g_quark_from_string("elapsed time (includes per process waiting time)");
1359 LTTV_STATS_EVENTS
= g_quark_from_string("events");
1360 LTTV_STATS_EVENTS_COUNT
= g_quark_from_string("events count");
1361 LTTV_STATS_BEFORE_HOOKS
= g_quark_from_string("saved stats before hooks");
1362 LTTV_STATS_AFTER_HOOKS
= g_quark_from_string("saved stats after hooks");
1363 LTTV_STATS_USE_COUNT
= g_quark_from_string("stats_use_count");
1364 LTTV_STATS
= g_quark_from_string("statistics");
1365 LTTV_STATS_TRACEFILES
= g_quark_from_string("tracefiles statistics");
1366 LTTV_STATS_SUMMED
= g_quark_from_string("statistics summed");
1369 static void module_destroy()
1374 LTTV_MODULE("stats", "Compute processes statistics", \
1375 "Accumulate statistics for event types, processes and CPUs", \
1376 module_init
, module_destroy
, "state");
1378 /* Change the places where stats are called (create/read/write stats)
1380 Check for options in batchtest.c to reduce writing and see what tests are
1381 best candidates for performance analysis. Once OK, commit, move to main
1382 and run tests. Update the gui for statistics. */