fix core facility event update
[lttv.git] / ltt / branches / poly / lttv / lttv / stats.c
... / ...
CommitLineData
1/* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Michel Dagenais
3 *
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;
7 *
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.
12 *
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,
16 * MA 02111-1307, USA.
17 */
18
19#ifdef HAVE_CONFIG_H
20#include <config.h>
21#endif
22
23#include <stdio.h>
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>
31#include <ltt/type.h>
32
33#define BUF_SIZE 256
34#define MAX_64_HEX_STRING_LEN 19
35
36GQuark
37 LTTV_STATS_PROCESS_UNKNOWN,
38 LTTV_STATS_PROCESSES,
39 LTTV_STATS_CPU,
40 LTTV_STATS_MODE_TYPES,
41 LTTV_STATS_MODES,
42 LTTV_STATS_SUBMODES,
43 LTTV_STATS_FUNCTIONS,
44 LTTV_STATS_EVENT_TYPES,
45 LTTV_STATS_CPU_TIME,
46 LTTV_STATS_CUMULATIVE_CPU_TIME,
47 LTTV_STATS_ELAPSED_TIME,
48 LTTV_STATS_EVENTS,
49 LTTV_STATS_EVENTS_COUNT,
50 LTTV_STATS_USE_COUNT,
51 LTTV_STATS,
52 LTTV_STATS_TRACEFILES,
53 LTTV_STATS_SUMMED,
54 LTTV_STATS_BEFORE_HOOKS,
55 LTTV_STATS_AFTER_HOOKS;
56
57static void
58find_event_tree(LttvTracefileStats *tfcs, GQuark pid_time, guint cpu,
59 guint64 function,
60 GQuark mode, GQuark sub_mode, LttvAttribute **events_tree,
61 LttvAttribute **event_types_tree);
62
63
64static void lttv_stats_init(LttvTracesetStats *self)
65{
66 guint i, j, nb_trace, nb_tracefile;
67
68 LttvTraceContext *tc;
69
70 LttvTraceStats *tcs;
71
72 LttvTracefileContext *tfc;
73
74 LttvTracefileContext **tfs;
75 LttvTracefileStats *tfcs;
76
77 LttTime timestamp = {0,0};
78
79 LttvAttributeValue v;
80
81 LttvAttribute
82 *stats_tree,
83 *tracefiles_stats;
84
85 LttvTraceset *ts = self->parent.parent.ts;
86
87 self->stats = lttv_attribute_find_subdir(
88 lttv_traceset_attribute(self->parent.parent.ts),
89 LTTV_STATS);
90 lttv_attribute_find(lttv_traceset_attribute(self->parent.parent.ts),
91 LTTV_STATS_USE_COUNT,
92 LTTV_UINT, &v);
93
94 (*(v.v_uint))++;
95 if(*(v.v_uint) == 1) {
96 g_assert(lttv_attribute_get_number(self->stats) == 0);
97 }
98
99 nb_trace = lttv_traceset_number(ts);
100
101 for(i = 0 ; i < nb_trace ; i++) {
102 tc = self->parent.parent.traces[i];
103 tcs = LTTV_TRACE_STATS(tc);
104
105 tcs->stats = lttv_attribute_find_subdir(tcs->parent.parent.t_a,LTTV_STATS);
106 tracefiles_stats = lttv_attribute_find_subdir(tcs->parent.parent.t_a,
107 LTTV_STATS_TRACEFILES);
108 lttv_attribute_find(tcs->parent.parent.t_a, LTTV_STATS_USE_COUNT,
109 LTTV_UINT, &v);
110
111 (*(v.v_uint))++;
112 if(*(v.v_uint) == 1) {
113 g_assert(lttv_attribute_get_number(tcs->stats) == 0);
114 }
115
116 nb_tracefile = tc->tracefiles->len;
117
118 for(j = 0 ; j < nb_tracefile ; j++) {
119 tfs = &g_array_index(tc->tracefiles,
120 LttvTracefileContext*, j);
121 tfcs = LTTV_TRACEFILE_STATS(*tfs);
122 tfcs->stats = lttv_attribute_find_subdir(tracefiles_stats,
123 ltt_tracefile_long_name(tfcs->parent.parent.tf));
124 guint cpu = tfcs->parent.cpu;
125 find_event_tree(tfcs, LTTV_STATS_PROCESS_UNKNOWN,
126 cpu,
127 0x0ULL,
128 LTTV_STATE_MODE_UNKNOWN,
129 LTTV_STATE_SUBMODE_UNKNOWN, &tfcs->current_events_tree,
130 &tfcs->current_event_types_tree);
131 }
132 }
133
134}
135
136static void lttv_stats_fini(LttvTracesetStats *self)
137{
138 guint i, j, nb_trace, nb_tracefile;
139
140 LttvTraceset *ts;
141
142 LttvTraceContext *tc;
143
144 LttvTraceStats *tcs;
145
146 LttvTracefileContext *tfc;
147
148 LttvTracefileStats *tfcs;
149
150 LttTime timestamp = {0,0};
151
152 LttvAttributeValue v;
153
154 LttvAttribute *tracefiles_stats;
155
156 lttv_attribute_find(self->parent.parent.ts_a, LTTV_STATS_USE_COUNT,
157 LTTV_UINT, &v);
158 (*(v.v_uint))--;
159
160 if(*(v.v_uint) == 0) {
161 lttv_attribute_remove_by_name(self->parent.parent.ts_a, LTTV_STATS);
162 }
163 self->stats = NULL;
164
165 ts = self->parent.parent.ts;
166 nb_trace = lttv_traceset_number(ts);
167
168 for(i = 0 ; i < nb_trace ; i++) {
169 tcs = (LttvTraceStats *)(tc = (LTTV_TRACESET_CONTEXT(self)->traces[i]));
170
171 lttv_attribute_find(tcs->parent.parent.t_a, LTTV_STATS_USE_COUNT,
172 LTTV_UINT, &v);
173 (*(v.v_uint))--;
174
175 if(*(v.v_uint) == 0) {
176 lttv_attribute_remove_by_name(tcs->parent.parent.t_a,LTTV_STATS);
177 tracefiles_stats = lttv_attribute_find_subdir(tcs->parent.parent.t_a,
178 LTTV_STATS_TRACEFILES);
179 lttv_attribute_remove_by_name(tcs->parent.parent.t_a,
180 LTTV_STATS_TRACEFILES);
181 }
182 tcs->stats = NULL;
183
184 nb_tracefile = tc->tracefiles->len;
185
186 for(j = 0 ; j < nb_tracefile ; j++) {
187 tfc = g_array_index(tc->tracefiles,
188 LttvTracefileContext*, j);
189 tfcs = (LttvTracefileStats *)tfc;
190 tfcs->stats = NULL;
191 tfcs->current_events_tree = NULL;
192 tfcs->current_event_types_tree = NULL;
193 }
194 }
195}
196
197
198void lttv_stats_reset(LttvTracesetStats *self)
199{
200 lttv_stats_fini(self);
201 lttv_stats_init(self);
202}
203
204
205
206static void
207init(LttvTracesetStats *self, LttvTraceset *ts)
208{
209 LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))->
210 init((LttvTracesetContext *)self, ts);
211
212 lttv_stats_init(self);
213}
214
215
216static void
217fini(LttvTracesetStats *self)
218{
219 lttv_stats_fini(self);
220
221 LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))->
222 fini((LttvTracesetContext *)self);
223}
224
225
226static LttvTracesetContext *
227new_traceset_context(LttvTracesetContext *self)
228{
229 return LTTV_TRACESET_CONTEXT(g_object_new(LTTV_TRACESET_STATS_TYPE, NULL));
230}
231
232
233static LttvTraceContext *
234new_trace_context(LttvTracesetContext *self)
235{
236 return LTTV_TRACE_CONTEXT(g_object_new(LTTV_TRACE_STATS_TYPE, NULL));
237}
238
239
240static LttvTracefileContext *
241new_tracefile_context(LttvTracesetContext *self)
242{
243 return LTTV_TRACEFILE_CONTEXT(g_object_new(LTTV_TRACEFILE_STATS_TYPE, NULL));
244}
245
246
247static void
248traceset_stats_instance_init (GTypeInstance *instance, gpointer g_class)
249{
250}
251
252
253static void
254traceset_stats_finalize (LttvTracesetStats *self)
255{
256 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))->
257 finalize(G_OBJECT(self));
258}
259
260
261static void
262traceset_stats_class_init (LttvTracesetContextClass *klass)
263{
264 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
265
266 gobject_class->finalize = (void (*)(GObject *self)) traceset_stats_finalize;
267 klass->init = (void (*)(LttvTracesetContext *self, LttvTraceset *ts))init;
268 klass->fini = (void (*)(LttvTracesetContext *self))fini;
269 klass->new_traceset_context = new_traceset_context;
270 klass->new_trace_context = new_trace_context;
271 klass->new_tracefile_context = new_tracefile_context;
272}
273
274
275GType
276lttv_traceset_stats_get_type(void)
277{
278 static GType type = 0;
279 if (type == 0) {
280 static const GTypeInfo info = {
281 sizeof (LttvTracesetStatsClass),
282 NULL, /* base_init */
283 NULL, /* base_finalize */
284 (GClassInitFunc) traceset_stats_class_init, /* class_init */
285 NULL, /* class_finalize */
286 NULL, /* class_data */
287 sizeof (LttvTracesetStats),
288 0, /* n_preallocs */
289 (GInstanceInitFunc) traceset_stats_instance_init, /* instance_init */
290 NULL /* Value handling */
291 };
292
293 type = g_type_register_static (LTTV_TRACESET_STATE_TYPE,
294 "LttvTracesetStatsType",
295 &info, 0);
296 }
297 return type;
298}
299
300
301static void
302trace_stats_instance_init (GTypeInstance *instance, gpointer g_class)
303{
304}
305
306
307static void
308trace_stats_finalize (LttvTraceStats *self)
309{
310 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACE_STATE_TYPE))->
311 finalize(G_OBJECT(self));
312}
313
314
315static void
316trace_stats_class_init (LttvTraceContextClass *klass)
317{
318 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
319
320 gobject_class->finalize = (void (*)(GObject *self)) trace_stats_finalize;
321}
322
323
324GType
325lttv_trace_stats_get_type(void)
326{
327 static GType type = 0;
328 if (type == 0) {
329 static const GTypeInfo info = {
330 sizeof (LttvTraceStatsClass),
331 NULL, /* base_init */
332 NULL, /* base_finalize */
333 (GClassInitFunc) trace_stats_class_init, /* class_init */
334 NULL, /* class_finalize */
335 NULL, /* class_data */
336 sizeof (LttvTraceStats),
337 0, /* n_preallocs */
338 (GInstanceInitFunc) trace_stats_instance_init, /* instance_init */
339 NULL /* Value handling */
340 };
341
342 type = g_type_register_static (LTTV_TRACE_STATE_TYPE,
343 "LttvTraceStatsType", &info, 0);
344 }
345 return type;
346}
347
348
349static void
350tracefile_stats_instance_init (GTypeInstance *instance, gpointer g_class)
351{
352}
353
354
355static void
356tracefile_stats_finalize (LttvTracefileStats *self)
357{
358 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACEFILE_STATE_TYPE))->
359 finalize(G_OBJECT(self));
360}
361
362
363static void
364tracefile_stats_class_init (LttvTracefileStatsClass *klass)
365{
366 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
367
368 gobject_class->finalize = (void (*)(GObject *self)) tracefile_stats_finalize;
369}
370
371
372GType
373lttv_tracefile_stats_get_type(void)
374{
375 static GType type = 0;
376 if (type == 0) {
377 static const GTypeInfo info = {
378 sizeof (LttvTracefileStatsClass),
379 NULL, /* base_init */
380 NULL, /* base_finalize */
381 (GClassInitFunc) tracefile_stats_class_init, /* class_init */
382 NULL, /* class_finalize */
383 NULL, /* class_data */
384 sizeof (LttvTracefileStats),
385 0, /* n_preallocs */
386 (GInstanceInitFunc) tracefile_stats_instance_init, /* instance_init */
387 NULL /* Value handling */
388 };
389
390 type = g_type_register_static (LTTV_TRACEFILE_STATE_TYPE,
391 "LttvTracefileStatsType", &info, 0);
392 }
393 return type;
394}
395
396
397static void
398find_event_tree(LttvTracefileStats *tfcs,
399 GQuark pid_time,
400 guint cpu,
401 guint64 function,
402 GQuark mode,
403 GQuark sub_mode,
404 LttvAttribute **events_tree,
405 LttvAttribute **event_types_tree)
406{
407 LttvAttribute *a, *prev_a;
408 gchar fstring[MAX_64_HEX_STRING_LEN];
409 gint ret;
410
411 ret = snprintf(fstring, MAX_64_HEX_STRING_LEN-1,
412 "0x%llX", function) > 0;
413 g_assert(ret > 0);
414 fstring[MAX_64_HEX_STRING_LEN-1] = '\0';
415
416 LttvTraceStats *tcs = (LttvTraceStats*)tfcs->parent.parent.t_context;
417 a = lttv_attribute_find_subdir(tcs->stats, LTTV_STATS_PROCESSES);
418 a = lttv_attribute_find_subdir(a, pid_time);
419 a = lttv_attribute_find_subdir(a, LTTV_STATS_CPU);
420 a = lttv_attribute_find_subdir_unnamed(a, cpu);
421 a = lttv_attribute_find_subdir(a, LTTV_STATS_FUNCTIONS);
422 a = lttv_attribute_find_subdir(a, g_quark_from_string(fstring));
423 a = lttv_attribute_find_subdir(a, LTTV_STATS_MODE_TYPES);
424 a = lttv_attribute_find_subdir(a, mode);
425 a = lttv_attribute_find_subdir(a, LTTV_STATS_SUBMODES);
426 a = lttv_attribute_find_subdir(a, sub_mode);
427 *events_tree = a;
428 a = lttv_attribute_find_subdir(a, LTTV_STATS_EVENT_TYPES);
429 *event_types_tree = a;
430}
431
432
433static void update_event_tree(LttvTracefileStats *tfcs)
434{
435 LttvTraceState *ts = (LttvTraceState *)tfcs->parent.parent.t_context;
436 guint cpu = tfcs->parent.cpu;
437 LttvProcessState *process = ts->running_process[cpu];
438 LttvExecutionState *es = process->state;
439
440 find_event_tree(tfcs, process->pid_time,
441 cpu,
442 process->current_function,
443 es->t, es->n, &(tfcs->current_events_tree),
444 &(tfcs->current_event_types_tree));
445}
446
447
448static void mode_change(LttvTracefileStats *tfcs)
449{
450 LttvTraceState *ts = (LttvTraceState *)tfcs->parent.parent.t_context;
451 guint cpu = tfcs->parent.cpu;
452 LttvProcessState *process = ts->running_process[cpu];
453 LttvAttributeValue cpu_time, cum_cpu_time;
454
455 LttTime delta;
456
457 delta = ltt_time_sub(tfcs->parent.parent.timestamp,
458 process->state->change);
459
460 lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CPU_TIME,
461 LTTV_TIME, &cpu_time);
462 *(cpu_time.v_time) = ltt_time_add(*(cpu_time.v_time), delta);
463
464 process->state->cum_cpu_time = ltt_time_add(process->state->cum_cpu_time,
465 delta);
466}
467
468/* Note : every mode_end must come with a cumulative cpu time update in the
469 * after hook */
470static void mode_end(LttvTracefileStats *tfcs)
471{
472 LttvTraceState *ts = (LttvTraceState *)tfcs->parent.parent.t_context;
473 guint cpu = tfcs->parent.cpu;
474 LttvProcessState *process = ts->running_process[cpu];
475 LttvAttributeValue elapsed_time, cpu_time, cum_cpu_time;
476
477 LttTime delta;
478
479 lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_ELAPSED_TIME,
480 LTTV_TIME, &elapsed_time);
481 delta = ltt_time_sub(tfcs->parent.parent.timestamp,
482 process->state->entry);
483 *(elapsed_time.v_time) = ltt_time_add(*(elapsed_time.v_time), delta);
484
485 lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CPU_TIME,
486 LTTV_TIME, &cpu_time);
487 delta = ltt_time_sub(tfcs->parent.parent.timestamp,
488 process->state->change);
489 *(cpu_time.v_time) = ltt_time_add(*(cpu_time.v_time), delta);
490 process->state->cum_cpu_time = ltt_time_add(process->state->cum_cpu_time,
491 delta);
492
493 lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CUMULATIVE_CPU_TIME,
494 LTTV_TIME, &cum_cpu_time);
495 *(cum_cpu_time.v_time) = ltt_time_add(*(cum_cpu_time.v_time),
496 process->state->cum_cpu_time);
497}
498
499
500static void after_mode_end(LttvTracefileStats *tfcs)
501{
502 LttvTraceState *ts = (LttvTraceState *)tfcs->parent.parent.t_context;
503 guint cpu = tfcs->parent.cpu;
504 LttvProcessState *process = ts->running_process[cpu];
505 LttvAttributeValue cum_cpu_time;
506
507 LttTime nested_delta;
508
509 nested_delta = process->state->cum_cpu_time;
510 process->state->cum_cpu_time = ltt_time_zero; /* For after traceset hook */
511
512 update_event_tree(tfcs);
513
514 process->state->cum_cpu_time = ltt_time_add(process->state->cum_cpu_time,
515 nested_delta);
516}
517
518static gboolean before_syscall_entry(void *hook_data, void *call_data)
519{
520 mode_change((LttvTracefileStats *)call_data);
521 return FALSE;
522}
523
524
525static gboolean after_syscall_entry(void *hook_data, void *call_data)
526{
527 update_event_tree((LttvTracefileStats *)call_data);
528 return FALSE;
529}
530
531
532gboolean before_syscall_exit(void *hook_data, void *call_data)
533{
534 mode_end((LttvTracefileStats *)call_data);
535 return FALSE;
536}
537
538
539static gboolean after_syscall_exit(void *hook_data, void *call_data)
540{
541 after_mode_end((LttvTracefileStats *)call_data);
542 return FALSE;
543}
544
545
546gboolean before_trap_entry(void *hook_data, void *call_data)
547{
548 mode_change((LttvTracefileStats *)call_data);
549 return FALSE;
550}
551
552
553static gboolean after_trap_entry(void *hook_data, void *call_data)
554{
555 update_event_tree((LttvTracefileStats *)call_data);
556 return FALSE;
557}
558
559
560gboolean before_trap_exit(void *hook_data, void *call_data)
561{
562 mode_end((LttvTracefileStats *)call_data);
563 return FALSE;
564}
565
566
567gboolean after_trap_exit(void *hook_data, void *call_data)
568{
569 after_mode_end((LttvTracefileStats *)call_data);
570 return FALSE;
571}
572
573
574gboolean before_irq_entry(void *hook_data, void *call_data)
575{
576 mode_change((LttvTracefileStats *)call_data);
577 return FALSE;
578}
579
580gboolean after_irq_entry(void *hook_data, void *call_data)
581{
582 update_event_tree((LttvTracefileStats *)call_data);
583 return FALSE;
584}
585
586
587gboolean before_irq_exit(void *hook_data, void *call_data)
588{
589 mode_end((LttvTracefileStats *)call_data);
590 return FALSE;
591}
592
593
594gboolean after_irq_exit(void *hook_data, void *call_data)
595{
596 after_mode_end((LttvTracefileStats *)call_data);
597 return FALSE;
598}
599
600
601gboolean before_soft_irq_entry(void *hook_data, void *call_data)
602{
603 mode_change((LttvTracefileStats *)call_data);
604 return FALSE;
605}
606
607gboolean after_soft_irq_entry(void *hook_data, void *call_data)
608{
609 update_event_tree((LttvTracefileStats *)call_data);
610 return FALSE;
611}
612
613
614gboolean before_soft_irq_exit(void *hook_data, void *call_data)
615{
616 mode_end((LttvTracefileStats *)call_data);
617 return FALSE;
618}
619
620
621gboolean after_soft_irq_exit(void *hook_data, void *call_data)
622{
623 after_mode_end((LttvTracefileStats *)call_data);
624 return FALSE;
625}
626
627gboolean before_function_entry(void *hook_data, void *call_data)
628{
629 mode_change((LttvTracefileStats *)call_data);
630 return FALSE;
631}
632
633gboolean after_function_entry(void *hook_data, void *call_data)
634{
635 update_event_tree((LttvTracefileStats *)call_data);
636 return FALSE;
637}
638
639gboolean before_function_exit(void *hook_data, void *call_data)
640{
641 mode_end((LttvTracefileStats *)call_data);
642 return FALSE;
643}
644
645gboolean after_function_exit(void *hook_data, void *call_data)
646{
647 after_mode_end((LttvTracefileStats *)call_data);
648 return FALSE;
649}
650
651
652gboolean before_schedchange(void *hook_data, void *call_data)
653{
654 LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
655
656 LttvTraceState *ts = (LttvTraceState*)tfcs->parent.parent.t_context;
657
658 LttEvent *e = ltt_tracefile_get_event(tfcs->parent.parent.tf);
659
660 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
661
662 guint pid_in, pid_out;
663
664 gint state_out;
665
666 pid_out = ltt_event_get_unsigned(e, thf->f1);
667 pid_in = ltt_event_get_unsigned(e, thf->f2);
668 state_out = ltt_event_get_int(e, thf->f3);
669
670 /* compute the time for the process to schedule out */
671
672 mode_change(tfcs);
673
674 return FALSE;
675}
676
677gboolean after_schedchange(void *hook_data, void *call_data)
678{
679 LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
680
681 LttvTraceState *ts = (LttvTraceState*)tfcs->parent.parent.t_context;
682
683 LttEvent *e = ltt_tracefile_get_event(tfcs->parent.parent.tf);
684
685 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
686
687 guint pid_in, pid_out;
688
689 gint state_out;
690
691 LttvProcessState *process;
692
693 pid_out = ltt_event_get_unsigned(e, thf->f1);
694 pid_in = ltt_event_get_unsigned(e, thf->f2);
695 state_out = ltt_event_get_int(e, thf->f3);
696
697 /* get the information for the process scheduled in */
698 guint cpu = tfcs->parent.cpu;
699 process = ts->running_process[cpu];
700
701 find_event_tree(tfcs, process->pid_time,
702 cpu,
703 process->current_function,
704 process->state->t, process->state->n, &(tfcs->current_events_tree),
705 &(tfcs->current_event_types_tree));
706
707 /* compute the time waiting for the process to schedule in */
708 mode_change(tfcs);
709
710 return FALSE;
711}
712
713gboolean process_fork(void *hook_data, void *call_data)
714{
715 /* nothing to do for now */
716 return FALSE;
717}
718
719
720gboolean process_exit(void *hook_data, void *call_data)
721{
722 /* We should probably exit all modes here or we could do that at
723 schedule out. */
724 return FALSE;
725}
726
727gboolean process_free(void *hook_data, void *call_data)
728{
729 return FALSE;
730}
731
732gboolean every_event(void *hook_data, void *call_data)
733{
734 LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
735
736 LttEvent *e = ltt_tracefile_get_event(tfcs->parent.parent.tf);
737
738 LttvAttributeValue v;
739
740 /* The current branch corresponds to the tracefile/process/interrupt state.
741 Statistics are added within it, to count the number of events of this
742 type occuring in this context. A quark has been pre-allocated for each
743 event type and is used as name. */
744
745 lttv_attribute_find(tfcs->current_event_types_tree,
746 ltt_eventtype_name(ltt_event_eventtype(e)),
747 LTTV_UINT, &v);
748 (*(v.v_uint))++;
749 return FALSE;
750}
751
752static void lttv_stats_cleanup_process_state(gpointer key, gpointer value,
753 gpointer user_data)
754{
755 LttvTraceStats *tcs = (LttvTraceStats *)user_data;
756 LttvTraceState *ts = (LttvTraceState *)user_data;
757 LttvTracesetContext *tsc = ts->parent.ts_context;
758 LttvProcessState *process = (LttvProcessState *)value;
759 int i;
760 LttvTracefileStats **tfs = (LttvTracefileStats **)
761 &g_array_index(ts->parent.tracefiles, LttvTracefileContext*,
762 process->cpu);
763 int cleanup_empty = 0;
764 LttTime nested_delta = ltt_time_zero;
765 /* FIXME : ok, this is a hack. The time is infinite here :( */
766 LttTime save_time = (*tfs)->parent.parent.timestamp;
767 LttTime start, end;
768 ltt_trace_time_span_get(ts->parent.t, &start, &end);
769 (*tfs)->parent.parent.timestamp = end;
770
771 do {
772 if(ltt_time_compare(process->state->cum_cpu_time, ltt_time_zero) != 0) {
773 find_event_tree(*tfs, process->pid_time,
774 process->cpu,
775 process->current_function,
776 process->state->t, process->state->n, &((*tfs)->current_events_tree),
777 &((*tfs)->current_event_types_tree));
778 mode_end(*tfs);
779 nested_delta = process->state->cum_cpu_time;
780 }
781 cleanup_empty = lttv_state_pop_state_cleanup(process,
782 (LttvTracefileState *)*tfs);
783 process->state->cum_cpu_time = ltt_time_add(process->state->cum_cpu_time,
784 nested_delta);
785
786 } while(cleanup_empty != 1);
787
788 (*tfs)->parent.parent.timestamp = save_time;
789}
790
791/* For each process in the state, for each of their stacked states,
792 * perform sum of needed values. */
793static void lttv_stats_cleanup_state(LttvTraceStats *tcs)
794{
795 LttvTraceState *ts = (LttvTraceState *)tcs;
796
797 /* Does not work correctly FIXME. */
798 g_hash_table_foreach(ts->processes, lttv_stats_cleanup_process_state,
799 tcs);
800}
801
802void
803lttv_stats_sum_trace(LttvTraceStats *self, LttvAttribute *ts_stats)
804{
805 LttvAttribute *sum_container = self->stats;
806
807 LttvAttributeType type;
808
809 LttvAttributeValue value;
810
811 LttvAttributeName name;
812
813 gboolean is_named;
814
815 unsigned sum;
816
817 int trace_is_summed;
818
819 int i, j, k, l, m, nb_process, nb_cpu, nb_mode_type, nb_submode,
820 nb_event_type, nf, nb_functions;
821
822 LttvAttribute *main_tree, *processes_tree, *process_tree, *cpus_tree,
823 *cpu_tree, *mode_tree, *mode_types_tree, *submodes_tree,
824 *submode_tree, *event_types_tree, *mode_events_tree,
825 *cpu_functions_tree,
826 *function_tree,
827 *function_mode_types_tree,
828 *trace_cpu_tree;
829
830
831 main_tree = sum_container;
832
833 lttv_attribute_find(sum_container,
834 LTTV_STATS_SUMMED,
835 LTTV_UINT, &value);
836 trace_is_summed = *(value.v_uint);
837 *(value.v_uint) = 1;
838
839 /* First cleanup the state : sum all stalled information (never ending
840 * states). */
841 if(!trace_is_summed)
842 lttv_stats_cleanup_state(self);
843
844 processes_tree = lttv_attribute_find_subdir(main_tree,
845 LTTV_STATS_PROCESSES);
846 nb_process = lttv_attribute_get_number(processes_tree);
847
848 for(i = 0 ; i < nb_process ; i++) {
849 type = lttv_attribute_get(processes_tree, i, &name, &value, &is_named);
850 process_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
851
852 cpus_tree = lttv_attribute_find_subdir(process_tree, LTTV_STATS_CPU);
853 nb_cpu = lttv_attribute_get_number(cpus_tree);
854
855 for(j = 0 ; j < nb_cpu ; j++) {
856 type = lttv_attribute_get(cpus_tree, j, &name, &value, &is_named);
857 cpu_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
858
859 trace_cpu_tree = lttv_attribute_find_subdir(main_tree, LTTV_STATS_CPU);
860 trace_cpu_tree = lttv_attribute_find_subdir_unnamed(trace_cpu_tree, name);
861 cpu_functions_tree = lttv_attribute_find_subdir(cpu_tree,
862 LTTV_STATS_FUNCTIONS);
863 nb_functions = lttv_attribute_get_number(cpu_functions_tree);
864
865 for(nf=0; nf < nb_functions; nf++) {
866 type = lttv_attribute_get(cpu_functions_tree, nf, &name, &value,
867 &is_named);
868 function_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
869 function_mode_types_tree = lttv_attribute_find_subdir(function_tree,
870 LTTV_STATS_MODE_TYPES);
871 nb_mode_type = lttv_attribute_get_number(function_mode_types_tree);
872 for(k = 0 ; k < nb_mode_type ; k++) {
873 type = lttv_attribute_get(function_mode_types_tree, k, &name, &value,
874 &is_named);
875 mode_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
876
877 submodes_tree = lttv_attribute_find_subdir(mode_tree,
878 LTTV_STATS_SUBMODES);
879 mode_events_tree = lttv_attribute_find_subdir(mode_tree,
880 LTTV_STATS_EVENTS);
881 mode_types_tree = lttv_attribute_find_subdir(mode_tree,
882 LTTV_STATS_MODE_TYPES);
883
884 nb_submode = lttv_attribute_get_number(submodes_tree);
885
886 for(l = 0 ; l < nb_submode ; l++) {
887 type = lttv_attribute_get(submodes_tree, l, &name, &value,
888 &is_named);
889 submode_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
890
891 event_types_tree = lttv_attribute_find_subdir(submode_tree,
892 LTTV_STATS_EVENT_TYPES);
893 nb_event_type = lttv_attribute_get_number(event_types_tree);
894
895 sum = 0;
896 for(m = 0 ; m < nb_event_type ; m++) {
897 type = lttv_attribute_get(event_types_tree, m, &name, &value,
898 &is_named);
899 sum += *(value.v_uint);
900 }
901 lttv_attribute_find(submode_tree, LTTV_STATS_EVENTS_COUNT,
902 LTTV_UINT, &value);
903 *(value.v_uint) = sum;
904
905 type = lttv_attribute_get(submodes_tree, l, &name, &value,
906 &is_named);
907 submode_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
908 if(!trace_is_summed) {
909 lttv_attribute_recursive_add(mode_events_tree, event_types_tree);
910 lttv_attribute_recursive_add(mode_types_tree, submode_tree);
911 }
912 }
913 if(!trace_is_summed) {
914 lttv_attribute_recursive_add(function_tree, mode_types_tree);
915 }
916 }
917 if(!trace_is_summed) {
918 lttv_attribute_recursive_add(cpu_tree, function_tree);
919 lttv_attribute_recursive_add(process_tree, function_tree);
920 lttv_attribute_recursive_add(trace_cpu_tree, function_tree);
921 lttv_attribute_recursive_add(main_tree, function_tree);
922 }
923 lttv_attribute_recursive_add(ts_stats, function_tree);
924 }
925 }
926 }
927}
928
929
930gboolean lttv_stats_sum_traceset_hook(void *hook_data, void *call_data)
931{
932 lttv_stats_sum_traceset((LttvTracesetStats *)call_data);
933 return 0;
934}
935
936void
937lttv_stats_sum_traceset(LttvTracesetStats *self)
938{
939 LttvTraceset *traceset = self->parent.parent.ts;
940 LttvAttribute *sum_container = self->stats;
941
942 LttvTraceStats *tcs;
943
944 int i, nb_trace;
945
946 LttvAttribute *main_tree;
947
948 LttvAttributeValue value;
949
950 lttv_attribute_find(sum_container, LTTV_STATS_SUMMED,
951 LTTV_UINT, &value);
952 if(*(value.v_uint) != 0) return;
953 *(value.v_uint) = 1;
954
955 nb_trace = lttv_traceset_number(traceset);
956
957 for(i = 0 ; i < nb_trace ; i++) {
958 tcs = (LttvTraceStats *)(self->parent.parent.traces[i]);
959 lttv_stats_sum_trace(tcs, self->stats);
960 // lttv_attribute_recursive_add(sum_container, tcs->stats);
961 }
962}
963
964
965// Hook wrapper. call_data is a traceset context.
966gboolean lttv_stats_hook_add_event_hooks(void *hook_data, void *call_data)
967{
968 LttvTracesetStats *tss = (LttvTracesetStats*)call_data;
969
970 lttv_stats_add_event_hooks(tss);
971
972 return 0;
973}
974
975void lttv_stats_add_event_hooks(LttvTracesetStats *self)
976{
977 LttvTraceset *traceset = self->parent.parent.ts;
978
979 guint i, j, k, l, nb_trace, nb_tracefile;
980
981 LttvTraceStats *ts;
982
983 LttvTracefileStats *tfs;
984
985 GArray *hooks, *before_hooks, *after_hooks;
986
987 LttvTraceHook *hook;
988
989 LttvTraceHookByFacility *thf;
990
991 LttvAttributeValue val;
992
993 gint ret;
994 gint hn;
995
996 nb_trace = lttv_traceset_number(traceset);
997 for(i = 0 ; i < nb_trace ; i++) {
998 ts = (LttvTraceStats *)self->parent.parent.traces[i];
999
1000 /* Find the eventtype id for the following events and register the
1001 associated by id hooks. */
1002
1003 hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 11);
1004 g_array_set_size(hooks, 11);
1005 hn=0;
1006
1007 ret = lttv_trace_find_hook(ts->parent.parent.t,
1008 LTT_FACILITY_KERNEL_ARCH, LTT_EVENT_SYSCALL_ENTRY,
1009 LTT_FIELD_SYSCALL_ID, 0, 0,
1010 before_syscall_entry, NULL,
1011 &g_array_index(hooks, LttvTraceHook, hn++));
1012 if(ret) hn--;
1013
1014 ret = lttv_trace_find_hook(ts->parent.parent.t,
1015 LTT_FACILITY_KERNEL_ARCH, LTT_EVENT_SYSCALL_EXIT,
1016 0, 0, 0,
1017 before_syscall_exit, NULL,
1018 &g_array_index(hooks, LttvTraceHook, hn++));
1019 if(ret) hn--;
1020
1021 ret = lttv_trace_find_hook(ts->parent.parent.t,
1022 LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_ENTRY,
1023 LTT_FIELD_TRAP_ID, 0, 0,
1024 before_trap_entry, NULL,
1025 &g_array_index(hooks, LttvTraceHook, hn++));
1026 if(ret) hn--;
1027
1028 ret = lttv_trace_find_hook(ts->parent.parent.t,
1029 LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_EXIT,
1030 0, 0, 0,
1031 before_trap_exit, NULL,
1032 &g_array_index(hooks, LttvTraceHook, hn++));
1033 if(ret) hn--;
1034
1035 ret = lttv_trace_find_hook(ts->parent.parent.t,
1036 LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_ENTRY,
1037 LTT_FIELD_IRQ_ID, 0, 0,
1038 before_irq_entry, NULL,
1039 &g_array_index(hooks, LttvTraceHook, hn++));
1040 if(ret) hn--;
1041
1042 ret = lttv_trace_find_hook(ts->parent.parent.t,
1043 LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_EXIT,
1044 0, 0, 0,
1045 before_irq_exit, NULL,
1046 &g_array_index(hooks, LttvTraceHook, hn++));
1047 if(ret) hn--;
1048
1049 ret = lttv_trace_find_hook(ts->parent.parent.t,
1050 LTT_FACILITY_KERNEL, LTT_EVENT_SOFT_IRQ_ENTRY,
1051 LTT_FIELD_SOFT_IRQ_ID, 0, 0,
1052 before_soft_irq_entry, NULL,
1053 &g_array_index(hooks, LttvTraceHook, hn++));
1054 if(ret) hn--;
1055
1056 ret = lttv_trace_find_hook(ts->parent.parent.t,
1057 LTT_FACILITY_KERNEL, LTT_EVENT_SOFT_IRQ_EXIT,
1058 0, 0, 0,
1059 before_soft_irq_exit, NULL,
1060 &g_array_index(hooks, LttvTraceHook, hn++));
1061 if(ret) hn--;
1062
1063 ret = lttv_trace_find_hook(ts->parent.parent.t,
1064 LTT_FACILITY_PROCESS, LTT_EVENT_SCHEDCHANGE,
1065 LTT_FIELD_OUT, LTT_FIELD_IN, LTT_FIELD_OUT_STATE,
1066 before_schedchange, NULL,
1067 &g_array_index(hooks, LttvTraceHook, hn++));
1068 if(ret) hn--;
1069
1070 ret = lttv_trace_find_hook(ts->parent.parent.t,
1071 LTT_FACILITY_USER_GENERIC, LTT_EVENT_FUNCTION_ENTRY,
1072 LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE, 0,
1073 before_function_entry, NULL,
1074 &g_array_index(hooks, LttvTraceHook, hn++));
1075 if(ret) hn--;
1076
1077 ret = lttv_trace_find_hook(ts->parent.parent.t,
1078 LTT_FACILITY_USER_GENERIC, LTT_EVENT_FUNCTION_EXIT,
1079 LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE, 0,
1080 before_function_exit, NULL,
1081 &g_array_index(hooks, LttvTraceHook, hn++));
1082 if(ret) hn--;
1083
1084 g_array_set_size(hooks, hn);
1085
1086 before_hooks = hooks;
1087
1088 hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 14);
1089 g_array_set_size(hooks, 14);
1090 hn=0;
1091
1092 ret = lttv_trace_find_hook(ts->parent.parent.t,
1093 LTT_FACILITY_KERNEL_ARCH, LTT_EVENT_SYSCALL_ENTRY,
1094 LTT_FIELD_SYSCALL_ID, 0, 0,
1095 after_syscall_entry, NULL,
1096 &g_array_index(hooks, LttvTraceHook, hn++));
1097 if(ret) hn--;
1098
1099 ret = lttv_trace_find_hook(ts->parent.parent.t,
1100 LTT_FACILITY_KERNEL_ARCH, LTT_EVENT_SYSCALL_EXIT,
1101 0, 0, 0,
1102 after_syscall_exit, NULL,
1103 &g_array_index(hooks, LttvTraceHook, hn++));
1104 if(ret) hn--;
1105
1106 ret = lttv_trace_find_hook(ts->parent.parent.t,
1107 LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_ENTRY,
1108 LTT_FIELD_TRAP_ID, 0, 0,
1109 after_trap_entry, NULL,
1110 &g_array_index(hooks, LttvTraceHook, hn++));
1111 if(ret) hn--;
1112
1113 ret = lttv_trace_find_hook(ts->parent.parent.t,
1114 LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_EXIT,
1115 0, 0, 0,
1116 after_trap_exit, NULL,
1117 &g_array_index(hooks, LttvTraceHook, hn++));
1118 if(ret) hn--;
1119
1120 ret = lttv_trace_find_hook(ts->parent.parent.t,
1121 LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_ENTRY,
1122 LTT_FIELD_IRQ_ID, 0, 0,
1123 after_irq_entry, NULL,
1124 &g_array_index(hooks, LttvTraceHook, hn++));
1125 if(ret) hn--;
1126
1127 ret = lttv_trace_find_hook(ts->parent.parent.t,
1128 LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_EXIT,
1129 0, 0, 0,
1130 after_irq_exit, NULL,
1131 &g_array_index(hooks, LttvTraceHook, hn++));
1132 if(ret) hn--;
1133
1134 ret = lttv_trace_find_hook(ts->parent.parent.t,
1135 LTT_FACILITY_KERNEL, LTT_EVENT_SOFT_IRQ_ENTRY,
1136 LTT_FIELD_SOFT_IRQ_ID, 0, 0,
1137 after_irq_entry, NULL,
1138 &g_array_index(hooks, LttvTraceHook, hn++));
1139 if(ret) hn--;
1140
1141 ret = lttv_trace_find_hook(ts->parent.parent.t,
1142 LTT_FACILITY_KERNEL, LTT_EVENT_SOFT_IRQ_EXIT,
1143 0, 0, 0,
1144 after_soft_irq_exit, NULL,
1145 &g_array_index(hooks, LttvTraceHook, hn++));
1146 if(ret) hn--;
1147
1148 ret = lttv_trace_find_hook(ts->parent.parent.t,
1149 LTT_FACILITY_PROCESS, LTT_EVENT_SCHEDCHANGE,
1150 LTT_FIELD_OUT, LTT_FIELD_IN, LTT_FIELD_OUT_STATE,
1151 after_schedchange, NULL,
1152 &g_array_index(hooks, LttvTraceHook, hn++));
1153 if(ret) hn--;
1154
1155 ret = lttv_trace_find_hook(ts->parent.parent.t,
1156 LTT_FACILITY_PROCESS, LTT_EVENT_FORK,
1157 LTT_FIELD_PARENT_PID, LTT_FIELD_CHILD_PID, 0,
1158 process_fork, NULL,
1159 &g_array_index(hooks, LttvTraceHook, hn++));
1160 if(ret) hn--;
1161
1162 ret = lttv_trace_find_hook(ts->parent.parent.t,
1163 LTT_FACILITY_PROCESS, LTT_EVENT_EXIT,
1164 LTT_FIELD_PID, 0, 0,
1165 process_exit, NULL,
1166 &g_array_index(hooks, LttvTraceHook, hn++));
1167 if(ret) hn--;
1168
1169 ret = lttv_trace_find_hook(ts->parent.parent.t,
1170 LTT_FACILITY_PROCESS, LTT_EVENT_FREE,
1171 LTT_FIELD_PID, 0, 0,
1172 process_free, NULL,
1173 &g_array_index(hooks, LttvTraceHook, hn++));
1174 if(ret) hn--;
1175
1176 ret = lttv_trace_find_hook(ts->parent.parent.t,
1177 LTT_FACILITY_USER_GENERIC, LTT_EVENT_FUNCTION_ENTRY,
1178 LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE, 0,
1179 after_function_entry, NULL,
1180 &g_array_index(hooks, LttvTraceHook, hn++));
1181 if(ret) hn--;
1182
1183 ret = lttv_trace_find_hook(ts->parent.parent.t,
1184 LTT_FACILITY_USER_GENERIC, LTT_EVENT_FUNCTION_EXIT,
1185 LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE, 0,
1186 after_function_exit, NULL,
1187 &g_array_index(hooks, LttvTraceHook, hn++));
1188 if(ret) hn--;
1189
1190 g_array_set_size(hooks, hn);
1191
1192 after_hooks = hooks;
1193
1194 /* Add these hooks to each event_by_id hooks list */
1195
1196 nb_tracefile = ts->parent.parent.tracefiles->len;
1197
1198 for(j = 0 ; j < nb_tracefile ; j++) {
1199 tfs = LTTV_TRACEFILE_STATS(g_array_index(ts->parent.parent.tracefiles,
1200 LttvTracefileContext*, j));
1201 lttv_hooks_add(tfs->parent.parent.event, every_event, NULL,
1202 LTTV_PRIO_DEFAULT);
1203
1204 for(k = 0 ; k < before_hooks->len ; k++) {
1205 hook = &g_array_index(before_hooks, LttvTraceHook, k);
1206 for(l = 0; l<hook->fac_list->len;l++) {
1207 thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
1208 lttv_hooks_add(
1209 lttv_hooks_by_id_find(tfs->parent.parent.event_by_id, thf->id),
1210 thf->h,
1211 thf,
1212 LTTV_PRIO_STATS_BEFORE_STATE);
1213 }
1214 }
1215 for(k = 0 ; k < after_hooks->len ; k++) {
1216 hook = &g_array_index(after_hooks, LttvTraceHook, k);
1217 for(l = 0; l<hook->fac_list->len;l++) {
1218 thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
1219 lttv_hooks_add(
1220 lttv_hooks_by_id_find(tfs->parent.parent.event_by_id, thf->id),
1221 thf->h,
1222 thf,
1223 LTTV_PRIO_STATS_AFTER_STATE);
1224 }
1225 }
1226 }
1227 lttv_attribute_find(self->parent.parent.a, LTTV_STATS_BEFORE_HOOKS,
1228 LTTV_POINTER, &val);
1229 *(val.v_pointer) = before_hooks;
1230 lttv_attribute_find(self->parent.parent.a, LTTV_STATS_AFTER_HOOKS,
1231 LTTV_POINTER, &val);
1232 *(val.v_pointer) = after_hooks;
1233 }
1234}
1235
1236// Hook wrapper. call_data is a traceset context.
1237gboolean lttv_stats_hook_remove_event_hooks(void *hook_data, void *call_data)
1238{
1239 LttvTracesetStats *tss = (LttvTracesetStats*)call_data;
1240
1241 lttv_stats_remove_event_hooks(tss);
1242
1243 return 0;
1244}
1245
1246void lttv_stats_remove_event_hooks(LttvTracesetStats *self)
1247{
1248 LttvTraceset *traceset = self->parent.parent.ts;
1249
1250 guint i, j, k, l, nb_trace, nb_tracefile;
1251
1252 LttvTraceStats *ts;
1253
1254 LttvTracefileStats *tfs;
1255
1256 void *hook_data;
1257
1258 GArray *before_hooks, *after_hooks;
1259
1260 LttvTraceHook *hook;
1261
1262 LttvTraceHookByFacility *thf;
1263
1264 LttvAttributeValue val;
1265
1266 nb_trace = lttv_traceset_number(traceset);
1267 for(i = 0 ; i < nb_trace ; i++) {
1268 ts = (LttvTraceStats*)self->parent.parent.traces[i];
1269 lttv_attribute_find(self->parent.parent.a, LTTV_STATS_BEFORE_HOOKS,
1270 LTTV_POINTER, &val);
1271 before_hooks = *(val.v_pointer);
1272 lttv_attribute_find(self->parent.parent.a, LTTV_STATS_AFTER_HOOKS,
1273 LTTV_POINTER, &val);
1274 after_hooks = *(val.v_pointer);
1275
1276 /* Remove these hooks from each event_by_id hooks list */
1277
1278 nb_tracefile = ts->parent.parent.tracefiles->len;
1279
1280 for(j = 0 ; j < nb_tracefile ; j++) {
1281 tfs = LTTV_TRACEFILE_STATS(g_array_index(ts->parent.parent.tracefiles,
1282 LttvTracefileContext*, j));
1283 lttv_hooks_remove_data(tfs->parent.parent.event, every_event,
1284 NULL);
1285
1286 for(k = 0 ; k < before_hooks->len ; k++) {
1287 hook = &g_array_index(before_hooks, LttvTraceHook, k);
1288 for(l = 0 ; l < hook->fac_list->len ; l++) {
1289 thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
1290 lttv_hooks_remove_data(
1291 lttv_hooks_by_id_find(tfs->parent.parent.event_by_id, thf->id),
1292 thf->h,
1293 thf);
1294 }
1295 }
1296 for(k = 0 ; k < after_hooks->len ; k++) {
1297 hook = &g_array_index(after_hooks, LttvTraceHook, k);
1298 for(l = 0 ; l < hook->fac_list->len ; l++) {
1299 thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
1300 lttv_hooks_remove_data(
1301 lttv_hooks_by_id_find(tfs->parent.parent.event_by_id, thf->id),
1302 thf->h,
1303 thf);
1304 }
1305 }
1306 }
1307 g_debug("lttv_stats_remove_event_hooks()");
1308 g_array_free(before_hooks, TRUE);
1309 g_array_free(after_hooks, TRUE);
1310 }
1311}
1312
1313
1314static void module_init()
1315{
1316 LTTV_STATS_PROCESS_UNKNOWN = g_quark_from_string("unknown process");
1317 LTTV_STATS_PROCESSES = g_quark_from_string("processes");
1318 LTTV_STATS_CPU = g_quark_from_string("cpu");
1319 LTTV_STATS_MODE_TYPES = g_quark_from_string("mode_types");
1320 LTTV_STATS_MODES = g_quark_from_string("modes");
1321 LTTV_STATS_SUBMODES = g_quark_from_string("submodes");
1322 LTTV_STATS_FUNCTIONS = g_quark_from_string("functions");
1323 LTTV_STATS_EVENT_TYPES = g_quark_from_string("event_types");
1324 LTTV_STATS_CPU_TIME = g_quark_from_string("cpu time");
1325 LTTV_STATS_CUMULATIVE_CPU_TIME = g_quark_from_string("cumulative cpu time (includes nested routines and modes)");
1326 LTTV_STATS_ELAPSED_TIME = g_quark_from_string("elapsed time (includes per process waiting time)");
1327 LTTV_STATS_EVENTS = g_quark_from_string("events");
1328 LTTV_STATS_EVENTS_COUNT = g_quark_from_string("events count");
1329 LTTV_STATS_BEFORE_HOOKS = g_quark_from_string("saved stats before hooks");
1330 LTTV_STATS_AFTER_HOOKS = g_quark_from_string("saved stats after hooks");
1331 LTTV_STATS_USE_COUNT = g_quark_from_string("stats_use_count");
1332 LTTV_STATS = g_quark_from_string("statistics");
1333 LTTV_STATS_TRACEFILES = g_quark_from_string("tracefiles statistics");
1334 LTTV_STATS_SUMMED = g_quark_from_string("statistics summed");
1335}
1336
1337static void module_destroy()
1338{
1339}
1340
1341
1342LTTV_MODULE("stats", "Compute processes statistics", \
1343 "Accumulate statistics for event types, processes and CPUs", \
1344 module_init, module_destroy, "state");
1345
1346/* Change the places where stats are called (create/read/write stats)
1347
1348 Check for options in batchtest.c to reduce writing and see what tests are
1349 best candidates for performance analysis. Once OK, commit, move to main
1350 and run tests. Update the gui for statistics. */
This page took 0.025768 seconds and 4 git commands to generate.