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/trace.h>
29 #include <ltt/event.h>
32 #define MAX_64_HEX_STRING_LEN 19
35 LTTV_STATS_PROCESS_UNKNOWN
,
38 LTTV_STATS_MODE_TYPES
,
42 LTTV_STATS_EVENT_TYPES
,
44 LTTV_STATS_CUMULATIVE_CPU_TIME
,
45 LTTV_STATS_ELAPSED_TIME
,
47 LTTV_STATS_EVENTS_COUNT
,
50 LTTV_STATS_TRACEFILES
,
52 LTTV_STATS_BEFORE_HOOKS
,
53 LTTV_STATS_AFTER_HOOKS
;
56 find_event_tree(LttvTracefileStats
*tfcs
, GQuark pid_time
, guint cpu
,
58 GQuark mode
, GQuark sub_mode
, LttvAttribute
**events_tree
,
59 LttvAttribute
**event_types_tree
);
62 static void lttv_stats_init(LttvTracesetStats
*self
)
64 guint i
, j
, nb_trace
, nb_tracefile
;
70 LttvTracefileContext
**tfs
;
71 LttvTracefileStats
*tfcs
;
75 LttvAttribute
*tracefiles_stats
;
77 LttvTraceset
*ts
= self
->parent
.parent
.ts
;
79 self
->stats
= lttv_attribute_find_subdir(
80 lttv_traceset_attribute(self
->parent
.parent
.ts
),
82 lttv_attribute_find(lttv_traceset_attribute(self
->parent
.parent
.ts
),
87 if(*(v
.v_uint
) == 1) {
88 g_assert(lttv_attribute_get_number(self
->stats
) == 0);
91 nb_trace
= lttv_traceset_number(ts
);
93 for(i
= 0 ; i
< nb_trace
; i
++) {
94 tc
= self
->parent
.parent
.traces
[i
];
95 tcs
= LTTV_TRACE_STATS(tc
);
97 tcs
->stats
= lttv_attribute_find_subdir(tcs
->parent
.parent
.t_a
,LTTV_STATS
);
98 tracefiles_stats
= lttv_attribute_find_subdir(tcs
->parent
.parent
.t_a
,
99 LTTV_STATS_TRACEFILES
);
100 lttv_attribute_find(tcs
->parent
.parent
.t_a
, LTTV_STATS_USE_COUNT
,
104 if(*(v
.v_uint
) == 1) {
105 g_assert(lttv_attribute_get_number(tcs
->stats
) == 0);
108 nb_tracefile
= tc
->tracefiles
->len
;
110 for(j
= 0 ; j
< nb_tracefile
; j
++) {
111 tfs
= &g_array_index(tc
->tracefiles
,
112 LttvTracefileContext
*, j
);
113 tfcs
= LTTV_TRACEFILE_STATS(*tfs
);
114 tfcs
->stats
= lttv_attribute_find_subdir(tracefiles_stats
,
115 ltt_tracefile_long_name(tfcs
->parent
.parent
.tf
));
116 guint cpu
= tfcs
->parent
.cpu
;
117 find_event_tree(tfcs
, LTTV_STATS_PROCESS_UNKNOWN
,
120 LTTV_STATE_MODE_UNKNOWN
,
121 LTTV_STATE_SUBMODE_UNKNOWN
, &tfcs
->current_events_tree
,
122 &tfcs
->current_event_types_tree
);
128 static void lttv_stats_fini(LttvTracesetStats
*self
)
130 guint i
, j
, nb_trace
, nb_tracefile
;
134 LttvTraceContext
*tc
;
138 LttvTracefileContext
*tfc
;
140 LttvTracefileStats
*tfcs
;
142 LttvAttributeValue v
;
144 LttvAttribute
*tracefiles_stats
;
146 lttv_attribute_find(self
->parent
.parent
.ts_a
, LTTV_STATS_USE_COUNT
,
150 if(*(v
.v_uint
) == 0) {
151 lttv_attribute_remove_by_name(self
->parent
.parent
.ts_a
, LTTV_STATS
);
155 ts
= self
->parent
.parent
.ts
;
156 nb_trace
= lttv_traceset_number(ts
);
158 for(i
= 0 ; i
< nb_trace
; i
++) {
159 tcs
= (LttvTraceStats
*)(tc
= (LTTV_TRACESET_CONTEXT(self
)->traces
[i
]));
161 lttv_attribute_find(tcs
->parent
.parent
.t_a
, LTTV_STATS_USE_COUNT
,
165 if(*(v
.v_uint
) == 0) {
166 lttv_attribute_remove_by_name(tcs
->parent
.parent
.t_a
,LTTV_STATS
);
167 tracefiles_stats
= lttv_attribute_find_subdir(tcs
->parent
.parent
.t_a
,
168 LTTV_STATS_TRACEFILES
);
169 lttv_attribute_remove_by_name(tcs
->parent
.parent
.t_a
,
170 LTTV_STATS_TRACEFILES
);
174 nb_tracefile
= tc
->tracefiles
->len
;
176 for(j
= 0 ; j
< nb_tracefile
; j
++) {
177 tfc
= g_array_index(tc
->tracefiles
,
178 LttvTracefileContext
*, j
);
179 tfcs
= (LttvTracefileStats
*)tfc
;
181 tfcs
->current_events_tree
= NULL
;
182 tfcs
->current_event_types_tree
= NULL
;
188 void lttv_stats_reset(LttvTracesetStats
*self
)
190 lttv_stats_fini(self
);
191 lttv_stats_init(self
);
197 init(LttvTracesetStats
*self
, LttvTraceset
*ts
)
199 LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE
))->
200 init((LttvTracesetContext
*)self
, ts
);
202 lttv_stats_init(self
);
207 fini(LttvTracesetStats
*self
)
209 lttv_stats_fini(self
);
211 LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE
))->
212 fini((LttvTracesetContext
*)self
);
216 static LttvTracesetContext
*
217 new_traceset_context(LttvTracesetContext
*self
)
219 return LTTV_TRACESET_CONTEXT(g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
));
223 static LttvTraceContext
*
224 new_trace_context(LttvTracesetContext
*self
)
226 return LTTV_TRACE_CONTEXT(g_object_new(LTTV_TRACE_STATS_TYPE
, NULL
));
230 static LttvTracefileContext
*
231 new_tracefile_context(LttvTracesetContext
*self
)
233 return LTTV_TRACEFILE_CONTEXT(g_object_new(LTTV_TRACEFILE_STATS_TYPE
, NULL
));
238 traceset_stats_instance_init (GTypeInstance
*instance
, gpointer g_class
)
244 traceset_stats_finalize (LttvTracesetStats
*self
)
246 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE
))->
247 finalize(G_OBJECT(self
));
252 traceset_stats_class_init (LttvTracesetContextClass
*klass
)
254 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
256 gobject_class
->finalize
= (void (*)(GObject
*self
)) traceset_stats_finalize
;
257 klass
->init
= (void (*)(LttvTracesetContext
*self
, LttvTraceset
*ts
))init
;
258 klass
->fini
= (void (*)(LttvTracesetContext
*self
))fini
;
259 klass
->new_traceset_context
= new_traceset_context
;
260 klass
->new_trace_context
= new_trace_context
;
261 klass
->new_tracefile_context
= new_tracefile_context
;
266 lttv_traceset_stats_get_type(void)
268 static GType type
= 0;
270 static const GTypeInfo info
= {
271 sizeof (LttvTracesetStatsClass
),
272 NULL
, /* base_init */
273 NULL
, /* base_finalize */
274 (GClassInitFunc
) traceset_stats_class_init
, /* class_init */
275 NULL
, /* class_finalize */
276 NULL
, /* class_data */
277 sizeof (LttvTracesetStats
),
279 (GInstanceInitFunc
) traceset_stats_instance_init
, /* instance_init */
280 NULL
/* Value handling */
283 type
= g_type_register_static (LTTV_TRACESET_STATE_TYPE
,
284 "LttvTracesetStatsType",
292 trace_stats_instance_init (GTypeInstance
*instance
, gpointer g_class
)
298 trace_stats_finalize (LttvTraceStats
*self
)
300 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACE_STATE_TYPE
))->
301 finalize(G_OBJECT(self
));
306 trace_stats_class_init (LttvTraceContextClass
*klass
)
308 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
310 gobject_class
->finalize
= (void (*)(GObject
*self
)) trace_stats_finalize
;
315 lttv_trace_stats_get_type(void)
317 static GType type
= 0;
319 static const GTypeInfo info
= {
320 sizeof (LttvTraceStatsClass
),
321 NULL
, /* base_init */
322 NULL
, /* base_finalize */
323 (GClassInitFunc
) trace_stats_class_init
, /* class_init */
324 NULL
, /* class_finalize */
325 NULL
, /* class_data */
326 sizeof (LttvTraceStats
),
328 (GInstanceInitFunc
) trace_stats_instance_init
, /* instance_init */
329 NULL
/* Value handling */
332 type
= g_type_register_static (LTTV_TRACE_STATE_TYPE
,
333 "LttvTraceStatsType", &info
, 0);
340 tracefile_stats_instance_init (GTypeInstance
*instance
, gpointer g_class
)
346 tracefile_stats_finalize (LttvTracefileStats
*self
)
348 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACEFILE_STATE_TYPE
))->
349 finalize(G_OBJECT(self
));
354 tracefile_stats_class_init (LttvTracefileStatsClass
*klass
)
356 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
358 gobject_class
->finalize
= (void (*)(GObject
*self
)) tracefile_stats_finalize
;
363 lttv_tracefile_stats_get_type(void)
365 static GType type
= 0;
367 static const GTypeInfo info
= {
368 sizeof (LttvTracefileStatsClass
),
369 NULL
, /* base_init */
370 NULL
, /* base_finalize */
371 (GClassInitFunc
) tracefile_stats_class_init
, /* class_init */
372 NULL
, /* class_finalize */
373 NULL
, /* class_data */
374 sizeof (LttvTracefileStats
),
376 (GInstanceInitFunc
) tracefile_stats_instance_init
, /* instance_init */
377 NULL
/* Value handling */
380 type
= g_type_register_static (LTTV_TRACEFILE_STATE_TYPE
,
381 "LttvTracefileStatsType", &info
, 0);
387 find_event_tree(LttvTracefileStats
*tfcs
,
393 LttvAttribute
**events_tree
,
394 LttvAttribute
**event_types_tree
)
397 gchar fstring
[MAX_64_HEX_STRING_LEN
];
400 ret
= snprintf(fstring
, MAX_64_HEX_STRING_LEN
-1,
401 "0x%llX", function
) > 0;
403 fstring
[MAX_64_HEX_STRING_LEN
-1] = '\0';
405 LttvTraceStats
*tcs
= (LttvTraceStats
*)tfcs
->parent
.parent
.t_context
;
406 a
= lttv_attribute_find_subdir(tcs
->stats
, LTTV_STATS_PROCESSES
);
407 a
= lttv_attribute_find_subdir(a
, pid_time
);
408 a
= lttv_attribute_find_subdir(a
, LTTV_STATS_CPU
);
409 a
= lttv_attribute_find_subdir_unnamed(a
, cpu
);
410 a
= lttv_attribute_find_subdir(a
, LTTV_STATS_FUNCTIONS
);
411 a
= lttv_attribute_find_subdir(a
, g_quark_from_string(fstring
));
412 a
= lttv_attribute_find_subdir(a
, LTTV_STATS_MODE_TYPES
);
413 a
= lttv_attribute_find_subdir(a
, mode
);
414 a
= lttv_attribute_find_subdir(a
, LTTV_STATS_SUBMODES
);
415 a
= lttv_attribute_find_subdir(a
, sub_mode
);
417 a
= lttv_attribute_find_subdir(a
, LTTV_STATS_EVENT_TYPES
);
418 *event_types_tree
= a
;
421 static void update_event_tree(LttvTracefileStats
*tfcs
)
423 guint cpu
= tfcs
->parent
.cpu
;
424 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
425 LttvProcessState
*process
= ts
->running_process
[cpu
];
426 LttvExecutionState
*es
= process
->state
;
428 find_event_tree(tfcs
, process
->pid_time
,
430 process
->current_function
,
431 es
->t
, es
->n
, &(tfcs
->current_events_tree
),
432 &(tfcs
->current_event_types_tree
));
436 /* Update the trace event tree for the specified cpu */
437 static void update_trace_event_tree(LttvTraceStats
*tcs
)
439 LttvTracefileStats
*tfcs
;
440 LttvTraceContext
*tc
= (LttvTraceContext
*)tcs
;
441 guint j
, nb_tracefile
;
443 /* For each tracefile, update the event tree */
444 nb_tracefile
= tc
->tracefiles
->len
;
445 for(j
= 0; j
< nb_tracefile
; j
++) {
446 tfcs
= LTTV_TRACEFILE_STATS(g_array_index(tc
->tracefiles
,
447 LttvTracefileContext
*, j
));
448 update_event_tree(tfcs
);
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
;
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 //void *lasttree = tfcs->current_events_tree;
489 //update_event_tree(tfcs);
490 //g_assert (lasttree == tfcs->current_events_tree);
491 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_STATS_ELAPSED_TIME
,
492 LTTV_TIME
, &elapsed_time
);
494 if(process
->state
->t
!= LTTV_STATE_MODE_UNKNOWN
) {
495 delta
= ltt_time_sub(tfcs
->parent
.parent
.timestamp
,
496 process
->state
->entry
);
498 delta
= ltt_time_zero
;
500 *(elapsed_time
.v_time
) = ltt_time_add(*(elapsed_time
.v_time
), delta
);
502 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_STATS_CPU_TIME
,
503 LTTV_TIME
, &cpu_time
);
505 /* if it is a running mode, we must count its cpu time */
506 if(process
->state
->s
== LTTV_STATE_RUN
&&
507 process
->state
->t
!= LTTV_STATE_MODE_UNKNOWN
)
508 delta
= ltt_time_sub(tfcs
->parent
.parent
.timestamp
,
509 process
->state
->change
);
511 delta
= ltt_time_zero
;
513 *(cpu_time
.v_time
) = ltt_time_add(*(cpu_time
.v_time
), delta
);
514 process
->state
->cum_cpu_time
= ltt_time_add(process
->state
->cum_cpu_time
,
517 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_STATS_CUMULATIVE_CPU_TIME
,
518 LTTV_TIME
, &cum_cpu_time
);
519 *(cum_cpu_time
.v_time
) = ltt_time_add(*(cum_cpu_time
.v_time
),
520 process
->state
->cum_cpu_time
);
524 static void after_mode_end(LttvTracefileStats
*tfcs
)
526 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
527 guint cpu
= tfcs
->parent
.cpu
;
528 LttvProcessState
*process
= ts
->running_process
[cpu
];
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 static 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 static 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 static gboolean
before_trap_exit(void *hook_data
, void *call_data
)
585 mode_end((LttvTracefileStats
*)call_data
);
590 static gboolean
after_trap_exit(void *hook_data
, void *call_data
)
592 after_mode_end((LttvTracefileStats
*)call_data
);
597 static gboolean
before_irq_entry(void *hook_data
, void *call_data
)
599 mode_change((LttvTracefileStats
*)call_data
);
603 static gboolean
after_irq_entry(void *hook_data
, void *call_data
)
605 update_event_tree((LttvTracefileStats
*)call_data
);
610 static gboolean
before_irq_exit(void *hook_data
, void *call_data
)
612 mode_end((LttvTracefileStats
*)call_data
);
617 static gboolean
after_irq_exit(void *hook_data
, void *call_data
)
619 after_mode_end((LttvTracefileStats
*)call_data
);
624 static gboolean
before_soft_irq_entry(void *hook_data
, void *call_data
)
626 mode_change((LttvTracefileStats
*)call_data
);
630 static gboolean
after_soft_irq_entry(void *hook_data
, void *call_data
)
632 update_event_tree((LttvTracefileStats
*)call_data
);
636 static gboolean
before_soft_irq_exit(void *hook_data
, void *call_data
)
638 mode_end((LttvTracefileStats
*)call_data
);
643 static gboolean
after_soft_irq_exit(void *hook_data
, void *call_data
)
645 after_mode_end((LttvTracefileStats
*)call_data
);
649 static gboolean
before_function_entry(void *hook_data
, void *call_data
)
651 mode_change((LttvTracefileStats
*)call_data
);
655 static gboolean
after_function_entry(void *hook_data
, void *call_data
)
657 update_event_tree((LttvTracefileStats
*)call_data
);
661 static gboolean
before_function_exit(void *hook_data
, void *call_data
)
663 mode_end((LttvTracefileStats
*)call_data
);
667 static gboolean
after_function_exit(void *hook_data
, void *call_data
)
669 after_mode_end((LttvTracefileStats
*)call_data
);
674 static gboolean
before_schedchange(void *hook_data
, void *call_data
)
676 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
678 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
680 LttvTraceHook
*th
= (LttvTraceHook
*)hook_data
;
682 guint pid_in
, pid_out
;
686 pid_out
= ltt_event_get_unsigned(e
, th
->f1
);
687 pid_in
= ltt_event_get_unsigned(e
, th
->f2
);
688 state_out
= ltt_event_get_long_int(e
, th
->f3
);
690 /* compute the time for the process to schedule out */
696 static gboolean
after_schedchange(void *hook_data
, void *call_data
)
698 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
700 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
702 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
704 LttvTraceHook
*th
= (LttvTraceHook
*)hook_data
;
706 guint pid_in
, pid_out
;
710 LttvProcessState
*process
;
712 pid_out
= ltt_event_get_unsigned(e
, th
->f1
);
713 pid_in
= ltt_event_get_unsigned(e
, th
->f2
);
714 state_out
= ltt_event_get_long_int(e
, th
->f3
);
716 /* get the information for the process scheduled in */
717 guint cpu
= tfcs
->parent
.cpu
;
718 process
= ts
->running_process
[cpu
];
720 find_event_tree(tfcs
, process
->pid_time
,
722 process
->current_function
,
723 process
->state
->t
, process
->state
->n
, &(tfcs
->current_events_tree
),
724 &(tfcs
->current_event_types_tree
));
726 /* compute the time waiting for the process to schedule in */
732 static gboolean
process_fork(void *hook_data
, void *call_data
)
737 static gboolean
process_exit(void *hook_data
, void *call_data
)
739 update_event_tree((LttvTracefileStats
*)call_data
);
743 static gboolean
before_enum_process_state(void *hook_data
, void *call_data
)
746 /* Broken : adds up time in the current process doing the dump */
747 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
749 after_mode_end(tfcs
);
755 static gboolean
after_enum_process_state(void *hook_data
, void *call_data
)
757 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
758 LttvTraceStats
*tcs
= (LttvTraceStats
*)tfc
->t_context
;
759 update_trace_event_tree(tcs
);
763 static gboolean
after_statedump_end(void *hook_data
, void *call_data
)
765 LttvTracefileContext
*tfc
= (LttvTracefileContext
*)call_data
;
766 LttvTraceStats
*tcs
= (LttvTraceStats
*)tfc
->t_context
;
767 update_trace_event_tree(tcs
);
771 static gboolean
process_free(void *hook_data
, void *call_data
)
776 static gboolean
every_event(void *hook_data
, void *call_data
)
778 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
780 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
782 LttvAttributeValue v
;
784 /* The current branch corresponds to the tracefile/process/interrupt state.
785 Statistics are added within it, to count the number of events of this
786 type occuring in this context. A quark has been pre-allocated for each
787 event type and is used as name. */
789 lttv_attribute_find(tfcs
->current_event_types_tree
,
790 ltt_eventtype_name(ltt_event_eventtype(e
)),
796 struct cleanup_state_struct
{
798 LttTime current_time
;
801 //static void lttv_stats_cleanup_process_state(LttvTraceState *ts,
802 // LttvProcessState *process, LttTime current_time)
803 static void lttv_stats_cleanup_process_state(gpointer key
, gpointer value
,
806 struct cleanup_state_struct
*cleanup_closure
=
807 (struct cleanup_state_struct
*)user_data
;
808 LttvTraceState
*ts
= cleanup_closure
->ts
;
809 LttvProcessState
*process
= (LttvProcessState
*)value
;
810 LttTime current_time
= cleanup_closure
->current_time
;
811 LttvTracefileStats
**tfs
= (LttvTracefileStats
**)
812 &g_array_index(ts
->parent
.tracefiles
, LttvTracefileContext
*,
814 int cleanup_empty
= 0;
815 LttTime nested_delta
= ltt_time_zero
;
817 /* FIXME : ok, this is a hack. The time is infinite here :( */
818 //LttTime save_time = (*tfs)->parent.parent.timestamp;
819 //LttTime start, end;
820 //ltt_trace_time_span_get(ts->parent.t, &start, &end);
821 //(*tfs)->parent.parent.timestamp = end;
824 if(ltt_time_compare(process
->state
->cum_cpu_time
, ltt_time_zero
) != 0) {
825 find_event_tree(*tfs
, process
->pid_time
,
827 process
->current_function
,
828 process
->state
->t
, process
->state
->n
, &((*tfs
)->current_events_tree
),
829 &((*tfs
)->current_event_types_tree
));
830 /* Call mode_end only if not at end of trace */
831 if(ltt_time_compare(current_time
, ltt_time_infinite
) != 0)
833 nested_delta
= process
->state
->cum_cpu_time
;
835 cleanup_empty
= lttv_state_pop_state_cleanup(process
,
836 (LttvTracefileState
*)*tfs
);
837 process
->state
->cum_cpu_time
= ltt_time_add(process
->state
->cum_cpu_time
,
840 } while(cleanup_empty
!= 1);
842 //(*tfs)->parent.parent.timestamp = save_time;
845 /* For each cpu, for each of their stacked states,
846 * perform sum of needed values. */
847 static void lttv_stats_cleanup_state(LttvTraceStats
*tcs
, LttTime current_time
)
849 LttvTraceState
*ts
= (LttvTraceState
*)tcs
;
850 struct cleanup_state_struct cleanup_closure
;
854 nb_cpus
= ltt_trace_get_num_cpu(ts
->parent
.t
);
856 for(i
=0; i
<nb_cpus
; i
++) {
857 lttv_stats_cleanup_process_state(ts
, ts
->running_process
[i
], current_time
);
860 cleanup_closure
.ts
= tcs
;
861 cleanup_closure
.current_time
= current_time
;
862 g_hash_table_foreach(ts
->processes
, lttv_stats_cleanup_process_state
,
867 lttv_stats_sum_trace(LttvTraceStats
*self
, LttvAttribute
*ts_stats
,
868 LttTime current_time
)
870 LttvAttribute
*sum_container
= self
->stats
;
872 LttvAttributeType type
;
874 LttvAttributeValue value
;
876 LttvAttributeName name
;
884 int i
, j
, k
, l
, m
, nb_process
, nb_cpu
, nb_mode_type
, nb_submode
,
885 nb_event_type
, nf
, nb_functions
;
887 LttvAttribute
*main_tree
, *processes_tree
, *process_tree
, *cpus_tree
,
888 *cpu_tree
, *mode_tree
, *mode_types_tree
, *submodes_tree
,
889 *submode_tree
, *event_types_tree
, *mode_events_tree
,
892 *function_mode_types_tree
,
896 main_tree
= sum_container
;
898 lttv_attribute_find(sum_container
,
901 trace_is_summed
= *(value
.v_uint
);
904 /* First cleanup the state : sum all stalled information (never ending
907 lttv_stats_cleanup_state(self
, current_time
);
909 processes_tree
= lttv_attribute_find_subdir(main_tree
,
910 LTTV_STATS_PROCESSES
);
911 nb_process
= lttv_attribute_get_number(processes_tree
);
913 for(i
= 0 ; i
< nb_process
; i
++) {
914 type
= lttv_attribute_get(processes_tree
, i
, &name
, &value
, &is_named
);
915 process_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
917 cpus_tree
= lttv_attribute_find_subdir(process_tree
, LTTV_STATS_CPU
);
918 nb_cpu
= lttv_attribute_get_number(cpus_tree
);
920 for(j
= 0 ; j
< nb_cpu
; j
++) {
921 type
= lttv_attribute_get(cpus_tree
, j
, &name
, &value
, &is_named
);
922 cpu_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
924 trace_cpu_tree
= lttv_attribute_find_subdir(main_tree
, LTTV_STATS_CPU
);
925 trace_cpu_tree
= lttv_attribute_find_subdir_unnamed(trace_cpu_tree
, name
);
926 cpu_functions_tree
= lttv_attribute_find_subdir(cpu_tree
,
927 LTTV_STATS_FUNCTIONS
);
928 nb_functions
= lttv_attribute_get_number(cpu_functions_tree
);
930 for(nf
=0; nf
< nb_functions
; nf
++) {
931 type
= lttv_attribute_get(cpu_functions_tree
, nf
, &name
, &value
,
933 function_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
934 function_mode_types_tree
= lttv_attribute_find_subdir(function_tree
,
935 LTTV_STATS_MODE_TYPES
);
936 nb_mode_type
= lttv_attribute_get_number(function_mode_types_tree
);
937 for(k
= 0 ; k
< nb_mode_type
; k
++) {
938 type
= lttv_attribute_get(function_mode_types_tree
, k
, &name
, &value
,
940 mode_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
942 submodes_tree
= lttv_attribute_find_subdir(mode_tree
,
943 LTTV_STATS_SUBMODES
);
944 mode_events_tree
= lttv_attribute_find_subdir(mode_tree
,
946 mode_types_tree
= lttv_attribute_find_subdir(mode_tree
,
947 LTTV_STATS_MODE_TYPES
);
949 nb_submode
= lttv_attribute_get_number(submodes_tree
);
951 for(l
= 0 ; l
< nb_submode
; l
++) {
952 type
= lttv_attribute_get(submodes_tree
, l
, &name
, &value
,
954 submode_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
956 event_types_tree
= lttv_attribute_find_subdir(submode_tree
,
957 LTTV_STATS_EVENT_TYPES
);
958 nb_event_type
= lttv_attribute_get_number(event_types_tree
);
961 for(m
= 0 ; m
< nb_event_type
; m
++) {
962 type
= lttv_attribute_get(event_types_tree
, m
, &name
, &value
,
964 sum
+= *(value
.v_uint
);
966 lttv_attribute_find(submode_tree
, LTTV_STATS_EVENTS_COUNT
,
968 *(value
.v_uint
) = sum
;
970 type
= lttv_attribute_get(submodes_tree
, l
, &name
, &value
,
972 submode_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
973 if(!trace_is_summed
) {
974 lttv_attribute_recursive_add(mode_events_tree
, event_types_tree
);
975 lttv_attribute_recursive_add(mode_types_tree
, submode_tree
);
978 if(!trace_is_summed
) {
979 lttv_attribute_recursive_add(function_tree
, mode_types_tree
);
982 if(!trace_is_summed
) {
983 lttv_attribute_recursive_add(cpu_tree
, function_tree
);
984 lttv_attribute_recursive_add(process_tree
, function_tree
);
985 lttv_attribute_recursive_add(trace_cpu_tree
, function_tree
);
986 lttv_attribute_recursive_add(main_tree
, function_tree
);
988 lttv_attribute_recursive_add(ts_stats
, function_tree
);
995 gboolean
lttv_stats_sum_traceset_hook(void *hook_data
, void *call_data
)
997 struct sum_traceset_closure
*closure
=
998 (struct sum_traceset_closure
*)call_data
;
999 lttv_stats_sum_traceset(closure
->tss
, closure
->current_time
);
1004 lttv_stats_sum_traceset(LttvTracesetStats
*self
, LttTime current_time
)
1006 LttvTraceset
*traceset
= self
->parent
.parent
.ts
;
1007 LttvAttribute
*sum_container
= self
->stats
;
1009 LttvTraceStats
*tcs
;
1013 LttvAttributeValue value
;
1015 lttv_attribute_find(sum_container
, LTTV_STATS_SUMMED
,
1017 if(*(value
.v_uint
) != 0) return;
1018 *(value
.v_uint
) = 1;
1020 nb_trace
= lttv_traceset_number(traceset
);
1022 for(i
= 0 ; i
< nb_trace
; i
++) {
1023 tcs
= (LttvTraceStats
*)(self
->parent
.parent
.traces
[i
]);
1024 lttv_stats_sum_trace(tcs
, self
->stats
, current_time
);
1025 // lttv_attribute_recursive_add(sum_container, tcs->stats);
1030 // Hook wrapper. call_data is a traceset context.
1031 gboolean
lttv_stats_hook_add_event_hooks(void *hook_data
, void *call_data
)
1033 LttvTracesetStats
*tss
= (LttvTracesetStats
*)call_data
;
1035 lttv_stats_add_event_hooks(tss
);
1040 void lttv_stats_add_event_hooks(LttvTracesetStats
*self
)
1042 LttvTraceset
*traceset
= self
->parent
.parent
.ts
;
1044 guint i
, j
, k
, nb_trace
, nb_tracefile
;
1048 LttvTracefileStats
*tfs
;
1050 GArray
*hooks
, *before_hooks
, *after_hooks
;
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_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_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_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_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_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
,
1108 before_irq_exit
, NULL
,
1109 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1112 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1113 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_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_EVENT_SCHED_SCHEDULE
,
1128 LTT_FIELD_PREV_PID
, LTT_FIELD_NEXT_PID
, LTT_FIELD_PREV_STATE
,
1129 before_schedchange
, NULL
,
1130 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1133 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1134 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_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_EVENT_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_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_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_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_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_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
,
1201 after_irq_exit
, NULL
,
1202 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1205 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1206 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_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_EVENT_SCHED_SCHEDULE
,
1221 LTT_FIELD_PREV_PID
, LTT_FIELD_NEXT_PID
, LTT_FIELD_PREV_STATE
,
1222 after_schedchange
, NULL
,
1223 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1226 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1227 LTT_EVENT_PROCESS_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_EVENT_PROCESS_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_EVENT_PROCESS_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_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_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_EVENT_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_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 th
= &g_array_index(before_hooks
, LttvTraceHook
, k
);
1293 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, th
->id
),
1296 LTTV_PRIO_STATS_BEFORE_STATE
);
1298 for(k
= 0 ; k
< after_hooks
->len
; k
++) {
1299 th
= &g_array_index(after_hooks
, LttvTraceHook
, k
);
1301 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, th
->id
),
1304 LTTV_PRIO_STATS_AFTER_STATE
);
1307 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_BEFORE_HOOKS
,
1308 LTTV_POINTER
, &val
);
1309 *(val
.v_pointer
) = before_hooks
;
1310 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_AFTER_HOOKS
,
1311 LTTV_POINTER
, &val
);
1312 *(val
.v_pointer
) = after_hooks
;
1316 // Hook wrapper. call_data is a traceset context.
1317 gboolean
lttv_stats_hook_remove_event_hooks(void *hook_data
, void *call_data
)
1319 LttvTracesetStats
*tss
= (LttvTracesetStats
*)call_data
;
1321 lttv_stats_remove_event_hooks(tss
);
1326 void lttv_stats_remove_event_hooks(LttvTracesetStats
*self
)
1328 LttvTraceset
*traceset
= self
->parent
.parent
.ts
;
1330 guint i
, j
, k
, nb_trace
, nb_tracefile
;
1334 LttvTracefileStats
*tfs
;
1336 GArray
*before_hooks
, *after_hooks
;
1340 LttvAttributeValue val
;
1342 nb_trace
= lttv_traceset_number(traceset
);
1343 for(i
= 0 ; i
< nb_trace
; i
++) {
1344 ts
= (LttvTraceStats
*)self
->parent
.parent
.traces
[i
];
1345 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_BEFORE_HOOKS
,
1346 LTTV_POINTER
, &val
);
1347 before_hooks
= *(val
.v_pointer
);
1348 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_AFTER_HOOKS
,
1349 LTTV_POINTER
, &val
);
1350 after_hooks
= *(val
.v_pointer
);
1352 /* Remove these hooks from each event_by_id hooks list */
1354 nb_tracefile
= ts
->parent
.parent
.tracefiles
->len
;
1356 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1357 tfs
= LTTV_TRACEFILE_STATS(g_array_index(ts
->parent
.parent
.tracefiles
,
1358 LttvTracefileContext
*, j
));
1359 lttv_hooks_remove_data(tfs
->parent
.parent
.event
, every_event
,
1362 for(k
= 0 ; k
< before_hooks
->len
; k
++) {
1363 th
= &g_array_index(before_hooks
, LttvTraceHook
, k
);
1364 lttv_hooks_remove_data(
1365 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, th
->id
),
1369 for(k
= 0 ; k
< after_hooks
->len
; k
++) {
1370 th
= &g_array_index(after_hooks
, LttvTraceHook
, k
);
1371 lttv_hooks_remove_data(
1372 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, th
->id
),
1378 g_debug("lttv_stats_remove_event_hooks()");
1379 g_array_free(before_hooks
, TRUE
);
1380 g_array_free(after_hooks
, TRUE
);
1385 static void module_init()
1387 LTTV_STATS_PROCESS_UNKNOWN
= g_quark_from_string("unknown process");
1388 LTTV_STATS_PROCESSES
= g_quark_from_string("processes");
1389 LTTV_STATS_CPU
= g_quark_from_string("cpu");
1390 LTTV_STATS_MODE_TYPES
= g_quark_from_string("mode_types");
1391 LTTV_STATS_MODES
= g_quark_from_string("modes");
1392 LTTV_STATS_SUBMODES
= g_quark_from_string("submodes");
1393 LTTV_STATS_FUNCTIONS
= g_quark_from_string("functions");
1394 LTTV_STATS_EVENT_TYPES
= g_quark_from_string("event_types");
1395 LTTV_STATS_CPU_TIME
= g_quark_from_string("cpu time");
1396 LTTV_STATS_CUMULATIVE_CPU_TIME
= g_quark_from_string("cumulative cpu time (includes nested routines and modes)");
1397 LTTV_STATS_ELAPSED_TIME
= g_quark_from_string("elapsed time (includes per process waiting time)");
1398 LTTV_STATS_EVENTS
= g_quark_from_string("events");
1399 LTTV_STATS_EVENTS_COUNT
= g_quark_from_string("events count");
1400 LTTV_STATS_BEFORE_HOOKS
= g_quark_from_string("saved stats before hooks");
1401 LTTV_STATS_AFTER_HOOKS
= g_quark_from_string("saved stats after hooks");
1402 LTTV_STATS_USE_COUNT
= g_quark_from_string("stats_use_count");
1403 LTTV_STATS
= g_quark_from_string("statistics");
1404 LTTV_STATS_TRACEFILES
= g_quark_from_string("tracefiles statistics");
1405 LTTV_STATS_SUMMED
= g_quark_from_string("statistics summed");
1408 static void module_destroy()
1413 LTTV_MODULE("stats", "Compute processes statistics", \
1414 "Accumulate statistics for event types, processes and CPUs", \
1415 module_init
, module_destroy
, "state");
1417 /* Change the places where stats are called (create/read/write stats)
1419 Check for options in batchtest.c to reduce writing and see what tests are
1420 best candidates for performance analysis. Once OK, commit, move to main
1421 and run tests. Update the gui for statistics. */