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
,
56 /***********************************************************/
57 LTTV_XENO_STATS_THREADS
,
58 LTTV_XENO_STATS_THREAD_PERIOD
,
59 LTTV_XENO_STATS_THREAD_PRIO
,
60 LTTV_XENO_STATS_STATE
,
61 LTTV_XENO_STATS_SYNCH
,
62 LTTV_XENO_STATS_PERIOD
,
63 LTTV_XENO_STATS_PERIOD_OVERRUNS
,
64 LTTV_XENO_STATS_TEXT_OVERRUNS
,
65 LTTV_XENO_STATS_TEXT_TICKS
,
66 LTTV_XENO_STATS_TEXT_TOTAL
,
67 LTTV_XENO_STATS_TEXT_OWNER
,
68 LTTV_XENO_STATS_TEXT_WAITING
,
69 LTTV_XENO_STATS_TEXT_OWNER_TOTAL
,
70 LTTV_XENO_STATS_TEXT_OWNER_MAX
,
71 LTTV_XENO_STATS_TEXT_OWNER_MIN
,
72 LTTV_XENO_STATS_TEXT_OWNER_AVG
,
73 LTTV_XENO_STATS_TEXT_WAITING
,
74 LTTV_XENO_STATS_TEXT_WAITING_TOTAL
,
75 LTTV_XENO_STATS_TEXT_WAITING_MAX
,
76 LTTV_XENO_STATS_TEXT_WAITING_MIN
,
77 LTTV_XENO_STATS_TEXT_WAITING_AVG
,
78 LTTV_XENO_STATS_TEXT_READY_MAX
,
79 LTTV_XENO_STATS_TEXT_READY_MIN
,
80 LTTV_XENO_STATS_TEXT_READY_AVG
,
81 LTTV_XENO_STATS_TEXT_RUNNING_MAX
,
82 LTTV_XENO_STATS_TEXT_RUNNING_MIN
,
83 LTTV_XENO_STATS_TEXT_RUNNING_AVG
,
84 LTTV_XENO_STATS_TEXT_SUSPEND_MAX
,
85 LTTV_XENO_STATS_TEXT_SUSPEND_MIN
,
86 LTTV_XENO_STATS_TEXT_SUSPEND_AVG
,
87 LTTV_XENO_STATS_NB_PERIOD
,
89 /***********************************************************/
91 /****************************************************************************************************************************/
92 static void xeno_find_task_tree(LttvTracefileStats
*tfcs
, GQuark name
, gulong address
, guint cpu
, LttvAttribute
**events_tree
, LttvAttribute
**event_types_tree
);
93 gboolean
xenoltt_thread_init(void *hook_data
, void *call_data
);
94 gboolean
xenoltt_thread_set_period(void *hook_data
, void *call_data
);
95 gboolean
xenoltt_thread_renice(void *hook_data
, void *call_data
);
96 gboolean
xenoltt_before_change_state(void *hook_data
, void *call_data
);
97 gboolean
xenoltt_after_change_state(void *hook_data
, void *call_data
);
98 gboolean
xenoltt_thread_overruns(void *hook_data
, void *call_data
);
99 gboolean
xenoltt_synch_owner(void *hook_data
, void *call_data
);
100 gboolean
xenoltt_synch_wait(void *hook_data
, void *call_data
);
101 gboolean
xenoltt_synch_unblock(void *hook_data
, void *call_data
);
102 gboolean
xenoltt_synch_wakeup(void *hook_data
, void *call_data
);
103 gboolean
xenoltt_synch_flush(void *hook_data
, void *call_data
);
104 /****************************************************************************************************************************/
106 find_event_tree(LttvTracefileStats
*tfcs
, GQuark pid_time
, guint cpu
,
108 GQuark mode
, GQuark sub_mode
, LttvAttribute
**events_tree
,
109 LttvAttribute
**event_types_tree
);
112 static void lttv_stats_init(LttvTracesetStats
*self
)
114 guint i
, j
, nb_trace
, nb_tracefile
;
116 LttvTraceContext
*tc
;
120 LttvTracefileContext
**tfs
;
121 LttvTracefileStats
*tfcs
;
123 LttvAttributeValue v
;
125 LttvAttribute
*tracefiles_stats
;
127 LttvTraceset
*ts
= self
->parent
.parent
.ts
;
129 self
->stats
= lttv_attribute_find_subdir(
130 lttv_traceset_attribute(self
->parent
.parent
.ts
),
132 lttv_attribute_find(lttv_traceset_attribute(self
->parent
.parent
.ts
),
133 LTTV_STATS_USE_COUNT
,
136 self
->xenoltt_stats
= lttv_attribute_find_subdir(
137 lttv_traceset_attribute(self
->parent
.parent
.ts
),
141 if(*(v
.v_uint
) == 1) {
142 g_assert(lttv_attribute_get_number(self
->stats
) == 0);
145 nb_trace
= lttv_traceset_number(ts
);
147 for(i
= 0 ; i
< nb_trace
; i
++) {
148 tc
= self
->parent
.parent
.traces
[i
];
149 tcs
= LTTV_TRACE_STATS(tc
);
151 tcs
->stats
= lttv_attribute_find_subdir(tcs
->parent
.parent
.t_a
,LTTV_STATS
);
153 tcs
->xenoltt_stats
= lttv_attribute_find_subdir(tcs
->parent
.parent
.t_a
,LTTV_STATS
);
155 tracefiles_stats
= lttv_attribute_find_subdir(tcs
->parent
.parent
.t_a
,
156 LTTV_STATS_TRACEFILES
);
157 lttv_attribute_find(tcs
->parent
.parent
.t_a
, LTTV_STATS_USE_COUNT
,
161 if(*(v
.v_uint
) == 1) {
162 g_assert(lttv_attribute_get_number(tcs
->stats
) == 0);
165 nb_tracefile
= tc
->tracefiles
->len
;
167 for(j
= 0 ; j
< nb_tracefile
; j
++) {
168 tfs
= &g_array_index(tc
->tracefiles
,
169 LttvTracefileContext
*, j
);
170 tfcs
= LTTV_TRACEFILE_STATS(*tfs
);
171 tfcs
->stats
= lttv_attribute_find_subdir(tracefiles_stats
,
172 ltt_tracefile_long_name(tfcs
->parent
.parent
.tf
));
173 guint cpu
= tfcs
->parent
.cpu
;
174 find_event_tree(tfcs
, LTTV_STATS_PROCESS_UNKNOWN
,
177 LTTV_STATE_MODE_UNKNOWN
,
178 LTTV_STATE_SUBMODE_UNKNOWN
, &tfcs
->current_events_tree
,
179 &tfcs
->current_event_types_tree
);
184 static void lttv_stats_fini(LttvTracesetStats
*self
)
186 guint i
, j
, nb_trace
, nb_tracefile
;
190 LttvTraceContext
*tc
;
194 LttvTracefileContext
*tfc
;
196 LttvTracefileStats
*tfcs
;
198 LttvAttributeValue v
;
200 LttvAttribute
*tracefiles_stats
;
202 lttv_attribute_find(self
->parent
.parent
.ts_a
, LTTV_STATS_USE_COUNT
,
206 if(*(v
.v_uint
) == 0) {
207 lttv_attribute_remove_by_name(self
->parent
.parent
.ts_a
, LTTV_STATS
);
211 ts
= self
->parent
.parent
.ts
;
212 nb_trace
= lttv_traceset_number(ts
);
214 for(i
= 0 ; i
< nb_trace
; i
++) {
215 tcs
= (LttvTraceStats
*)(tc
= (LTTV_TRACESET_CONTEXT(self
)->traces
[i
]));
217 lttv_attribute_find(tcs
->parent
.parent
.t_a
, LTTV_STATS_USE_COUNT
,
221 if(*(v
.v_uint
) == 0) {
222 lttv_attribute_remove_by_name(tcs
->parent
.parent
.t_a
,LTTV_STATS
);
223 tracefiles_stats
= lttv_attribute_find_subdir(tcs
->parent
.parent
.t_a
,
224 LTTV_STATS_TRACEFILES
);
225 lttv_attribute_remove_by_name(tcs
->parent
.parent
.t_a
,
226 LTTV_STATS_TRACEFILES
);
230 nb_tracefile
= tc
->tracefiles
->len
;
232 for(j
= 0 ; j
< nb_tracefile
; j
++) {
233 tfc
= g_array_index(tc
->tracefiles
,
234 LttvTracefileContext
*, j
);
235 tfcs
= (LttvTracefileStats
*)tfc
;
237 tfcs
->current_events_tree
= NULL
;
238 tfcs
->current_event_types_tree
= NULL
;
244 void lttv_stats_reset(LttvTracesetStats
*self
)
246 lttv_stats_fini(self
);
247 lttv_stats_init(self
);
253 init(LttvTracesetStats
*self
, LttvTraceset
*ts
)
255 LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE
))->
256 init((LttvTracesetContext
*)self
, ts
);
258 lttv_stats_init(self
);
263 fini(LttvTracesetStats
*self
)
265 lttv_stats_fini(self
);
267 LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE
))->
268 fini((LttvTracesetContext
*)self
);
272 static LttvTracesetContext
*
273 new_traceset_context(LttvTracesetContext
*self
)
275 return LTTV_TRACESET_CONTEXT(g_object_new(LTTV_TRACESET_STATS_TYPE
, NULL
));
279 static LttvTraceContext
*
280 new_trace_context(LttvTracesetContext
*self
)
282 return LTTV_TRACE_CONTEXT(g_object_new(LTTV_TRACE_STATS_TYPE
, NULL
));
286 static LttvTracefileContext
*
287 new_tracefile_context(LttvTracesetContext
*self
)
289 return LTTV_TRACEFILE_CONTEXT(g_object_new(LTTV_TRACEFILE_STATS_TYPE
, NULL
));
294 traceset_stats_instance_init (GTypeInstance
*instance
, gpointer g_class
)
300 traceset_stats_finalize (LttvTracesetStats
*self
)
302 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE
))->
303 finalize(G_OBJECT(self
));
308 traceset_stats_class_init (LttvTracesetContextClass
*klass
)
310 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
312 gobject_class
->finalize
= (void (*)(GObject
*self
)) traceset_stats_finalize
;
313 klass
->init
= (void (*)(LttvTracesetContext
*self
, LttvTraceset
*ts
))init
;
314 klass
->fini
= (void (*)(LttvTracesetContext
*self
))fini
;
315 klass
->new_traceset_context
= new_traceset_context
;
316 klass
->new_trace_context
= new_trace_context
;
317 klass
->new_tracefile_context
= new_tracefile_context
;
322 lttv_traceset_stats_get_type(void)
324 static GType type
= 0;
326 static const GTypeInfo info
= {
327 sizeof (LttvTracesetStatsClass
),
328 NULL
, /* base_init */
329 NULL
, /* base_finalize */
330 (GClassInitFunc
) traceset_stats_class_init
, /* class_init */
331 NULL
, /* class_finalize */
332 NULL
, /* class_data */
333 sizeof (LttvTracesetStats
),
335 (GInstanceInitFunc
) traceset_stats_instance_init
, /* instance_init */
336 NULL
/* Value handling */
339 type
= g_type_register_static (LTTV_TRACESET_STATE_TYPE
,
340 "LttvTracesetStatsType",
348 trace_stats_instance_init (GTypeInstance
*instance
, gpointer g_class
)
354 trace_stats_finalize (LttvTraceStats
*self
)
356 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACE_STATE_TYPE
))->
357 finalize(G_OBJECT(self
));
362 trace_stats_class_init (LttvTraceContextClass
*klass
)
364 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
366 gobject_class
->finalize
= (void (*)(GObject
*self
)) trace_stats_finalize
;
371 lttv_trace_stats_get_type(void)
373 static GType type
= 0;
375 static const GTypeInfo info
= {
376 sizeof (LttvTraceStatsClass
),
377 NULL
, /* base_init */
378 NULL
, /* base_finalize */
379 (GClassInitFunc
) trace_stats_class_init
, /* class_init */
380 NULL
, /* class_finalize */
381 NULL
, /* class_data */
382 sizeof (LttvTraceStats
),
384 (GInstanceInitFunc
) trace_stats_instance_init
, /* instance_init */
385 NULL
/* Value handling */
388 type
= g_type_register_static (LTTV_TRACE_STATE_TYPE
,
389 "LttvTraceStatsType", &info
, 0);
396 tracefile_stats_instance_init (GTypeInstance
*instance
, gpointer g_class
)
402 tracefile_stats_finalize (LttvTracefileStats
*self
)
404 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACEFILE_STATE_TYPE
))->
405 finalize(G_OBJECT(self
));
410 tracefile_stats_class_init (LttvTracefileStatsClass
*klass
)
412 GObjectClass
*gobject_class
= G_OBJECT_CLASS(klass
);
414 gobject_class
->finalize
= (void (*)(GObject
*self
)) tracefile_stats_finalize
;
419 lttv_tracefile_stats_get_type(void)
421 static GType type
= 0;
423 static const GTypeInfo info
= {
424 sizeof (LttvTracefileStatsClass
),
425 NULL
, /* base_init */
426 NULL
, /* base_finalize */
427 (GClassInitFunc
) tracefile_stats_class_init
, /* class_init */
428 NULL
, /* class_finalize */
429 NULL
, /* class_data */
430 sizeof (LttvTracefileStats
),
432 (GInstanceInitFunc
) tracefile_stats_instance_init
, /* instance_init */
433 NULL
/* Value handling */
436 type
= g_type_register_static (LTTV_TRACEFILE_STATE_TYPE
,
437 "LttvTracefileStatsType", &info
, 0);
444 find_event_tree(LttvTracefileStats
*tfcs
,
450 LttvAttribute
**events_tree
,
451 LttvAttribute
**event_types_tree
)
454 gchar fstring
[MAX_64_HEX_STRING_LEN
];
457 ret
= snprintf(fstring
, MAX_64_HEX_STRING_LEN
-1,
458 "0x%llX", function
) > 0;
460 fstring
[MAX_64_HEX_STRING_LEN
-1] = '\0';
462 LttvTraceStats
*tcs
= (LttvTraceStats
*)tfcs
->parent
.parent
.t_context
;
463 a
= lttv_attribute_find_subdir(tcs
->stats
, LTTV_STATS_PROCESSES
);
464 a
= lttv_attribute_find_subdir(a
, pid_time
);
465 a
= lttv_attribute_find_subdir(a
, LTTV_STATS_CPU
);
466 a
= lttv_attribute_find_subdir_unnamed(a
, cpu
);
467 a
= lttv_attribute_find_subdir(a
, LTTV_STATS_FUNCTIONS
);
468 a
= lttv_attribute_find_subdir(a
, g_quark_from_string(fstring
));
469 a
= lttv_attribute_find_subdir(a
, LTTV_STATS_MODE_TYPES
);
470 a
= lttv_attribute_find_subdir(a
, mode
);
471 a
= lttv_attribute_find_subdir(a
, LTTV_STATS_SUBMODES
);
472 a
= lttv_attribute_find_subdir(a
, sub_mode
);
474 a
= lttv_attribute_find_subdir(a
, LTTV_STATS_EVENT_TYPES
);
475 *event_types_tree
= a
;
479 static void update_event_tree(LttvTracefileStats
*tfcs
)
481 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
482 guint cpu
= tfcs
->parent
.cpu
;
483 LttvProcessState
*process
= ts
->running_process
[cpu
];
484 LttvExecutionState
*es
= process
->state
;
486 find_event_tree(tfcs
, process
->pid_time
,
488 process
->current_function
,
489 es
->t
, es
->n
, &(tfcs
->current_events_tree
),
490 &(tfcs
->current_event_types_tree
));
494 static void mode_change(LttvTracefileStats
*tfcs
)
496 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
497 guint cpu
= tfcs
->parent
.cpu
;
498 LttvProcessState
*process
= ts
->running_process
[cpu
];
499 LttvAttributeValue cpu_time
;
502 delta
= ltt_time_sub(tfcs
->parent
.parent
.timestamp
,
503 process
->state
->change
);
505 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_STATS_CPU_TIME
, LTTV_TIME
, &cpu_time
);
506 *(cpu_time
.v_time
) = ltt_time_add(*(cpu_time
.v_time
), delta
);
508 process
->state
->cum_cpu_time
= ltt_time_add(process
->state
->cum_cpu_time
,
512 /* Note : every mode_end must come with a cumulative cpu time update in the
514 static void mode_end(LttvTracefileStats
*tfcs
)
516 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
517 guint cpu
= tfcs
->parent
.cpu
;
518 LttvProcessState
*process
= ts
->running_process
[cpu
];
519 LttvAttributeValue elapsed_time
, cpu_time
, cum_cpu_time
;
523 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_STATS_ELAPSED_TIME
,
524 LTTV_TIME
, &elapsed_time
);
525 delta
= ltt_time_sub(tfcs
->parent
.parent
.timestamp
,
526 process
->state
->entry
);
527 *(elapsed_time
.v_time
) = ltt_time_add(*(elapsed_time
.v_time
), delta
);
529 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_STATS_CPU_TIME
,
530 LTTV_TIME
, &cpu_time
);
531 delta
= ltt_time_sub(tfcs
->parent
.parent
.timestamp
,
532 process
->state
->change
);
533 *(cpu_time
.v_time
) = ltt_time_add(*(cpu_time
.v_time
), delta
);
534 process
->state
->cum_cpu_time
= ltt_time_add(process
->state
->cum_cpu_time
,
537 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_STATS_CUMULATIVE_CPU_TIME
,
538 LTTV_TIME
, &cum_cpu_time
);
539 *(cum_cpu_time
.v_time
) = ltt_time_add(*(cum_cpu_time
.v_time
),
540 process
->state
->cum_cpu_time
);
544 static void after_mode_end(LttvTracefileStats
*tfcs
)
546 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
547 guint cpu
= tfcs
->parent
.cpu
;
548 LttvProcessState
*process
= ts
->running_process
[cpu
];
550 LttTime nested_delta
;
552 nested_delta
= process
->state
->cum_cpu_time
;
553 process
->state
->cum_cpu_time
= ltt_time_zero
; /* For after traceset hook */
555 update_event_tree(tfcs
);
557 process
->state
->cum_cpu_time
= ltt_time_add(process
->state
->cum_cpu_time
,
561 static gboolean
before_syscall_entry(void *hook_data
, void *call_data
)
563 mode_change((LttvTracefileStats
*)call_data
);
568 static gboolean
after_syscall_entry(void *hook_data
, void *call_data
)
570 update_event_tree((LttvTracefileStats
*)call_data
);
575 gboolean
before_syscall_exit(void *hook_data
, void *call_data
)
577 mode_end((LttvTracefileStats
*)call_data
);
582 static gboolean
after_syscall_exit(void *hook_data
, void *call_data
)
584 after_mode_end((LttvTracefileStats
*)call_data
);
589 gboolean
before_trap_entry(void *hook_data
, void *call_data
)
591 mode_change((LttvTracefileStats
*)call_data
);
596 static gboolean
after_trap_entry(void *hook_data
, void *call_data
)
598 update_event_tree((LttvTracefileStats
*)call_data
);
603 gboolean
before_trap_exit(void *hook_data
, void *call_data
)
605 mode_end((LttvTracefileStats
*)call_data
);
610 gboolean
after_trap_exit(void *hook_data
, void *call_data
)
612 after_mode_end((LttvTracefileStats
*)call_data
);
617 gboolean
before_irq_entry(void *hook_data
, void *call_data
)
619 mode_change((LttvTracefileStats
*)call_data
);
623 gboolean
after_irq_entry(void *hook_data
, void *call_data
)
625 update_event_tree((LttvTracefileStats
*)call_data
);
630 gboolean
before_irq_exit(void *hook_data
, void *call_data
)
632 mode_end((LttvTracefileStats
*)call_data
);
637 gboolean
after_irq_exit(void *hook_data
, void *call_data
)
639 after_mode_end((LttvTracefileStats
*)call_data
);
644 gboolean
before_soft_irq_entry(void *hook_data
, void *call_data
)
646 mode_change((LttvTracefileStats
*)call_data
);
650 gboolean
after_soft_irq_entry(void *hook_data
, void *call_data
)
652 update_event_tree((LttvTracefileStats
*)call_data
);
657 gboolean
before_soft_irq_exit(void *hook_data
, void *call_data
)
659 mode_end((LttvTracefileStats
*)call_data
);
664 gboolean
after_soft_irq_exit(void *hook_data
, void *call_data
)
666 after_mode_end((LttvTracefileStats
*)call_data
);
670 gboolean
before_function_entry(void *hook_data
, void *call_data
)
672 mode_change((LttvTracefileStats
*)call_data
);
676 gboolean
after_function_entry(void *hook_data
, void *call_data
)
678 update_event_tree((LttvTracefileStats
*)call_data
);
682 gboolean
before_function_exit(void *hook_data
, void *call_data
)
684 mode_end((LttvTracefileStats
*)call_data
);
688 gboolean
after_function_exit(void *hook_data
, void *call_data
)
690 after_mode_end((LttvTracefileStats
*)call_data
);
695 gboolean
before_schedchange(void *hook_data
, void *call_data
)
697 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
699 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
701 LttvTraceHookByFacility
*thf
= (LttvTraceHookByFacility
*)hook_data
;
703 guint pid_in
, pid_out
;
707 pid_out
= ltt_event_get_unsigned(e
, thf
->f1
);
708 pid_in
= ltt_event_get_unsigned(e
, thf
->f2
);
709 state_out
= ltt_event_get_int(e
, thf
->f3
);
711 /* compute the time for the process to schedule out */
718 gboolean
after_schedchange(void *hook_data
, void *call_data
)
720 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
722 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
724 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
726 LttvTraceHookByFacility
*thf
= (LttvTraceHookByFacility
*)hook_data
;
728 guint pid_in
, pid_out
;
732 LttvProcessState
*process
;
734 pid_out
= ltt_event_get_unsigned(e
, thf
->f1
);
735 pid_in
= ltt_event_get_unsigned(e
, thf
->f2
);
736 state_out
= ltt_event_get_int(e
, thf
->f3
);
738 /* get the information for the process scheduled in */
739 guint cpu
= tfcs
->parent
.cpu
;
740 process
= ts
->running_process
[cpu
];
742 find_event_tree(tfcs
, process
->pid_time
,
744 process
->current_function
,
745 process
->state
->t
, process
->state
->n
, &(tfcs
->current_events_tree
),
746 &(tfcs
->current_event_types_tree
));
748 /* compute the time waiting for the process to schedule in */
754 gboolean
process_fork(void *hook_data
, void *call_data
)
756 /* nothing to do for now */
761 gboolean
process_exit(void *hook_data
, void *call_data
)
763 /* We should probably exit all modes here or we could do that at
768 gboolean
before_enum_process_state(void *hook_data
, void *call_data
)
770 mode_end((LttvTracefileStats
*)call_data
);
771 after_mode_end((LttvTracefileStats
*)call_data
);
772 mode_change((LttvTracefileStats
*)call_data
);
776 gboolean
after_enum_process_state(void *hook_data
, void *call_data
)
778 update_event_tree((LttvTracefileStats
*)call_data
);
782 gboolean
process_free(void *hook_data
, void *call_data
)
787 gboolean
every_event(void *hook_data
, void *call_data
)
789 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
791 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
793 LttvAttributeValue v
;
795 /* The current branch corresponds to the tracefile/process/interrupt state.
796 Statistics are added within it, to count the number of events of this
797 type occuring in this context. A quark has been pre-allocated for each
798 event type and is used as name. */
800 lttv_attribute_find(tfcs
->current_event_types_tree
,
801 ltt_eventtype_name(ltt_event_eventtype(e
)),
807 static void lttv_stats_cleanup_process_state(gpointer key
, gpointer value
,
810 LttvTraceState
*ts
= (LttvTraceState
*)user_data
;
811 LttvProcessState
*process
= (LttvProcessState
*)value
;
812 LttvTracefileStats
**tfs
= (LttvTracefileStats
**)
813 &g_array_index(ts
->parent
.tracefiles
, LttvTracefileContext
*,
815 int cleanup_empty
= 0;
816 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
;
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
));
831 nested_delta
= process
->state
->cum_cpu_time
;
833 cleanup_empty
= lttv_state_pop_state_cleanup(process
,
834 (LttvTracefileState
*)*tfs
);
835 process
->state
->cum_cpu_time
= ltt_time_add(process
->state
->cum_cpu_time
,
838 } while(cleanup_empty
!= 1);
840 (*tfs
)->parent
.parent
.timestamp
= save_time
;
843 /* For each process in the state, for each of their stacked states,
844 * perform sum of needed values. */
845 static void lttv_stats_cleanup_state(LttvTraceStats
*tcs
)
847 LttvTraceState
*ts
= (LttvTraceState
*)tcs
;
849 /* Does not work correctly FIXME. */
850 g_hash_table_foreach(ts
->processes
, lttv_stats_cleanup_process_state
,
855 lttv_stats_sum_trace(LttvTraceStats
*self
, LttvAttribute
*ts_stats
)
857 LttvAttribute
*sum_container
= self
->stats
;
859 LttvAttributeType type
;
861 LttvAttributeValue value
;
863 LttvAttributeName name
;
871 int i
, j
, k
, l
, m
, nb_process
, nb_cpu
, nb_mode_type
, nb_submode
,
872 nb_event_type
, nf
, nb_functions
;
874 LttvAttribute
*main_tree
, *processes_tree
, *process_tree
, *cpus_tree
,
875 *cpu_tree
, *mode_tree
, *mode_types_tree
, *submodes_tree
,
876 *submode_tree
, *event_types_tree
, *mode_events_tree
,
879 *function_mode_types_tree
,
883 main_tree
= sum_container
;
885 lttv_attribute_find(sum_container
,
888 trace_is_summed
= *(value
.v_uint
);
891 /* First cleanup the state : sum all stalled information (never ending
894 lttv_stats_cleanup_state(self
);
896 processes_tree
= lttv_attribute_find_subdir(main_tree
,
897 LTTV_STATS_PROCESSES
);
898 nb_process
= lttv_attribute_get_number(processes_tree
);
900 for(i
= 0 ; i
< nb_process
; i
++) {
901 type
= lttv_attribute_get(processes_tree
, i
, &name
, &value
, &is_named
);
902 process_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
904 cpus_tree
= lttv_attribute_find_subdir(process_tree
, LTTV_STATS_CPU
);
905 nb_cpu
= lttv_attribute_get_number(cpus_tree
);
907 for(j
= 0 ; j
< nb_cpu
; j
++) {
908 type
= lttv_attribute_get(cpus_tree
, j
, &name
, &value
, &is_named
);
909 cpu_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
911 trace_cpu_tree
= lttv_attribute_find_subdir(main_tree
, LTTV_STATS_CPU
);
912 trace_cpu_tree
= lttv_attribute_find_subdir_unnamed(trace_cpu_tree
, name
);
913 cpu_functions_tree
= lttv_attribute_find_subdir(cpu_tree
,
914 LTTV_STATS_FUNCTIONS
);
915 nb_functions
= lttv_attribute_get_number(cpu_functions_tree
);
917 for(nf
=0; nf
< nb_functions
; nf
++) {
918 type
= lttv_attribute_get(cpu_functions_tree
, nf
, &name
, &value
,
920 function_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
921 function_mode_types_tree
= lttv_attribute_find_subdir(function_tree
,
922 LTTV_STATS_MODE_TYPES
);
923 nb_mode_type
= lttv_attribute_get_number(function_mode_types_tree
);
924 for(k
= 0 ; k
< nb_mode_type
; k
++) {
925 type
= lttv_attribute_get(function_mode_types_tree
, k
, &name
, &value
,
927 mode_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
929 submodes_tree
= lttv_attribute_find_subdir(mode_tree
,
930 LTTV_STATS_SUBMODES
);
931 mode_events_tree
= lttv_attribute_find_subdir(mode_tree
,
933 mode_types_tree
= lttv_attribute_find_subdir(mode_tree
,
934 LTTV_STATS_MODE_TYPES
);
936 nb_submode
= lttv_attribute_get_number(submodes_tree
);
938 for(l
= 0 ; l
< nb_submode
; l
++) {
939 type
= lttv_attribute_get(submodes_tree
, l
, &name
, &value
,
941 submode_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
943 event_types_tree
= lttv_attribute_find_subdir(submode_tree
,
944 LTTV_STATS_EVENT_TYPES
);
945 nb_event_type
= lttv_attribute_get_number(event_types_tree
);
948 for(m
= 0 ; m
< nb_event_type
; m
++) {
949 type
= lttv_attribute_get(event_types_tree
, m
, &name
, &value
,
951 sum
+= *(value
.v_uint
);
953 lttv_attribute_find(submode_tree
, LTTV_STATS_EVENTS_COUNT
,
955 *(value
.v_uint
) = sum
;
957 type
= lttv_attribute_get(submodes_tree
, l
, &name
, &value
,
959 submode_tree
= LTTV_ATTRIBUTE(*(value
.v_gobject
));
960 if(!trace_is_summed
) {
961 lttv_attribute_recursive_add(mode_events_tree
, event_types_tree
);
962 lttv_attribute_recursive_add(mode_types_tree
, submode_tree
);
965 if(!trace_is_summed
) {
966 lttv_attribute_recursive_add(function_tree
, mode_types_tree
);
969 if(!trace_is_summed
) {
970 lttv_attribute_recursive_add(cpu_tree
, function_tree
);
971 lttv_attribute_recursive_add(process_tree
, function_tree
);
972 lttv_attribute_recursive_add(trace_cpu_tree
, function_tree
);
973 lttv_attribute_recursive_add(main_tree
, function_tree
);
975 lttv_attribute_recursive_add(ts_stats
, function_tree
);
982 gboolean
lttv_stats_sum_traceset_hook(void *hook_data
, void *call_data
)
984 lttv_stats_sum_traceset((LttvTracesetStats
*)call_data
);
989 lttv_stats_sum_traceset(LttvTracesetStats
*self
)
991 LttvTraceset
*traceset
= self
->parent
.parent
.ts
;
992 LttvAttribute
*sum_container
= self
->stats
;
998 LttvAttributeValue value
;
1000 lttv_attribute_find(sum_container
, LTTV_STATS_SUMMED
,
1002 if(*(value
.v_uint
) != 0) return;
1003 *(value
.v_uint
) = 1;
1005 nb_trace
= lttv_traceset_number(traceset
);
1007 for(i
= 0 ; i
< nb_trace
; i
++) {
1008 tcs
= (LttvTraceStats
*)(self
->parent
.parent
.traces
[i
]);
1009 lttv_stats_sum_trace(tcs
, self
->stats
);
1010 // lttv_attribute_recursive_add(sum_container, tcs->stats);
1015 // Hook wrapper. call_data is a traceset context.
1016 gboolean
lttv_stats_hook_add_event_hooks(void *hook_data
, void *call_data
)
1018 LttvTracesetStats
*tss
= (LttvTracesetStats
*)call_data
;
1020 lttv_stats_add_event_hooks(tss
);
1025 void lttv_stats_add_event_hooks(LttvTracesetStats
*self
)
1027 LttvTraceset
*traceset
= self
->parent
.parent
.ts
;
1029 guint i
, j
, k
, l
, nb_trace
, nb_tracefile
;
1033 LttvTracefileStats
*tfs
;
1035 GArray
*hooks
, *before_hooks
, *after_hooks
;
1037 LttvTraceHook
*hook
;
1039 LttvTraceHookByFacility
*thf
;
1041 LttvAttributeValue val
;
1046 nb_trace
= lttv_traceset_number(traceset
);
1047 for(i
= 0 ; i
< nb_trace
; i
++) {
1048 ts
= (LttvTraceStats
*)self
->parent
.parent
.traces
[i
];
1050 /* Find the eventtype id for the following events and register the
1051 associated by id hooks. */
1053 hooks
= g_array_sized_new(FALSE
, FALSE
, sizeof(LttvTraceHook
), 16);
1054 g_array_set_size(hooks
, 16);
1057 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1058 LTT_FACILITY_KERNEL_ARCH
, LTT_EVENT_SYSCALL_ENTRY
,
1059 LTT_FIELD_SYSCALL_ID
, 0, 0,
1060 before_syscall_entry
, NULL
,
1061 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1064 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1065 LTT_FACILITY_KERNEL_ARCH
, LTT_EVENT_SYSCALL_EXIT
,
1067 before_syscall_exit
, NULL
,
1068 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1071 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1072 LTT_FACILITY_KERNEL
, LTT_EVENT_TRAP_ENTRY
,
1073 LTT_FIELD_TRAP_ID
, 0, 0,
1074 before_trap_entry
, NULL
,
1075 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1078 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1079 LTT_FACILITY_KERNEL
, LTT_EVENT_TRAP_EXIT
,
1081 before_trap_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_IRQ_ENTRY
,
1087 LTT_FIELD_IRQ_ID
, 0, 0,
1088 before_irq_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_IRQ_EXIT
,
1095 before_irq_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_SOFT_IRQ_ENTRY
,
1101 LTT_FIELD_SOFT_IRQ_ID
, 0, 0,
1102 before_soft_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_SOFT_IRQ_EXIT
,
1109 before_soft_irq_exit
, NULL
,
1110 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1113 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1114 LTT_FACILITY_PROCESS
, LTT_EVENT_SCHEDCHANGE
,
1115 LTT_FIELD_OUT
, LTT_FIELD_IN
, LTT_FIELD_OUT_STATE
,
1116 before_schedchange
, NULL
,
1117 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1120 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1121 LTT_FACILITY_USER_GENERIC
, LTT_EVENT_FUNCTION_ENTRY
,
1122 LTT_FIELD_THIS_FN
, LTT_FIELD_CALL_SITE
, 0,
1123 before_function_entry
, NULL
,
1124 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1127 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1128 LTT_FACILITY_USER_GENERIC
, LTT_EVENT_FUNCTION_EXIT
,
1129 LTT_FIELD_THIS_FN
, LTT_FIELD_CALL_SITE
, 0,
1130 before_function_exit
, NULL
,
1131 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1134 /* statedump-related hooks */
1135 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1136 LTT_FACILITY_STATEDUMP
, LTT_EVENT_ENUM_PROCESS_STATE
,
1137 LTT_FIELD_PID
, LTT_FIELD_PARENT_PID
, LTT_FIELD_NAME
,
1138 before_enum_process_state
, NULL
,
1139 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1142 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1143 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_THREAD_START
,
1145 xenoltt_before_change_state
, NULL
,
1146 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1149 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1150 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_THREAD_RESUME
,
1152 xenoltt_before_change_state
, NULL
,
1153 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1156 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1157 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_THREAD_WAIT_PERIOD
,
1159 xenoltt_before_change_state
, NULL
,
1160 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1163 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1164 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_THREAD_SUSPEND
,
1166 xenoltt_before_change_state
, NULL
,
1167 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1170 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1171 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_THREAD_SWITCH
,
1173 xenoltt_before_change_state
, NULL
,
1174 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1177 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1178 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_SYNCH_UNLOCK
,
1179 LTT_FIELD_XENOLTT_SYNCH
, 0, 0,
1180 xenoltt_synch_unblock
, NULL
,
1181 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1184 g_array_set_size(hooks
, hn
);
1186 before_hooks
= hooks
;
1188 hooks
= g_array_sized_new(FALSE
, FALSE
, sizeof(LttvTraceHook
), 24);
1189 g_array_set_size(hooks
, 24);
1192 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1193 LTT_FACILITY_KERNEL_ARCH
, LTT_EVENT_SYSCALL_ENTRY
,
1194 LTT_FIELD_SYSCALL_ID
, 0, 0,
1195 after_syscall_entry
, NULL
,
1196 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1199 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1200 LTT_FACILITY_KERNEL_ARCH
, LTT_EVENT_SYSCALL_EXIT
,
1202 after_syscall_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_TRAP_ENTRY
,
1208 LTT_FIELD_TRAP_ID
, 0, 0,
1209 after_trap_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_TRAP_EXIT
,
1216 after_trap_exit
, NULL
,
1217 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1220 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1221 LTT_FACILITY_KERNEL
, LTT_EVENT_IRQ_ENTRY
,
1222 LTT_FIELD_IRQ_ID
, 0, 0,
1223 after_irq_entry
, NULL
,
1224 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1227 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1228 LTT_FACILITY_KERNEL
, LTT_EVENT_IRQ_EXIT
,
1230 after_irq_exit
, NULL
,
1231 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1234 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1235 LTT_FACILITY_KERNEL
, LTT_EVENT_SOFT_IRQ_ENTRY
,
1236 LTT_FIELD_SOFT_IRQ_ID
, 0, 0,
1237 after_irq_entry
, NULL
,
1238 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1241 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1242 LTT_FACILITY_KERNEL
, LTT_EVENT_SOFT_IRQ_EXIT
,
1244 after_soft_irq_exit
, NULL
,
1245 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1248 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1249 LTT_FACILITY_PROCESS
, LTT_EVENT_SCHEDCHANGE
,
1250 LTT_FIELD_OUT
, LTT_FIELD_IN
, LTT_FIELD_OUT_STATE
,
1251 after_schedchange
, NULL
,
1252 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1255 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1256 LTT_FACILITY_PROCESS
, LTT_EVENT_FORK
,
1257 LTT_FIELD_PARENT_PID
, LTT_FIELD_CHILD_PID
, 0,
1259 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1262 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1263 LTT_FACILITY_PROCESS
, LTT_EVENT_EXIT
,
1264 LTT_FIELD_PID
, 0, 0,
1266 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1269 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1270 LTT_FACILITY_PROCESS
, LTT_EVENT_FREE
,
1271 LTT_FIELD_PID
, 0, 0,
1273 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1276 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1277 LTT_FACILITY_USER_GENERIC
, LTT_EVENT_FUNCTION_ENTRY
,
1278 LTT_FIELD_THIS_FN
, LTT_FIELD_CALL_SITE
, 0,
1279 after_function_entry
, NULL
,
1280 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1283 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1284 LTT_FACILITY_USER_GENERIC
, LTT_EVENT_FUNCTION_EXIT
,
1285 LTT_FIELD_THIS_FN
, LTT_FIELD_CALL_SITE
, 0,
1286 after_function_exit
, NULL
,
1287 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1290 /* statedump-related hooks */
1291 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1292 LTT_FACILITY_STATEDUMP
, LTT_EVENT_ENUM_PROCESS_STATE
,
1293 LTT_FIELD_PID
, LTT_FIELD_PARENT_PID
, LTT_FIELD_NAME
,
1294 after_enum_process_state
, NULL
,
1295 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1299 /* xenoltt-related hooks */
1300 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1301 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_THREAD_INIT
,
1302 LTT_FIELD_XENOLTT_NAME
, 0, 0,
1303 xenoltt_thread_init
, NULL
,
1304 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1307 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1308 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_THREAD_SET_PERIOD
,
1310 xenoltt_thread_set_period
, NULL
,
1311 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1314 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1315 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_THREAD_RENICE
,
1317 xenoltt_thread_renice
, NULL
,
1318 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1321 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1322 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_THREAD_MISSED_PERIOD
,
1323 LTT_FIELD_XENOLTT_NAME
, LTT_FIELD_XENOLTT_ADDRESS
, LTT_FIELD_XENOLTT_OVERRUNS
,
1324 xenoltt_thread_overruns
, NULL
,
1325 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1328 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1329 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_SYNCH_SET_OWNER
,
1330 LTT_FIELD_XENOLTT_SYNCH
, 0, 0,
1331 xenoltt_synch_owner
, NULL
,
1332 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1335 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1336 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_SYNCH_WAKEUPX
,
1337 LTT_FIELD_XENOLTT_SYNCH
, LTT_FIELD_XENOLTT_NAME
, LTT_FIELD_XENOLTT_ADDRESS
,
1338 xenoltt_synch_wakeup
, NULL
,
1339 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1342 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1343 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_SYNCH_WAKEUP1
,
1344 LTT_FIELD_XENOLTT_SYNCH
, LTT_FIELD_XENOLTT_NAME
, LTT_FIELD_XENOLTT_ADDRESS
,
1345 xenoltt_synch_wakeup
, NULL
,
1346 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1349 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1350 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_SYNCH_SLEEP_ON
,
1351 LTT_FIELD_XENOLTT_SYNCH
, LTT_FIELD_XENOLTT_NAME
, LTT_FIELD_XENOLTT_ADDRESS
,
1352 xenoltt_synch_wait
, NULL
,
1353 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1357 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1358 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_SYNCH_FLUSH
,
1359 LTT_FIELD_XENOLTT_SYNCH
, 0, 0,
1360 xenoltt_synch_flush
, NULL
, &g_array_index(hooks
, LttvTraceHook
, hn
++));
1364 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1365 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_SYNCH_FORGET
,
1366 LTT_FIELD_XENOLTT_SYNCH
, LTT_FIELD_XENOLTT_NAME
, LTT_FIELD_XENOLTT_ADDRESS
,
1367 xenoltt_synch_wakeup
, NULL
, &g_array_index(hooks
, LttvTraceHook
, hn
++));
1370 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1371 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_THREAD_START
,
1373 xenoltt_after_change_state
, NULL
,
1374 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1377 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1378 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_THREAD_RESUME
,
1380 xenoltt_after_change_state
, NULL
,
1381 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1384 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1385 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_THREAD_WAIT_PERIOD
,
1387 xenoltt_after_change_state
, NULL
,
1388 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1391 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1392 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_THREAD_SUSPEND
,
1394 xenoltt_after_change_state
, NULL
,
1395 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1398 ret
= lttv_trace_find_hook(ts
->parent
.parent
.t
,
1399 LTT_FACILITY_XENOLTT
, LTT_EVENT_XENOLTT_THREAD_SWITCH
,
1401 xenoltt_after_change_state
, NULL
,
1402 &g_array_index(hooks
, LttvTraceHook
, hn
++));
1405 g_array_set_size(hooks
, hn
);
1407 after_hooks
= hooks
;
1409 /* Add these hooks to each event_by_id hooks list */
1411 nb_tracefile
= ts
->parent
.parent
.tracefiles
->len
;
1413 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1414 tfs
= LTTV_TRACEFILE_STATS(g_array_index(ts
->parent
.parent
.tracefiles
,
1415 LttvTracefileContext
*, j
));
1416 lttv_hooks_add(tfs
->parent
.parent
.event
, every_event
, NULL
,
1419 for(k
= 0 ; k
< before_hooks
->len
; k
++) {
1420 hook
= &g_array_index(before_hooks
, LttvTraceHook
, k
);
1421 for(l
= 0; l
<hook
->fac_list
->len
;l
++) {
1422 thf
= g_array_index(hook
->fac_list
, LttvTraceHookByFacility
*, l
);
1424 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, thf
->id
),
1427 LTTV_PRIO_STATS_BEFORE_STATE
);
1430 for(k
= 0 ; k
< after_hooks
->len
; k
++) {
1431 hook
= &g_array_index(after_hooks
, LttvTraceHook
, k
);
1432 for(l
= 0; l
<hook
->fac_list
->len
;l
++) {
1433 thf
= g_array_index(hook
->fac_list
, LttvTraceHookByFacility
*, l
);
1435 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, thf
->id
),
1438 LTTV_PRIO_STATS_AFTER_STATE
);
1442 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_BEFORE_HOOKS
,
1443 LTTV_POINTER
, &val
);
1444 *(val
.v_pointer
) = before_hooks
;
1445 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_AFTER_HOOKS
,
1446 LTTV_POINTER
, &val
);
1447 *(val
.v_pointer
) = after_hooks
;
1451 // Hook wrapper. call_data is a traceset context.
1452 gboolean
lttv_stats_hook_remove_event_hooks(void *hook_data
, void *call_data
)
1454 LttvTracesetStats
*tss
= (LttvTracesetStats
*)call_data
;
1456 lttv_stats_remove_event_hooks(tss
);
1461 void lttv_stats_remove_event_hooks(LttvTracesetStats
*self
)
1463 LttvTraceset
*traceset
= self
->parent
.parent
.ts
;
1465 guint i
, j
, k
, l
, nb_trace
, nb_tracefile
;
1469 LttvTracefileStats
*tfs
;
1471 GArray
*before_hooks
, *after_hooks
;
1473 LttvTraceHook
*hook
;
1475 LttvTraceHookByFacility
*thf
;
1477 LttvAttributeValue val
;
1479 nb_trace
= lttv_traceset_number(traceset
);
1480 for(i
= 0 ; i
< nb_trace
; i
++) {
1481 ts
= (LttvTraceStats
*)self
->parent
.parent
.traces
[i
];
1482 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_BEFORE_HOOKS
,
1483 LTTV_POINTER
, &val
);
1484 before_hooks
= *(val
.v_pointer
);
1485 lttv_attribute_find(self
->parent
.parent
.a
, LTTV_STATS_AFTER_HOOKS
,
1486 LTTV_POINTER
, &val
);
1487 after_hooks
= *(val
.v_pointer
);
1489 /* Remove these hooks from each event_by_id hooks list */
1491 nb_tracefile
= ts
->parent
.parent
.tracefiles
->len
;
1493 for(j
= 0 ; j
< nb_tracefile
; j
++) {
1494 tfs
= LTTV_TRACEFILE_STATS(g_array_index(ts
->parent
.parent
.tracefiles
,
1495 LttvTracefileContext
*, j
));
1496 lttv_hooks_remove_data(tfs
->parent
.parent
.event
, every_event
,
1499 for(k
= 0 ; k
< before_hooks
->len
; k
++) {
1500 hook
= &g_array_index(before_hooks
, LttvTraceHook
, k
);
1501 for(l
= 0 ; l
< hook
->fac_list
->len
; l
++) {
1502 thf
= g_array_index(hook
->fac_list
, LttvTraceHookByFacility
*, l
);
1503 lttv_hooks_remove_data(
1504 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, thf
->id
),
1509 for(k
= 0 ; k
< after_hooks
->len
; k
++) {
1510 hook
= &g_array_index(after_hooks
, LttvTraceHook
, k
);
1511 for(l
= 0 ; l
< hook
->fac_list
->len
; l
++) {
1512 thf
= g_array_index(hook
->fac_list
, LttvTraceHookByFacility
*, l
);
1513 lttv_hooks_remove_data(
1514 lttv_hooks_by_id_find(tfs
->parent
.parent
.event_by_id
, thf
->id
),
1520 g_debug("lttv_stats_remove_event_hooks()");
1521 g_array_free(before_hooks
, TRUE
);
1522 g_array_free(after_hooks
, TRUE
);
1528 /****************************************************************************************************************************/
1530 void lttv_xeno_stats_sum_trace(LttvTraceStats
*self
, LttvAttribute
*ts_stats
){
1531 LttvAttribute
*sum_container
= self
->xenoltt_stats
;
1532 LttvAttributeValue value
;
1533 int trace_is_summed
;
1536 LttvAttribute
*main_tree
, *threads_tree
;
1538 main_tree
= sum_container
;
1540 lttv_attribute_find(sum_container
,LTTV_STATS_SUMMED
, LTTV_UINT
, &value
);
1541 trace_is_summed
= *(value
.v_uint
);
1542 *(value
.v_uint
) = 1;
1544 /* First cleanup the state : sum all stalled information (never ending
1546 if(!trace_is_summed
) lttv_stats_cleanup_state(self
);
1548 // First level of Xenomai Tasks Statistics Tree
1549 threads_tree
= lttv_attribute_find_subdir(main_tree
, LTTV_XENO_STATS
);
1550 nb_threads
= lttv_attribute_get_number(threads_tree
);
1555 void lttv_xeno_stats_sum_traceset(LttvTracesetStats
*self
){
1556 LttvTraceset
*traceset
= self
->parent
.parent
.ts
;
1557 LttvAttribute
*sum_container
= self
->xenoltt_stats
;
1559 LttvTraceStats
*tcs
;
1563 LttvAttributeValue value
;
1565 lttv_attribute_find(sum_container
, LTTV_STATS_SUMMED
,
1567 if(*(value
.v_uint
) != 0) return;
1568 *(value
.v_uint
) = 1;
1570 nb_trace
= lttv_traceset_number(traceset
);
1572 for(i
= 0 ; i
< nb_trace
; i
++) {
1573 tcs
= (LttvTraceStats
*)(self
->parent
.parent
.traces
[i
]);
1574 lttv_xeno_stats_sum_trace(tcs
, self
->xenoltt_stats
);
1579 /****************************************************************************
1580 - Task Name ( Address, Priority, Period )
1582 * Running Avg, Max, Min
1583 * Suspend Avg, Max, Min
1584 * Ready Avg, Max, Min
1586 - # ( ticks missed, time )
1588 - Status name (#, total time, avg)
1591 - Possession (#, time, avg)
1592 - Waiting (#, time, avg)
1596 - Possession (#, time, avg)
1597 - Waiting (#, time, avg)
1598 *****************************************************************************/
1600 static void xeno_find_task_tree(LttvTracefileStats
*tfcs
, GQuark name
, gulong address
, guint cpu
, LttvAttribute
**events_tree
, LttvAttribute
**event_types_tree
){
1601 LttvAttribute
*a
, *task_tree
, *xenoltt_tree
, *state_tree
, *synch_tree
;
1603 LttvAttributeValue prio
, period
;
1605 LttvTraceStats
*tcs
= (LttvTraceStats
*)tfcs
->parent
.parent
.t_context
;
1606 xenoltt_tree
= lttv_attribute_find_subdir(tcs
->xenoltt_stats
, LTTV_XENO_STATS
);
1608 task_tree
= lttv_attribute_find_subdir(xenoltt_tree
, LTTV_XENO_STATS_THREADS
);
1609 task_tree
= lttv_attribute_find_subdir(task_tree
, name
);
1610 *events_tree
= task_tree
;
1611 lttv_attribute_find_subdir(xenoltt_tree
, LTTV_XENO_STATS_SYNCH
);
1613 lttv_attribute_find(task_tree
, LTTV_XENO_STATS_THREAD_PERIOD
, LTTV_UINT
, &period
);
1614 lttv_attribute_find(task_tree
, LTTV_XENO_STATS_THREAD_PRIO
, LTTV_UINT
, &prio
);
1616 lttv_attribute_find_subdir(task_tree
, LTTV_XENO_STATS_SYNCH
);
1618 lttv_attribute_find_subdir(task_tree
, LTTV_XENO_STATS_PERIOD_OVERRUNS
);
1621 state_tree
= lttv_attribute_find_subdir(task_tree
, LTTV_XENO_STATS_STATE
);
1623 synch_tree
= lttv_attribute_find_subdir(task_tree
, LTTV_XENO_STATS_SYNCH
);
1625 a
= lttv_attribute_find_subdir(task_tree
, LTTV_STATS_EVENT_TYPES
);
1626 *event_types_tree
= a
;
1630 gboolean
xenoltt_thread_init(void *hook_data
, void *call_data
){
1631 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
1632 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
1633 LttvXenoThreadState
*thread
;
1634 LttvAttributeValue prio
;
1635 guint cpu
= tfcs
->parent
.cpu
;
1636 thread
= ts
->running_thread
[cpu
];
1638 xeno_find_task_tree(tfcs
, thread
->name
, thread
->address
,cpu
, &(tfcs
->current_events_tree
), &(tfcs
->current_event_types_tree
));
1640 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_XENO_STATS_THREAD_PRIO
, LTTV_UINT
, &prio
);
1641 *(prio
.v_uint
) = thread
->prio
;
1643 xenoltt_after_change_state(hook_data
,call_data
);
1648 gboolean
xenoltt_thread_renice(void *hook_data
, void *call_data
){
1649 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
1650 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
1651 LttvXenoThreadState
*thread
;
1652 LttvAttributeValue prio
;
1653 guint cpu
= tfcs
->parent
.cpu
;
1654 thread
= ts
->running_thread
[cpu
];
1656 xeno_find_task_tree(tfcs
, thread
->name
, thread
->address
,cpu
, &(tfcs
->current_events_tree
), &(tfcs
->current_event_types_tree
));
1658 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_XENO_STATS_THREAD_PRIO
, LTTV_UINT
, &prio
);
1659 *(prio
.v_uint
) = thread
->prio
;
1664 gboolean
xenoltt_thread_set_period(void *hook_data
, void *call_data
){
1665 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
1666 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
1667 LttvXenoThreadState
*thread
;
1668 LttvAttributeValue period
;
1669 guint cpu
= tfcs
->parent
.cpu
;
1670 thread
= ts
->running_thread
[cpu
];
1672 // Find corresponding task
1673 xeno_find_task_tree(tfcs
, thread
->name
, thread
->address
,cpu
, &(tfcs
->current_events_tree
), &(tfcs
->current_event_types_tree
));
1675 // Write the period of the task
1676 lttv_attribute_find(tfcs
->current_events_tree
, LTTV_XENO_STATS_THREAD_PERIOD
, LTTV_UINT
, &period
);
1677 *(period
.v_uint
) = thread
->period
;
1682 gboolean
xenoltt_thread_overruns(void *hook_data
, void *call_data
){
1683 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
1684 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
1685 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
1686 LttvTraceHookByFacility
*thf
= (LttvTraceHookByFacility
*)hook_data
;
1687 LttvAttributeValue overrun
;
1688 LttvAttribute
*overrun_tree
;
1689 guint cpu
= tfcs
->parent
.cpu
;
1691 g_assert(thf
->f1
!= NULL
);
1692 GQuark name
= g_quark_from_string(ltt_event_get_string(e
, thf
->f1
));
1693 g_assert(thf
->f2
!= NULL
);
1694 gulong address
= ltt_event_get_long_unsigned(e
, thf
->f2
);
1695 g_assert(thf
->f3
!= NULL
);
1696 guint overruns
= ltt_event_get_long_unsigned(e
, thf
->f3
);
1697 LttvXenoThreadState
*thread
= lttv_xeno_state_find_thread(ts
,cpu
,address
);
1698 xeno_find_task_tree(tfcs
, name
, address
,cpu
, &(tfcs
->current_events_tree
), &(tfcs
->current_event_types_tree
));
1700 overrun_tree
= lttv_attribute_find_subdir(tfcs
->current_events_tree
, LTTV_XENO_STATS_PERIOD_OVERRUNS
);
1702 gchar overrun_time
[MAX_64_HEX_STRING_LEN
];
1703 sprintf(overrun_time
,"%lu,%lu", tfcs
->parent
.parent
.timestamp
.tv_sec
,tfcs
->parent
.parent
.timestamp
.tv_nsec
);
1704 overrun_tree
= lttv_attribute_find_subdir(overrun_tree
, g_quark_from_string(overrun_time
));
1706 lttv_attribute_find(overrun_tree
, LTTV_XENO_STATS_TEXT_TICKS
, LTTV_UINT
, &overrun
);
1707 *(overrun
.v_uint
) = overruns
;
1709 LttTime delta
= ltt_time_sub(tfcs
->parent
.parent
.timestamp
, thread
->state
->overrun_start
);
1710 lttv_attribute_find(overrun_tree
, LTTV_XENO_STATS_TEXT_TOTAL
, LTTV_TIME
, &overrun
);
1711 *(overrun
.v_time
) = delta
;
1715 gboolean
xenoltt_before_change_state(void *hook_data
, void *call_data
){
1716 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
1717 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
1718 LttvXenoThreadState
*thread
;
1719 LttvAttributeValue state_count
, state_time
, state_time_average
;
1721 guint cpu
= tfcs
->parent
.cpu
;
1722 thread
= ts
->running_thread
[cpu
];
1724 xeno_find_task_tree(tfcs
, thread
->name
, thread
->address
,cpu
, &(tfcs
->current_events_tree
), &(tfcs
->current_event_types_tree
));
1726 // Create or go to State subtree
1727 a
= lttv_attribute_find_subdir(tfcs
->current_events_tree
, LTTV_XENO_STATS_STATE
);
1728 // Create or go to the current state subtree
1729 a
= lttv_attribute_find_subdir(a
, thread
->state
->status
);
1730 lttv_attribute_find(a
, g_quark_from_string("Number of times in this state"), LTTV_UINT
, &state_count
);
1732 LttTime delta
= ltt_time_sub(tfcs
->parent
.parent
.timestamp
, thread
->state
->change
);
1733 lttv_attribute_find(a
, g_quark_from_string("Cumulative time"), LTTV_TIME
, &state_time
);
1734 *(state_time
.v_time
) = ltt_time_add(*(state_time
.v_time
), delta
);
1736 lttv_attribute_find(a
, g_quark_from_string("Average elapsed time"), LTTV_TIME
, &state_time_average
);
1737 if (*(state_count
.v_uint
) == 0 || ltt_time_compare(*(state_time
.v_time
),ltt_time_zero
) == 0) *(state_time_average
.v_time
) = *(state_time
.v_time
);
1738 else *(state_time_average
.v_time
) = ltt_time_div(*(state_time
.v_time
), *(state_count
.v_uint
));
1743 gboolean
xenoltt_after_change_state(void *hook_data
, void *call_data
){
1744 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
1745 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
1746 LttvXenoThreadState
*thread
;
1747 LttvAttributeValue state_count
, state_time
, state_time_average
;
1749 guint cpu
= tfcs
->parent
.cpu
;
1750 thread
= ts
->running_thread
[cpu
];
1752 xeno_find_task_tree(tfcs
, thread
->name
, thread
->address
,cpu
, &(tfcs
->current_events_tree
), &(tfcs
->current_event_types_tree
));
1754 // Create or go to State subtree
1755 a
= lttv_attribute_find_subdir(tfcs
->current_events_tree
, LTTV_XENO_STATS_STATE
);
1756 // Create or go to the current state subtree
1757 a
= lttv_attribute_find_subdir(a
, thread
->state
->status
);
1758 lttv_attribute_find(a
, g_quark_from_string("Number of times in this state"), LTTV_UINT
, &state_count
);
1759 *(state_count
.v_uint
) = *(state_count
.v_uint
) + 1;
1761 LttTime delta
= ltt_time_sub(tfcs
->parent
.parent
.timestamp
, thread
->state
->entry
);
1762 lttv_attribute_find(a
, g_quark_from_string("Cumulative time"), LTTV_TIME
, &state_time
);
1763 *(state_time
.v_time
) = ltt_time_add(*(state_time
.v_time
), delta
);
1765 lttv_attribute_find(a
, g_quark_from_string("Average elapsed time"), LTTV_TIME
, &state_time_average
);
1766 if (*(state_count
.v_uint
) == 0 || ltt_time_compare(*(state_time
.v_time
),ltt_time_zero
) == 0) *(state_time_average
.v_time
) = *(state_time
.v_time
);
1767 else *(state_time_average
.v_time
) = ltt_time_div(*(state_time
.v_time
), *(state_count
.v_uint
));
1773 gboolean
xenoltt_synch_owner(void *hook_data
, void *call_data
){
1774 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
1775 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
1776 LttvTraceStats
*tcs
= (LttvTraceStats
*)tfcs
->parent
.parent
.t_context
;
1777 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
1778 LttvTraceHookByFacility
*thf
= (LttvTraceHookByFacility
*)hook_data
;
1779 LttvAttributeValue synch
;
1780 LttvAttribute
*synch_tree
, *global_synch_tree
;
1781 guint cpu
= tfcs
->parent
.cpu
;
1782 LttvXenoThreadState
*thread
= ts
->running_thread
[cpu
];
1784 if (thread
->state
->started
== TRUE
){
1785 g_assert(thf
->f1
!= NULL
);
1786 gulong synch_address
= ltt_event_get_long_unsigned(e
, thf
->f1
);
1788 xeno_find_task_tree(tfcs
, thread
->name
, thread
->address
,cpu
, &(tfcs
->current_events_tree
), &(tfcs
->current_event_types_tree
));
1790 synch_tree
= lttv_attribute_find_subdir(tfcs
->current_events_tree
, LTTV_XENO_STATS_SYNCH
);
1792 // Update the task ressources tree
1793 gchar synch_id
[MAX_64_HEX_STRING_LEN
];
1794 sprintf(synch_id
,"%p", (void *) synch_address
);
1795 synch_tree
= lttv_attribute_find_subdir(synch_tree
, g_quark_from_string(synch_id
));
1797 // We must update the global ressources tree also
1798 global_synch_tree
= lttv_attribute_find_subdir(tcs
->xenoltt_stats
, LTTV_XENO_STATS
);
1799 global_synch_tree
= lttv_attribute_find_subdir(global_synch_tree
, LTTV_XENO_STATS_SYNCH
);
1800 global_synch_tree
= lttv_attribute_find_subdir(global_synch_tree
, g_quark_from_string(synch_id
));
1803 lttv_attribute_find(synch_tree
, LTTV_XENO_STATS_TEXT_OWNER
, LTTV_UINT
, &synch
);
1804 *(synch
.v_uint
) += 1;
1806 // In the global tree
1807 lttv_attribute_find(global_synch_tree
, LTTV_XENO_STATS_TEXT_OWNER
, LTTV_UINT
, &synch
);
1808 *(synch
.v_uint
) += 1;
1813 // When sleep-on is called
1814 gboolean
xenoltt_synch_wait(void *hook_data
, void *call_data
){
1815 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
1816 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
1817 LttvTraceStats
*tcs
= (LttvTraceStats
*)tfcs
->parent
.parent
.t_context
;
1818 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
1819 LttvTraceHookByFacility
*thf
= (LttvTraceHookByFacility
*)hook_data
;
1820 LttvAttributeValue synch
;
1821 LttvAttribute
*synch_tree
, *global_synch_tree
;
1822 guint cpu
= tfcs
->parent
.cpu
;
1823 LttvXenoThreadState
*thread
;
1824 thread
= ts
->running_thread
[cpu
];
1826 g_assert(thf
->f1
!= NULL
);
1827 gulong synch_address
= ltt_event_get_long_unsigned(e
, thf
->f1
);
1828 g_assert(thf
->f2
!= NULL
);
1829 GQuark name
= g_quark_from_string(ltt_event_get_string(e
, thf
->f2
));
1830 g_assert(thf
->f3
!= NULL
);
1831 gulong address
= ltt_event_get_long_unsigned(e
, thf
->f3
);
1833 xeno_find_task_tree(tfcs
, name
, address
,cpu
, &(tfcs
->current_events_tree
), &(tfcs
->current_event_types_tree
));
1835 synch_tree
= lttv_attribute_find_subdir(tfcs
->current_events_tree
, LTTV_XENO_STATS_SYNCH
);
1837 gchar synch_id
[MAX_64_HEX_STRING_LEN
];
1838 sprintf(synch_id
,"%p", (void *) synch_address
);
1839 synch_tree
= lttv_attribute_find_subdir(synch_tree
, g_quark_from_string(synch_id
));
1841 // We must update the global ressources tree also
1842 global_synch_tree
= lttv_attribute_find_subdir(tcs
->xenoltt_stats
, LTTV_XENO_STATS
);
1843 global_synch_tree
= lttv_attribute_find_subdir(global_synch_tree
, LTTV_XENO_STATS_SYNCH
);
1844 global_synch_tree
= lttv_attribute_find_subdir(global_synch_tree
, g_quark_from_string(synch_id
));
1846 // We have one more waiting call to register
1848 lttv_attribute_find(synch_tree
, LTTV_XENO_STATS_TEXT_WAITING
, LTTV_UINT
, &synch
);
1849 *(synch
.v_uint
) = *(synch
.v_uint
) + 1;
1851 // In the global tree
1852 lttv_attribute_find(global_synch_tree
, LTTV_XENO_STATS_TEXT_WAITING
, LTTV_UINT
, &synch
);
1853 *(synch
.v_uint
) = *(synch
.v_uint
) + 1;
1858 gboolean
xenoltt_synch_wakeup(void *hook_data
, void *call_data
){
1859 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
1860 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
1861 LttvTraceStats
*tcs
= (LttvTraceStats
*)tfcs
->parent
.parent
.t_context
;
1862 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
1863 LttvTraceHookByFacility
*thf
= (LttvTraceHookByFacility
*)hook_data
;
1864 LttvAttributeValue synch
, total_time
, avg_time
, max_time
, min_time
;
1865 LttvAttributeValue global_synch
, global_total_time
, global_avg_time
, global_max_time
, global_min_time
;
1866 LttvAttribute
*synch_tree
, *global_synch_tree
;
1867 guint cpu
= tfcs
->parent
.cpu
;
1868 GQuark event_name
= ltt_eventtype_name(ltt_event_eventtype(e
));
1870 g_assert(thf
->f1
!= NULL
);
1871 gulong synch_address
= ltt_event_get_long_unsigned(e
, thf
->f1
);
1872 g_assert(thf
->f2
!= NULL
);
1873 GQuark name
= g_quark_from_string(ltt_event_get_string(e
, thf
->f2
));
1874 g_assert(thf
->f3
!= NULL
);
1875 gulong address
= ltt_event_get_long_unsigned(e
, thf
->f3
);
1876 LttvXenoSynchState
*synch_state
= lttv_xeno_state_find_synch(ts
,synch_address
);
1877 LttvXenoThreadState
*thread
= lttv_xeno_state_find_thread(ts
,cpu
,address
);
1878 if (synch_state
!= NULL
&& thread
!= NULL
){
1879 xeno_find_task_tree(tfcs
, name
, address
,cpu
, &(tfcs
->current_events_tree
), &(tfcs
->current_event_types_tree
));
1881 synch_tree
= lttv_attribute_find_subdir(tfcs
->current_events_tree
, LTTV_XENO_STATS_SYNCH
);
1883 gchar synch_id
[MAX_64_HEX_STRING_LEN
];
1884 sprintf(synch_id
,"%p", (void *) synch_address
);
1885 synch_tree
= lttv_attribute_find_subdir(synch_tree
, g_quark_from_string(synch_id
));
1887 // We must update the global ressources tree also
1888 global_synch_tree
= lttv_attribute_find_subdir(tcs
->xenoltt_stats
, LTTV_XENO_STATS
);
1889 global_synch_tree
= lttv_attribute_find_subdir(global_synch_tree
, LTTV_XENO_STATS_SYNCH
);
1890 global_synch_tree
= lttv_attribute_find_subdir(global_synch_tree
, g_quark_from_string(synch_id
));
1892 if (event_name
!= LTT_EVENT_XENOLTT_SYNCH_FORGET
){
1893 lttv_attribute_find(synch_tree
, LTTV_XENO_STATS_TEXT_OWNER
, LTTV_UINT
, &synch
);
1894 *(synch
.v_uint
) = *(synch
.v_uint
) + 1;
1896 lttv_attribute_find(global_synch_tree
, LTTV_XENO_STATS_TEXT_OWNER
, LTTV_UINT
, &synch
);
1897 *(synch
.v_uint
) = *(synch
.v_uint
) + 1;
1900 lttv_attribute_find(synch_tree
, LTTV_XENO_STATS_TEXT_WAITING
, LTTV_UINT
, &synch
);
1902 // Compute time spent in waiting state
1903 LttTime delta
= ltt_time_sub(tfcs
->parent
.parent
.timestamp
, thread
->start_wait_synch
);
1905 lttv_attribute_find(synch_tree
, LTTV_XENO_STATS_TEXT_WAITING_TOTAL
, LTTV_TIME
, &total_time
);
1906 *(total_time
.v_time
) = ltt_time_add(*(total_time
.v_time
), delta
);
1908 lttv_attribute_find(synch_tree
, LTTV_XENO_STATS_TEXT_WAITING_AVG
, LTTV_TIME
, &avg_time
);
1909 if (*(synch
.v_uint
) == 0 || ltt_time_compare(*(total_time
.v_time
),ltt_time_zero
) == 0) *(avg_time
.v_time
) = *(total_time
.v_time
);
1910 else *(avg_time
.v_time
) = ltt_time_div(*(total_time
.v_time
), *(synch
.v_uint
));
1912 lttv_attribute_find(synch_tree
, LTTV_XENO_STATS_TEXT_WAITING_MAX
, LTTV_TIME
, &max_time
);
1913 // If this owning time is longer than any other before
1914 if (ltt_time_compare(delta
,*(max_time
.v_time
)) == 1) *(max_time
.v_time
) = delta
;
1916 lttv_attribute_find(synch_tree
, LTTV_XENO_STATS_TEXT_WAITING_MIN
, LTTV_TIME
, &min_time
);
1917 // If this owning time is shorter than any other before
1918 if (*(synch
.v_uint
) == 1) *(min_time
.v_time
) = delta
;
1919 else if (ltt_time_compare(*(min_time
.v_time
), delta
) == 1) *(min_time
.v_time
) = delta
;
1921 /**** GLOBAL RESOURCE TREE ***********/
1922 lttv_attribute_find(global_synch_tree
, LTTV_XENO_STATS_TEXT_WAITING
, LTTV_UINT
, &global_synch
);
1924 lttv_attribute_find(global_synch_tree
, LTTV_XENO_STATS_TEXT_WAITING_TOTAL
, LTTV_TIME
, &global_total_time
);
1925 *(global_total_time
.v_time
) = ltt_time_add(*(global_total_time
.v_time
), delta
);
1927 lttv_attribute_find(global_synch_tree
, LTTV_XENO_STATS_TEXT_WAITING_AVG
, LTTV_TIME
, &global_avg_time
);
1928 if (*(global_synch
.v_uint
) == 0 || ltt_time_compare(*(global_total_time
.v_time
),ltt_time_zero
) == 0) *(global_avg_time
.v_time
) = *(global_total_time
.v_time
);
1929 else *(global_avg_time
.v_time
) = ltt_time_div(*(global_total_time
.v_time
), *(global_synch
.v_uint
));
1931 lttv_attribute_find(global_synch_tree
, LTTV_XENO_STATS_TEXT_WAITING_MAX
, LTTV_TIME
, &global_max_time
);
1932 // If this owning time is longer than any other before
1933 if (ltt_time_compare(delta
,*(global_max_time
.v_time
)) == 1) *(global_max_time
.v_time
) = delta
;
1935 lttv_attribute_find(global_synch_tree
, LTTV_XENO_STATS_TEXT_WAITING_MIN
, LTTV_TIME
, &global_min_time
);
1936 // If this owning time is shorter than any other before
1937 if (*(global_synch
.v_uint
) == 1) *(global_min_time
.v_time
) = delta
;
1938 else if (ltt_time_compare(*(global_min_time
.v_time
), delta
) == 1) *(global_min_time
.v_time
) = delta
;
1943 gboolean
xenoltt_synch_flush(void *hook_data
, void *call_data
){
1944 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
1945 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
1946 LttvTraceStats
*tcs
= (LttvTraceStats
*)tfcs
->parent
.parent
.t_context
;
1947 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
1948 LttvTraceHookByFacility
*thf
= (LttvTraceHookByFacility
*)hook_data
;
1949 LttvAttributeValue synch
, total_time
, avg_time
, max_time
, min_time
;
1950 LttvAttributeValue global_synch
, global_total_time
, global_avg_time
, global_max_time
, global_min_time
;
1951 LttvAttribute
*synch_tree
, *global_synch_tree
;
1952 guint cpu
= tfcs
->parent
.cpu
;
1953 GQuark event_name
= ltt_eventtype_name(ltt_event_eventtype(e
));
1955 g_assert(thf
->f1
!= NULL
);
1956 gulong synch_address
= ltt_event_get_long_unsigned(e
, thf
->f1
);
1958 LttvXenoSynchState
*synch_state
= lttv_xeno_state_find_synch(ts
,synch_address
);
1959 LttvXenoThreadState
*thread
;
1960 if (synch_state
!= NULL
){
1962 for(i
=0;i
<synch_state
->state
->waiting_threads
->len
;i
++){
1963 thread
= g_array_index(synch_state
->state
->waiting_threads
, LttvXenoThreadState
*, i
);
1964 if (thread
!= NULL
){
1965 xeno_find_task_tree(tfcs
, thread
->name
, thread
->address
,cpu
, &(tfcs
->current_events_tree
), &(tfcs
->current_event_types_tree
));
1967 synch_tree
= lttv_attribute_find_subdir(tfcs
->current_events_tree
, LTTV_XENO_STATS_SYNCH
);
1969 gchar synch_id
[MAX_64_HEX_STRING_LEN
];
1970 sprintf(synch_id
,"%p", (void *) synch_address
);
1971 synch_tree
= lttv_attribute_find_subdir(synch_tree
, g_quark_from_string(synch_id
));
1973 // We must update the global ressources tree also
1974 global_synch_tree
= lttv_attribute_find_subdir(tcs
->xenoltt_stats
, LTTV_XENO_STATS
);
1975 global_synch_tree
= lttv_attribute_find_subdir(global_synch_tree
, LTTV_XENO_STATS_SYNCH
);
1976 global_synch_tree
= lttv_attribute_find_subdir(global_synch_tree
, g_quark_from_string(synch_id
));
1978 if (event_name
!= LTT_EVENT_XENOLTT_SYNCH_FORGET
){
1979 lttv_attribute_find(synch_tree
, LTTV_XENO_STATS_TEXT_OWNER
, LTTV_UINT
, &synch
);
1980 *(synch
.v_uint
) = *(synch
.v_uint
) + 1;
1982 lttv_attribute_find(global_synch_tree
, LTTV_XENO_STATS_TEXT_OWNER
, LTTV_UINT
, &synch
);
1983 *(synch
.v_uint
) = *(synch
.v_uint
) + 1;
1986 lttv_attribute_find(synch_tree
, LTTV_XENO_STATS_TEXT_WAITING
, LTTV_UINT
, &synch
);
1988 // Compute time spent in waiting state
1989 LttTime delta
= ltt_time_sub(tfcs
->parent
.parent
.timestamp
, thread
->start_wait_synch
);
1991 lttv_attribute_find(synch_tree
, LTTV_XENO_STATS_TEXT_WAITING_TOTAL
, LTTV_TIME
, &total_time
);
1992 *(total_time
.v_time
) = ltt_time_add(*(total_time
.v_time
), delta
);
1994 lttv_attribute_find(synch_tree
, LTTV_XENO_STATS_TEXT_WAITING_AVG
, LTTV_TIME
, &avg_time
);
1995 if (*(synch
.v_uint
) == 0 || ltt_time_compare(*(total_time
.v_time
),ltt_time_zero
) == 0) *(avg_time
.v_time
) = *(total_time
.v_time
);
1996 else *(avg_time
.v_time
) = ltt_time_div(*(total_time
.v_time
), *(synch
.v_uint
));
1998 lttv_attribute_find(synch_tree
, LTTV_XENO_STATS_TEXT_WAITING_MAX
, LTTV_TIME
, &max_time
);
1999 // If this owning time is longer than any other before
2000 if (ltt_time_compare(delta
,*(max_time
.v_time
)) == 1) *(max_time
.v_time
) = delta
;
2002 lttv_attribute_find(synch_tree
, LTTV_XENO_STATS_TEXT_WAITING_MIN
, LTTV_TIME
, &min_time
);
2003 // If this owning time is shorter than any other before
2004 if (*(synch
.v_uint
) == 1) *(min_time
.v_time
) = delta
;
2005 else if (ltt_time_compare(*(min_time
.v_time
), delta
) == 1) *(min_time
.v_time
) = delta
;
2007 /**** GLOBAL RESOURCE TREE ***********/
2008 lttv_attribute_find(global_synch_tree
, LTTV_XENO_STATS_TEXT_WAITING
, LTTV_UINT
, &global_synch
);
2010 lttv_attribute_find(global_synch_tree
, LTTV_XENO_STATS_TEXT_WAITING_TOTAL
, LTTV_TIME
, &global_total_time
);
2011 *(global_total_time
.v_time
) = ltt_time_add(*(global_total_time
.v_time
), delta
);
2013 lttv_attribute_find(global_synch_tree
, LTTV_XENO_STATS_TEXT_WAITING_AVG
, LTTV_TIME
, &global_avg_time
);
2014 if (*(global_synch
.v_uint
) == 0 || ltt_time_compare(*(global_total_time
.v_time
),ltt_time_zero
) == 0) *(global_avg_time
.v_time
) = *(global_total_time
.v_time
);
2015 else *(global_avg_time
.v_time
) = ltt_time_div(*(global_total_time
.v_time
), *(global_synch
.v_uint
));
2017 lttv_attribute_find(global_synch_tree
, LTTV_XENO_STATS_TEXT_WAITING_MAX
, LTTV_TIME
, &global_max_time
);
2018 // If this owning time is longer than any other before
2019 if (ltt_time_compare(delta
,*(global_max_time
.v_time
)) == 1) *(global_max_time
.v_time
) = delta
;
2021 lttv_attribute_find(global_synch_tree
, LTTV_XENO_STATS_TEXT_WAITING_MIN
, LTTV_TIME
, &global_min_time
);
2022 // If this owning time is shorter than any other before
2023 if (*(global_synch
.v_uint
) == 1) *(global_min_time
.v_time
) = delta
;
2024 else if (ltt_time_compare(*(global_min_time
.v_time
), delta
) == 1) *(global_min_time
.v_time
) = delta
;
2031 gboolean
xenoltt_synch_unblock(void *hook_data
, void *call_data
){
2032 LttvTracefileStats
*tfcs
= (LttvTracefileStats
*)call_data
;
2033 LttvTraceState
*ts
= (LttvTraceState
*)tfcs
->parent
.parent
.t_context
;
2034 LttvTraceStats
*tcs
= (LttvTraceStats
*)tfcs
->parent
.parent
.t_context
;
2035 LttEvent
*e
= ltt_tracefile_get_event(tfcs
->parent
.parent
.tf
);
2036 LttvTraceHookByFacility
*thf
= (LttvTraceHookByFacility
*)hook_data
;
2037 LttvAttributeValue synch
, total_time
, avg_time
, max_time
, min_time
;
2038 LttvAttributeValue global_synch
, global_total_time
, global_avg_time
, global_max_time
, global_min_time
;
2039 LttvAttribute
*synch_tree
, *global_synch_tree
;
2040 guint cpu
= tfcs
->parent
.cpu
;
2041 LttvXenoThreadState
*thread
= ts
->running_thread
[cpu
];
2043 g_assert(thf
->f1
!= NULL
);
2044 gulong synch_address
= ltt_event_get_long_unsigned(e
, thf
->f1
);
2045 LttvXenoSynchState
*synch_state
= lttv_xeno_state_find_synch(ts
,synch_address
);
2046 if (synch_state
!= NULL
){
2048 xeno_find_task_tree(tfcs
, thread
->name
, thread
->address
,cpu
, &(tfcs
->current_events_tree
), &(tfcs
->current_event_types_tree
));
2050 synch_tree
= lttv_attribute_find_subdir(tfcs
->current_events_tree
, LTTV_XENO_STATS_SYNCH
);
2052 gchar synch_id
[MAX_64_HEX_STRING_LEN
];
2053 sprintf(synch_id
,"%p", (void *) synch_address
);
2054 synch_tree
= lttv_attribute_find_subdir(synch_tree
, g_quark_from_string(synch_id
));
2056 // We must update the global ressources tree also
2057 global_synch_tree
= lttv_attribute_find_subdir(tcs
->xenoltt_stats
, LTTV_XENO_STATS
);
2058 global_synch_tree
= lttv_attribute_find_subdir(global_synch_tree
, LTTV_XENO_STATS_SYNCH
);
2059 global_synch_tree
= lttv_attribute_find_subdir(global_synch_tree
, g_quark_from_string(synch_id
));
2061 lttv_attribute_find(synch_tree
, LTTV_XENO_STATS_TEXT_OWNER
, LTTV_UINT
, &synch
);
2063 // Compute time spent in possession of the ressource
2064 LttTime delta
= ltt_time_sub(tfcs
->parent
.parent
.timestamp
, synch_state
->state
->start_time
);
2066 lttv_attribute_find(synch_tree
, LTTV_XENO_STATS_TEXT_OWNER_TOTAL
, LTTV_TIME
, &total_time
);
2067 *(total_time
.v_time
) = ltt_time_add(*(total_time
.v_time
), delta
);
2069 lttv_attribute_find(synch_tree
, LTTV_XENO_STATS_TEXT_OWNER_AVG
, LTTV_TIME
, &avg_time
);
2070 if (*(synch
.v_uint
) == 0 || ltt_time_compare(*(total_time
.v_time
),ltt_time_zero
) == 0) *(avg_time
.v_time
) = *(total_time
.v_time
);
2071 else *(avg_time
.v_time
) = ltt_time_div(*(total_time
.v_time
), *(synch
.v_uint
));
2073 lttv_attribute_find(synch_tree
, LTTV_XENO_STATS_TEXT_OWNER_MAX
, LTTV_TIME
, &max_time
);
2074 // If this owning time is longer than any other before
2075 if (ltt_time_compare(delta
,*(max_time
.v_time
)) == 1) *(max_time
.v_time
) = delta
;
2077 lttv_attribute_find(synch_tree
, LTTV_XENO_STATS_TEXT_OWNER_MIN
, LTTV_TIME
, &min_time
);
2078 // If this owning time is shorter than any other before
2079 if (*(synch
.v_uint
) == 1) *(min_time
.v_time
) = delta
;
2080 else if (ltt_time_compare(*(min_time
.v_time
), delta
) == 1) *(min_time
.v_time
) = delta
;
2082 /**** GLOBAL RESOURCE TREE ***********/
2083 lttv_attribute_find(global_synch_tree
, LTTV_XENO_STATS_TEXT_OWNER
, LTTV_UINT
, &global_synch
);
2085 lttv_attribute_find(global_synch_tree
, LTTV_XENO_STATS_TEXT_OWNER_TOTAL
, LTTV_TIME
, &global_total_time
);
2086 *(global_total_time
.v_time
) = ltt_time_add(*(global_total_time
.v_time
), delta
);
2088 lttv_attribute_find(global_synch_tree
, LTTV_XENO_STATS_TEXT_OWNER_AVG
, LTTV_TIME
, &global_avg_time
);
2089 if (*(global_synch
.v_uint
) == 0 || ltt_time_compare(*(global_total_time
.v_time
),ltt_time_zero
) == 0) *(global_avg_time
.v_time
) = *(global_total_time
.v_time
);
2090 else *(global_avg_time
.v_time
) = ltt_time_div(*(global_total_time
.v_time
), *(global_synch
.v_uint
));
2092 lttv_attribute_find(global_synch_tree
, LTTV_XENO_STATS_TEXT_OWNER_MAX
, LTTV_TIME
, &global_max_time
);
2093 // If this owning time is longer than any other before
2094 if (ltt_time_compare(delta
,*(global_max_time
.v_time
)) == 1) *(global_max_time
.v_time
) = delta
;
2096 lttv_attribute_find(global_synch_tree
, LTTV_XENO_STATS_TEXT_OWNER_MIN
, LTTV_TIME
, &global_min_time
);
2097 // If this owning time is shorter than any other before
2098 if (*(global_synch
.v_uint
) == 1) *(global_min_time
.v_time
) = delta
;
2099 else if (ltt_time_compare(*(global_min_time
.v_time
), delta
) == 1) *(global_min_time
.v_time
) = delta
;
2107 /****************************************************************************************************************************/
2112 static void module_init()
2114 LTTV_STATS_PROCESS_UNKNOWN
= g_quark_from_string("unknown process");
2115 LTTV_STATS_PROCESSES
= g_quark_from_string("processes");
2116 LTTV_STATS_CPU
= g_quark_from_string("cpu");
2117 LTTV_STATS_MODE_TYPES
= g_quark_from_string("mode_types");
2118 LTTV_STATS_MODES
= g_quark_from_string("modes");
2119 LTTV_STATS_SUBMODES
= g_quark_from_string("submodes");
2120 LTTV_STATS_FUNCTIONS
= g_quark_from_string("functions");
2121 LTTV_STATS_EVENT_TYPES
= g_quark_from_string("event_types");
2122 LTTV_STATS_CPU_TIME
= g_quark_from_string("cpu time");
2123 LTTV_STATS_CUMULATIVE_CPU_TIME
= g_quark_from_string("cumulative cpu time (includes nested routines and modes)");
2124 LTTV_STATS_ELAPSED_TIME
= g_quark_from_string("elapsed time (includes per process waiting time)");
2125 LTTV_STATS_EVENTS
= g_quark_from_string("events");
2126 LTTV_STATS_EVENTS_COUNT
= g_quark_from_string("events count");
2127 LTTV_STATS_BEFORE_HOOKS
= g_quark_from_string("saved stats before hooks");
2128 LTTV_STATS_AFTER_HOOKS
= g_quark_from_string("saved stats after hooks");
2129 LTTV_STATS_USE_COUNT
= g_quark_from_string("stats_use_count");
2130 LTTV_STATS
= g_quark_from_string("statistics");
2131 LTTV_STATS_TRACEFILES
= g_quark_from_string("tracefiles statistics");
2132 LTTV_STATS_SUMMED
= g_quark_from_string("statistics summed");
2133 /****************************************************************************************************************************/
2134 LTTV_XENO_STATS
= g_quark_from_string("Xenomai");
2135 LTTV_XENO_STATS_THREADS
= g_quark_from_string("Tasks");
2136 LTTV_XENO_STATS_PERIOD
= g_quark_from_string("Periods");
2137 LTTV_XENO_STATS_STATE
= g_quark_from_string("Status");
2138 LTTV_XENO_STATS_SYNCH
= g_quark_from_string("Resources");
2139 LTTV_XENO_STATS_THREAD_PRIO
= g_quark_from_string("Priority");
2140 LTTV_XENO_STATS_THREAD_PERIOD
= g_quark_from_string("Period");
2141 LTTV_XENO_STATS_PERIOD_OVERRUNS
= g_quark_from_string("Overruns(s)");
2142 LTTV_XENO_STATS_TEXT_OVERRUNS
= g_quark_from_string("Overrun(s)");
2143 LTTV_XENO_STATS_TEXT_TICKS
= g_quark_from_string("Number of ticks");
2144 LTTV_XENO_STATS_TEXT_OWNER
= g_quark_from_string("Owner");
2145 LTTV_XENO_STATS_TEXT_OWNER_TOTAL
= g_quark_from_string("\tTotal time");
2146 LTTV_XENO_STATS_TEXT_OWNER_MAX
= g_quark_from_string("\tMax time");
2147 LTTV_XENO_STATS_TEXT_OWNER_MIN
= g_quark_from_string("\tMin time");
2148 LTTV_XENO_STATS_TEXT_OWNER_AVG
= g_quark_from_string("\tAverage time");
2149 LTTV_XENO_STATS_TEXT_WAITING
= g_quark_from_string("Waiting");
2150 LTTV_XENO_STATS_TEXT_WAITING_TOTAL
= g_quark_from_string("\tTotal time waiting");
2151 LTTV_XENO_STATS_TEXT_WAITING_MAX
= g_quark_from_string("\tMax time waiting");
2152 LTTV_XENO_STATS_TEXT_WAITING_MIN
= g_quark_from_string("\tMin time waiting");
2153 LTTV_XENO_STATS_TEXT_WAITING_AVG
= g_quark_from_string("\tAverage time waiting");
2154 LTTV_XENO_STATS_TEXT_TOTAL
= g_quark_from_string("\tTotal time");
2155 LTTV_XENO_STATS_TEXT_READY_MAX
= g_quark_from_string("\tMax time in readyq");
2156 LTTV_XENO_STATS_TEXT_READY_MIN
= g_quark_from_string("\tMin time in readyq");
2157 LTTV_XENO_STATS_TEXT_READY_AVG
= g_quark_from_string("\tAverage time in readyq");
2158 LTTV_XENO_STATS_TEXT_RUNNING_MAX
= g_quark_from_string("\tMax time running");
2159 LTTV_XENO_STATS_TEXT_RUNNING_MIN
= g_quark_from_string("\tMin time running");
2160 LTTV_XENO_STATS_TEXT_RUNNING_AVG
= g_quark_from_string("\tAverage time running");
2161 LTTV_XENO_STATS_TEXT_SUSPEND_MAX
= g_quark_from_string("\tMax time suspended");
2162 LTTV_XENO_STATS_TEXT_SUSPEND_MIN
= g_quark_from_string("\tMin time suspended");
2163 LTTV_XENO_STATS_TEXT_SUSPEND_AVG
= g_quark_from_string("\tAverage time suspended");
2164 LTTV_XENO_STATS_NB_PERIOD
= g_quark_from_string("Number of periods executed");
2165 /****************************************************************************************************************************/
2168 static void module_destroy()
2173 LTTV_MODULE("stats", "Compute processes statistics", \
2174 "Accumulate statistics for event types, processes and CPUs", \
2175 module_init
, module_destroy
, "state");
2177 /* Change the places where stats are called (create/read/write stats)
2179 Check for options in batchtest.c to reduce writing and see what tests are
2180 best candidates for performance analysis. Once OK, commit, move to main
2181 and run tests. Update the gui for statistics. */