convert from svn repository: remove tags directory
[lttv.git] / trunk / lttng-xenomai / LinuxTraceToolkitViewer-0.8.61-xenoltt / lttv / lttv / stats.c.bkp
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
36 GQuark
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 /***********************************************************/
57 LTTV_XENO_STATS_THREADS,
58 LTTV_XENO_STATS_THREAD_ADDRESS,
59 LTTV_XENO_STATS_THREAD_PERIOD,
60 LTTV_XENO_STATS_THREAD_PRIO,
61 LTTV_XENO_STATS_STATE,
62 LTTV_XENO_STATS_SYNCH,
63 LTTV_XENO_STATS_PERIOD,
64 LTTV_XENO_STATS_PERIOD_OVERRUNS,
65 LTTV_XENO_STATS_TEXT_OVERRUNS,
66 LTTV_XENO_STATS_TEXT_TICKS,
67 LTTV_XENO_STATS_TEXT_TOTAL,
68 LTTV_XENO_STATS_TEXT_OWNER,
69 LTTV_XENO_STATS_TEXT_WAITING,
70 LTTV_XENO_STATS_TEXT_OWNER_TOTAL,
71 LTTV_XENO_STATS_TEXT_OWNER_MAX,
72 LTTV_XENO_STATS_TEXT_OWNER_MIN,
73 LTTV_XENO_STATS_TEXT_OWNER_AVG,
74 LTTV_XENO_STATS_TEXT_WAITING,
75 LTTV_XENO_STATS_TEXT_WAITING_TOTAL,
76 LTTV_XENO_STATS_TEXT_WAITING_MAX,
77 LTTV_XENO_STATS_TEXT_WAITING_MIN,
78 LTTV_XENO_STATS_TEXT_WAITING_AVG,
79 LTTV_XENO_STATS_TEXT_READY_MAX,
80 LTTV_XENO_STATS_TEXT_READY_MIN,
81 LTTV_XENO_STATS_TEXT_READY_AVG,
82 LTTV_XENO_STATS_TEXT_RUNNING_MAX,
83 LTTV_XENO_STATS_TEXT_RUNNING_MIN,
84 LTTV_XENO_STATS_TEXT_RUNNING_AVG,
85 LTTV_XENO_STATS_TEXT_SUSPEND_MAX,
86 LTTV_XENO_STATS_TEXT_SUSPEND_MIN,
87 LTTV_XENO_STATS_TEXT_SUSPEND_AVG,
88 LTTV_XENO_STATS_NB_PERIOD;
89 /***********************************************************/
90
91 /****************************************************************************************************************************/
92 static void xeno_find_task_tree(LttvTracefileStats *tfcs, GQuark name, gulong address, guint cpu,
93 /*GQuark mode, GQuark sub_mode,*/ LttvAttribute **events_tree, LttvAttribute **event_types_tree);
94 gboolean xenoltt_thread_init(void *hook_data, void *call_data);
95 gboolean xenoltt_thread_set_period(void *hook_data, void *call_data);
96 gboolean xenoltt_thread_renice(void *hook_data, void *call_data);
97 gboolean xenoltt_before_change_state(void *hook_data, void *call_data);
98 gboolean xenoltt_after_change_state(void *hook_data, void *call_data);
99 gboolean xenoltt_thread_overruns(void *hook_data, void *call_data);
100 gboolean xenoltt_synch_owner(void *hook_data, void *call_data);
101 gboolean xenoltt_synch_wait(void *hook_data, void *call_data);
102 gboolean xenoltt_synch_unblock(void *hook_data, void *call_data);
103 gboolean xenoltt_synch_wakeup(void *hook_data, void *call_data);
104 gboolean xenoltt_synch_flush(void *hook_data, void *call_data);
105 /****************************************************************************************************************************/
106 static void
107 find_event_tree(LttvTracefileStats *tfcs, GQuark pid_time, guint cpu,
108 guint64 function,
109 GQuark mode, GQuark sub_mode, LttvAttribute **events_tree,
110 LttvAttribute **event_types_tree);
111
112
113 static void lttv_stats_init(LttvTracesetStats *self)
114 {
115 guint i, j, nb_trace, nb_tracefile;
116
117 LttvTraceContext *tc;
118
119 LttvTraceStats *tcs;
120
121 LttvTracefileContext *tfc;
122
123 LttvTracefileContext **tfs;
124 LttvTracefileStats *tfcs;
125
126 LttTime timestamp = {0,0};
127
128 LttvAttributeValue v;
129
130 LttvAttribute
131 *stats_tree,
132 *tracefiles_stats;
133
134 LttvTraceset *ts = self->parent.parent.ts;
135
136 self->stats = lttv_attribute_find_subdir(
137 lttv_traceset_attribute(self->parent.parent.ts),
138 LTTV_STATS);
139 lttv_attribute_find(lttv_traceset_attribute(self->parent.parent.ts),
140 LTTV_STATS_USE_COUNT,
141 LTTV_UINT, &v);
142
143 self->xenoltt_stats = lttv_attribute_find_subdir(
144 lttv_traceset_attribute(self->parent.parent.ts),
145 LTTV_STATS);
146
147 (*(v.v_uint))++;
148 if(*(v.v_uint) == 1) {
149 g_assert(lttv_attribute_get_number(self->stats) == 0);
150 }
151
152 nb_trace = lttv_traceset_number(ts);
153
154 for(i = 0 ; i < nb_trace ; i++) {
155 tc = self->parent.parent.traces[i];
156 tcs = LTTV_TRACE_STATS(tc);
157
158 tcs->stats = lttv_attribute_find_subdir(tcs->parent.parent.t_a,LTTV_STATS);
159
160 tcs->xenoltt_stats = lttv_attribute_find_subdir(tcs->parent.parent.t_a,LTTV_STATS);
161
162 tracefiles_stats = lttv_attribute_find_subdir(tcs->parent.parent.t_a,
163 LTTV_STATS_TRACEFILES);
164 lttv_attribute_find(tcs->parent.parent.t_a, LTTV_STATS_USE_COUNT,
165 LTTV_UINT, &v);
166
167 (*(v.v_uint))++;
168 if(*(v.v_uint) == 1) {
169 g_assert(lttv_attribute_get_number(tcs->stats) == 0);
170 }
171
172 nb_tracefile = tc->tracefiles->len;
173
174 for(j = 0 ; j < nb_tracefile ; j++) {
175 tfs = &g_array_index(tc->tracefiles,
176 LttvTracefileContext*, j);
177 tfcs = LTTV_TRACEFILE_STATS(*tfs);
178 tfcs->stats = lttv_attribute_find_subdir(tracefiles_stats,
179 ltt_tracefile_long_name(tfcs->parent.parent.tf));
180 guint cpu = tfcs->parent.cpu;
181 find_event_tree(tfcs, LTTV_STATS_PROCESS_UNKNOWN,
182 cpu,
183 0x0ULL,
184 LTTV_STATE_MODE_UNKNOWN,
185 LTTV_STATE_SUBMODE_UNKNOWN, &tfcs->current_events_tree,
186 &tfcs->current_event_types_tree);
187 }
188 }
189 }
190
191 static void lttv_stats_fini(LttvTracesetStats *self)
192 {
193 guint i, j, nb_trace, nb_tracefile;
194
195 LttvTraceset *ts;
196
197 LttvTraceContext *tc;
198
199 LttvTraceStats *tcs;
200
201 LttvTracefileContext *tfc;
202
203 LttvTracefileStats *tfcs;
204
205 LttTime timestamp = {0,0};
206
207 LttvAttributeValue v;
208
209 LttvAttribute *tracefiles_stats;
210
211 lttv_attribute_find(self->parent.parent.ts_a, LTTV_STATS_USE_COUNT,
212 LTTV_UINT, &v);
213 (*(v.v_uint))--;
214
215 if(*(v.v_uint) == 0) {
216 lttv_attribute_remove_by_name(self->parent.parent.ts_a, LTTV_STATS);
217 }
218 self->stats = NULL;
219
220 ts = self->parent.parent.ts;
221 nb_trace = lttv_traceset_number(ts);
222
223 for(i = 0 ; i < nb_trace ; i++) {
224 tcs = (LttvTraceStats *)(tc = (LTTV_TRACESET_CONTEXT(self)->traces[i]));
225
226 lttv_attribute_find(tcs->parent.parent.t_a, LTTV_STATS_USE_COUNT,
227 LTTV_UINT, &v);
228 (*(v.v_uint))--;
229
230 if(*(v.v_uint) == 0) {
231 lttv_attribute_remove_by_name(tcs->parent.parent.t_a,LTTV_STATS);
232 tracefiles_stats = lttv_attribute_find_subdir(tcs->parent.parent.t_a,
233 LTTV_STATS_TRACEFILES);
234 lttv_attribute_remove_by_name(tcs->parent.parent.t_a,
235 LTTV_STATS_TRACEFILES);
236 }
237 tcs->stats = NULL;
238
239 nb_tracefile = tc->tracefiles->len;
240
241 for(j = 0 ; j < nb_tracefile ; j++) {
242 tfc = g_array_index(tc->tracefiles,
243 LttvTracefileContext*, j);
244 tfcs = (LttvTracefileStats *)tfc;
245 tfcs->stats = NULL;
246 tfcs->current_events_tree = NULL;
247 tfcs->current_event_types_tree = NULL;
248 }
249 }
250 }
251
252
253 void lttv_stats_reset(LttvTracesetStats *self)
254 {
255 lttv_stats_fini(self);
256 lttv_stats_init(self);
257 }
258
259
260
261 static void
262 init(LttvTracesetStats *self, LttvTraceset *ts)
263 {
264 LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))->
265 init((LttvTracesetContext *)self, ts);
266
267 lttv_stats_init(self);
268 }
269
270
271 static void
272 fini(LttvTracesetStats *self)
273 {
274 lttv_stats_fini(self);
275
276 LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))->
277 fini((LttvTracesetContext *)self);
278 }
279
280
281 static LttvTracesetContext *
282 new_traceset_context(LttvTracesetContext *self)
283 {
284 return LTTV_TRACESET_CONTEXT(g_object_new(LTTV_TRACESET_STATS_TYPE, NULL));
285 }
286
287
288 static LttvTraceContext *
289 new_trace_context(LttvTracesetContext *self)
290 {
291 return LTTV_TRACE_CONTEXT(g_object_new(LTTV_TRACE_STATS_TYPE, NULL));
292 }
293
294
295 static LttvTracefileContext *
296 new_tracefile_context(LttvTracesetContext *self)
297 {
298 return LTTV_TRACEFILE_CONTEXT(g_object_new(LTTV_TRACEFILE_STATS_TYPE, NULL));
299 }
300
301
302 static void
303 traceset_stats_instance_init (GTypeInstance *instance, gpointer g_class)
304 {
305 }
306
307
308 static void
309 traceset_stats_finalize (LttvTracesetStats *self)
310 {
311 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))->
312 finalize(G_OBJECT(self));
313 }
314
315
316 static void
317 traceset_stats_class_init (LttvTracesetContextClass *klass)
318 {
319 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
320
321 gobject_class->finalize = (void (*)(GObject *self)) traceset_stats_finalize;
322 klass->init = (void (*)(LttvTracesetContext *self, LttvTraceset *ts))init;
323 klass->fini = (void (*)(LttvTracesetContext *self))fini;
324 klass->new_traceset_context = new_traceset_context;
325 klass->new_trace_context = new_trace_context;
326 klass->new_tracefile_context = new_tracefile_context;
327 }
328
329
330 GType
331 lttv_traceset_stats_get_type(void)
332 {
333 static GType type = 0;
334 if (type == 0) {
335 static const GTypeInfo info = {
336 sizeof (LttvTracesetStatsClass),
337 NULL, /* base_init */
338 NULL, /* base_finalize */
339 (GClassInitFunc) traceset_stats_class_init, /* class_init */
340 NULL, /* class_finalize */
341 NULL, /* class_data */
342 sizeof (LttvTracesetStats),
343 0, /* n_preallocs */
344 (GInstanceInitFunc) traceset_stats_instance_init, /* instance_init */
345 NULL /* Value handling */
346 };
347
348 type = g_type_register_static (LTTV_TRACESET_STATE_TYPE,
349 "LttvTracesetStatsType",
350 &info, 0);
351 }
352 return type;
353 }
354
355
356 static void
357 trace_stats_instance_init (GTypeInstance *instance, gpointer g_class)
358 {
359 }
360
361
362 static void
363 trace_stats_finalize (LttvTraceStats *self)
364 {
365 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACE_STATE_TYPE))->
366 finalize(G_OBJECT(self));
367 }
368
369
370 static void
371 trace_stats_class_init (LttvTraceContextClass *klass)
372 {
373 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
374
375 gobject_class->finalize = (void (*)(GObject *self)) trace_stats_finalize;
376 }
377
378
379 GType
380 lttv_trace_stats_get_type(void)
381 {
382 static GType type = 0;
383 if (type == 0) {
384 static const GTypeInfo info = {
385 sizeof (LttvTraceStatsClass),
386 NULL, /* base_init */
387 NULL, /* base_finalize */
388 (GClassInitFunc) trace_stats_class_init, /* class_init */
389 NULL, /* class_finalize */
390 NULL, /* class_data */
391 sizeof (LttvTraceStats),
392 0, /* n_preallocs */
393 (GInstanceInitFunc) trace_stats_instance_init, /* instance_init */
394 NULL /* Value handling */
395 };
396
397 type = g_type_register_static (LTTV_TRACE_STATE_TYPE,
398 "LttvTraceStatsType", &info, 0);
399 }
400 return type;
401 }
402
403
404 static void
405 tracefile_stats_instance_init (GTypeInstance *instance, gpointer g_class)
406 {
407 }
408
409
410 static void
411 tracefile_stats_finalize (LttvTracefileStats *self)
412 {
413 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACEFILE_STATE_TYPE))->
414 finalize(G_OBJECT(self));
415 }
416
417
418 static void
419 tracefile_stats_class_init (LttvTracefileStatsClass *klass)
420 {
421 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
422
423 gobject_class->finalize = (void (*)(GObject *self)) tracefile_stats_finalize;
424 }
425
426
427 GType
428 lttv_tracefile_stats_get_type(void)
429 {
430 static GType type = 0;
431 if (type == 0) {
432 static const GTypeInfo info = {
433 sizeof (LttvTracefileStatsClass),
434 NULL, /* base_init */
435 NULL, /* base_finalize */
436 (GClassInitFunc) tracefile_stats_class_init, /* class_init */
437 NULL, /* class_finalize */
438 NULL, /* class_data */
439 sizeof (LttvTracefileStats),
440 0, /* n_preallocs */
441 (GInstanceInitFunc) tracefile_stats_instance_init, /* instance_init */
442 NULL /* Value handling */
443 };
444
445 type = g_type_register_static (LTTV_TRACEFILE_STATE_TYPE,
446 "LttvTracefileStatsType", &info, 0);
447 }
448 return type;
449 }
450
451
452 static void
453 find_event_tree(LttvTracefileStats *tfcs,
454 GQuark pid_time,
455 guint cpu,
456 guint64 function,
457 GQuark mode,
458 GQuark sub_mode,
459 LttvAttribute **events_tree,
460 LttvAttribute **event_types_tree)
461 {
462 LttvAttribute *a, *prev_a;
463 gchar fstring[MAX_64_HEX_STRING_LEN];
464 gint ret;
465
466 ret = snprintf(fstring, MAX_64_HEX_STRING_LEN-1,
467 "0x%llX", function) > 0;
468 g_assert(ret > 0);
469 fstring[MAX_64_HEX_STRING_LEN-1] = '\0';
470
471 LttvTraceStats *tcs = (LttvTraceStats*)tfcs->parent.parent.t_context;
472 a = lttv_attribute_find_subdir(tcs->stats, LTTV_STATS_PROCESSES);
473 a = lttv_attribute_find_subdir(a, pid_time);
474 a = lttv_attribute_find_subdir(a, LTTV_STATS_CPU);
475 a = lttv_attribute_find_subdir_unnamed(a, cpu);
476 a = lttv_attribute_find_subdir(a, LTTV_STATS_FUNCTIONS);
477 a = lttv_attribute_find_subdir(a, g_quark_from_string(fstring));
478 a = lttv_attribute_find_subdir(a, LTTV_STATS_MODE_TYPES);
479 a = lttv_attribute_find_subdir(a, mode);
480 a = lttv_attribute_find_subdir(a, LTTV_STATS_SUBMODES);
481 a = lttv_attribute_find_subdir(a, sub_mode);
482 *events_tree = a;
483 a = lttv_attribute_find_subdir(a, LTTV_STATS_EVENT_TYPES);
484 *event_types_tree = a;
485 }
486
487
488 static void update_event_tree(LttvTracefileStats *tfcs)
489 {
490 LttvTraceState *ts = (LttvTraceState *)tfcs->parent.parent.t_context;
491 guint cpu = tfcs->parent.cpu;
492 LttvProcessState *process = ts->running_process[cpu];
493 LttvExecutionState *es = process->state;
494
495 find_event_tree(tfcs, process->pid_time,
496 cpu,
497 process->current_function,
498 es->t, es->n, &(tfcs->current_events_tree),
499 &(tfcs->current_event_types_tree));
500 }
501
502
503 static void mode_change(LttvTracefileStats *tfcs)
504 {
505 LttvTraceState *ts = (LttvTraceState *)tfcs->parent.parent.t_context;
506 guint cpu = tfcs->parent.cpu;
507 LttvProcessState *process = ts->running_process[cpu];
508 LttvAttributeValue cpu_time, cum_cpu_time;
509
510 LttTime delta;
511
512 delta = ltt_time_sub(tfcs->parent.parent.timestamp,
513 process->state->change);
514
515 lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CPU_TIME,
516 LTTV_TIME, &cpu_time);
517 *(cpu_time.v_time) = ltt_time_add(*(cpu_time.v_time), delta);
518
519 process->state->cum_cpu_time = ltt_time_add(process->state->cum_cpu_time,
520 delta);
521 }
522
523 /* Note : every mode_end must come with a cumulative cpu time update in the
524 * after hook */
525 static void mode_end(LttvTracefileStats *tfcs)
526 {
527 LttvTraceState *ts = (LttvTraceState *)tfcs->parent.parent.t_context;
528 guint cpu = tfcs->parent.cpu;
529 LttvProcessState *process = ts->running_process[cpu];
530 LttvAttributeValue elapsed_time, cpu_time, cum_cpu_time;
531
532 LttTime delta;
533
534 lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_ELAPSED_TIME,
535 LTTV_TIME, &elapsed_time);
536 delta = ltt_time_sub(tfcs->parent.parent.timestamp,
537 process->state->entry);
538 *(elapsed_time.v_time) = ltt_time_add(*(elapsed_time.v_time), delta);
539
540 lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CPU_TIME,
541 LTTV_TIME, &cpu_time);
542 delta = ltt_time_sub(tfcs->parent.parent.timestamp,
543 process->state->change);
544 *(cpu_time.v_time) = ltt_time_add(*(cpu_time.v_time), delta);
545 process->state->cum_cpu_time = ltt_time_add(process->state->cum_cpu_time,
546 delta);
547
548 lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CUMULATIVE_CPU_TIME,
549 LTTV_TIME, &cum_cpu_time);
550 *(cum_cpu_time.v_time) = ltt_time_add(*(cum_cpu_time.v_time),
551 process->state->cum_cpu_time);
552 }
553
554
555 static void after_mode_end(LttvTracefileStats *tfcs)
556 {
557 LttvTraceState *ts = (LttvTraceState *)tfcs->parent.parent.t_context;
558 guint cpu = tfcs->parent.cpu;
559 LttvProcessState *process = ts->running_process[cpu];
560 LttvAttributeValue cum_cpu_time;
561
562 LttTime nested_delta;
563
564 nested_delta = process->state->cum_cpu_time;
565 process->state->cum_cpu_time = ltt_time_zero; /* For after traceset hook */
566
567 update_event_tree(tfcs);
568
569 process->state->cum_cpu_time = ltt_time_add(process->state->cum_cpu_time,
570 nested_delta);
571 }
572
573 static gboolean before_syscall_entry(void *hook_data, void *call_data)
574 {
575 mode_change((LttvTracefileStats *)call_data);
576 return FALSE;
577 }
578
579
580 static gboolean after_syscall_entry(void *hook_data, void *call_data)
581 {
582 update_event_tree((LttvTracefileStats *)call_data);
583 return FALSE;
584 }
585
586
587 gboolean before_syscall_exit(void *hook_data, void *call_data)
588 {
589 mode_end((LttvTracefileStats *)call_data);
590 return FALSE;
591 }
592
593
594 static gboolean after_syscall_exit(void *hook_data, void *call_data)
595 {
596 after_mode_end((LttvTracefileStats *)call_data);
597 return FALSE;
598 }
599
600
601 gboolean before_trap_entry(void *hook_data, void *call_data)
602 {
603 mode_change((LttvTracefileStats *)call_data);
604 return FALSE;
605 }
606
607
608 static gboolean after_trap_entry(void *hook_data, void *call_data)
609 {
610 update_event_tree((LttvTracefileStats *)call_data);
611 return FALSE;
612 }
613
614
615 gboolean before_trap_exit(void *hook_data, void *call_data)
616 {
617 mode_end((LttvTracefileStats *)call_data);
618 return FALSE;
619 }
620
621
622 gboolean after_trap_exit(void *hook_data, void *call_data)
623 {
624 after_mode_end((LttvTracefileStats *)call_data);
625 return FALSE;
626 }
627
628
629 gboolean before_irq_entry(void *hook_data, void *call_data)
630 {
631 mode_change((LttvTracefileStats *)call_data);
632 return FALSE;
633 }
634
635 gboolean after_irq_entry(void *hook_data, void *call_data)
636 {
637 update_event_tree((LttvTracefileStats *)call_data);
638 return FALSE;
639 }
640
641
642 gboolean before_irq_exit(void *hook_data, void *call_data)
643 {
644 mode_end((LttvTracefileStats *)call_data);
645 return FALSE;
646 }
647
648
649 gboolean after_irq_exit(void *hook_data, void *call_data)
650 {
651 after_mode_end((LttvTracefileStats *)call_data);
652 return FALSE;
653 }
654
655
656 gboolean before_soft_irq_entry(void *hook_data, void *call_data)
657 {
658 mode_change((LttvTracefileStats *)call_data);
659 return FALSE;
660 }
661
662 gboolean after_soft_irq_entry(void *hook_data, void *call_data)
663 {
664 update_event_tree((LttvTracefileStats *)call_data);
665 return FALSE;
666 }
667
668
669 gboolean before_soft_irq_exit(void *hook_data, void *call_data)
670 {
671 mode_end((LttvTracefileStats *)call_data);
672 return FALSE;
673 }
674
675
676 gboolean after_soft_irq_exit(void *hook_data, void *call_data)
677 {
678 after_mode_end((LttvTracefileStats *)call_data);
679 return FALSE;
680 }
681
682 gboolean before_function_entry(void *hook_data, void *call_data)
683 {
684 mode_change((LttvTracefileStats *)call_data);
685 return FALSE;
686 }
687
688 gboolean after_function_entry(void *hook_data, void *call_data)
689 {
690 update_event_tree((LttvTracefileStats *)call_data);
691 return FALSE;
692 }
693
694 gboolean before_function_exit(void *hook_data, void *call_data)
695 {
696 mode_end((LttvTracefileStats *)call_data);
697 return FALSE;
698 }
699
700 gboolean after_function_exit(void *hook_data, void *call_data)
701 {
702 after_mode_end((LttvTracefileStats *)call_data);
703 return FALSE;
704 }
705
706
707 gboolean before_schedchange(void *hook_data, void *call_data)
708 {
709 LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
710
711 LttvTraceState *ts = (LttvTraceState*)tfcs->parent.parent.t_context;
712
713 LttEvent *e = ltt_tracefile_get_event(tfcs->parent.parent.tf);
714
715 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
716
717 guint pid_in, pid_out;
718
719 gint state_out;
720
721 pid_out = ltt_event_get_unsigned(e, thf->f1);
722 pid_in = ltt_event_get_unsigned(e, thf->f2);
723 state_out = ltt_event_get_int(e, thf->f3);
724
725 /* compute the time for the process to schedule out */
726
727 mode_change(tfcs);
728
729 return FALSE;
730 }
731
732 gboolean after_schedchange(void *hook_data, void *call_data)
733 {
734 LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
735
736 LttvTraceState *ts = (LttvTraceState*)tfcs->parent.parent.t_context;
737
738 LttEvent *e = ltt_tracefile_get_event(tfcs->parent.parent.tf);
739
740 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
741
742 guint pid_in, pid_out;
743
744 gint state_out;
745
746 LttvProcessState *process;
747
748 pid_out = ltt_event_get_unsigned(e, thf->f1);
749 pid_in = ltt_event_get_unsigned(e, thf->f2);
750 state_out = ltt_event_get_int(e, thf->f3);
751
752 /* get the information for the process scheduled in */
753 guint cpu = tfcs->parent.cpu;
754 process = ts->running_process[cpu];
755
756 find_event_tree(tfcs, process->pid_time,
757 cpu,
758 process->current_function,
759 process->state->t, process->state->n, &(tfcs->current_events_tree),
760 &(tfcs->current_event_types_tree));
761
762 /* compute the time waiting for the process to schedule in */
763 mode_change(tfcs);
764
765 return FALSE;
766 }
767
768 gboolean process_fork(void *hook_data, void *call_data)
769 {
770 /* nothing to do for now */
771 return FALSE;
772 }
773
774
775 gboolean process_exit(void *hook_data, void *call_data)
776 {
777 /* We should probably exit all modes here or we could do that at
778 schedule out. */
779 return FALSE;
780 }
781
782 gboolean before_enum_process_state(void *hook_data, void *call_data)
783 {
784 mode_end((LttvTracefileStats *)call_data);
785 after_mode_end((LttvTracefileStats *)call_data);
786 mode_change((LttvTracefileStats *)call_data);
787 return FALSE;
788 }
789
790 gboolean after_enum_process_state(void *hook_data, void *call_data)
791 {
792 update_event_tree((LttvTracefileStats *)call_data);
793 return FALSE;
794 }
795
796 gboolean process_free(void *hook_data, void *call_data)
797 {
798 return FALSE;
799 }
800
801 gboolean every_event(void *hook_data, void *call_data)
802 {
803 LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
804
805 LttEvent *e = ltt_tracefile_get_event(tfcs->parent.parent.tf);
806
807 LttvAttributeValue v;
808
809 /* The current branch corresponds to the tracefile/process/interrupt state.
810 Statistics are added within it, to count the number of events of this
811 type occuring in this context. A quark has been pre-allocated for each
812 event type and is used as name. */
813
814 lttv_attribute_find(tfcs->current_event_types_tree,
815 ltt_eventtype_name(ltt_event_eventtype(e)),
816 LTTV_UINT, &v);
817 (*(v.v_uint))++;
818 return FALSE;
819 }
820
821 static void lttv_stats_cleanup_process_state(gpointer key, gpointer value,
822 gpointer user_data)
823 {
824 LttvTraceStats *tcs = (LttvTraceStats *)user_data;
825 LttvTraceState *ts = (LttvTraceState *)user_data;
826 LttvTracesetContext *tsc = ts->parent.ts_context;
827 LttvProcessState *process = (LttvProcessState *)value;
828 int i;
829 LttvTracefileStats **tfs = (LttvTracefileStats **)
830 &g_array_index(ts->parent.tracefiles, LttvTracefileContext*,
831 process->cpu);
832 int cleanup_empty = 0;
833 LttTime nested_delta = ltt_time_zero;
834 /* FIXME : ok, this is a hack. The time is infinite here :( */
835 LttTime save_time = (*tfs)->parent.parent.timestamp;
836 LttTime start, end;
837 ltt_trace_time_span_get(ts->parent.t, &start, &end);
838 (*tfs)->parent.parent.timestamp = end;
839
840 do {
841 if(ltt_time_compare(process->state->cum_cpu_time, ltt_time_zero) != 0) {
842 find_event_tree(*tfs, process->pid_time,
843 process->cpu,
844 process->current_function,
845 process->state->t, process->state->n, &((*tfs)->current_events_tree),
846 &((*tfs)->current_event_types_tree));
847 mode_end(*tfs);
848 nested_delta = process->state->cum_cpu_time;
849 }
850 cleanup_empty = lttv_state_pop_state_cleanup(process,
851 (LttvTracefileState *)*tfs);
852 process->state->cum_cpu_time = ltt_time_add(process->state->cum_cpu_time,
853 nested_delta);
854
855 } while(cleanup_empty != 1);
856
857 (*tfs)->parent.parent.timestamp = save_time;
858 }
859
860 /* For each process in the state, for each of their stacked states,
861 * perform sum of needed values. */
862 static void lttv_stats_cleanup_state(LttvTraceStats *tcs)
863 {
864 LttvTraceState *ts = (LttvTraceState *)tcs;
865
866 /* Does not work correctly FIXME. */
867 g_hash_table_foreach(ts->processes, lttv_stats_cleanup_process_state,
868 tcs);
869 }
870
871 void
872 lttv_stats_sum_trace(LttvTraceStats *self, LttvAttribute *ts_stats)
873 {
874 LttvAttribute *sum_container = self->stats;
875
876 LttvAttributeType type;
877
878 LttvAttributeValue value;
879
880 LttvAttributeName name;
881
882 gboolean is_named;
883
884 unsigned sum;
885
886 int trace_is_summed;
887
888 int i, j, k, l, m, nb_process, nb_cpu, nb_mode_type, nb_submode,
889 nb_event_type, nf, nb_functions;
890
891 LttvAttribute *main_tree, *processes_tree, *process_tree, *cpus_tree,
892 *cpu_tree, *mode_tree, *mode_types_tree, *submodes_tree,
893 *submode_tree, *event_types_tree, *mode_events_tree,
894 *cpu_functions_tree,
895 *function_tree,
896 *function_mode_types_tree,
897 *trace_cpu_tree;
898
899
900 main_tree = sum_container;
901
902 lttv_attribute_find(sum_container,
903 LTTV_STATS_SUMMED,
904 LTTV_UINT, &value);
905 trace_is_summed = *(value.v_uint);
906 *(value.v_uint) = 1;
907
908 /* First cleanup the state : sum all stalled information (never ending
909 * states). */
910 if(!trace_is_summed)
911 lttv_stats_cleanup_state(self);
912
913 processes_tree = lttv_attribute_find_subdir(main_tree,
914 LTTV_STATS_PROCESSES);
915 nb_process = lttv_attribute_get_number(processes_tree);
916
917 for(i = 0 ; i < nb_process ; i++) {
918 type = lttv_attribute_get(processes_tree, i, &name, &value, &is_named);
919 process_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
920
921 cpus_tree = lttv_attribute_find_subdir(process_tree, LTTV_STATS_CPU);
922 nb_cpu = lttv_attribute_get_number(cpus_tree);
923
924 for(j = 0 ; j < nb_cpu ; j++) {
925 type = lttv_attribute_get(cpus_tree, j, &name, &value, &is_named);
926 cpu_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
927
928 trace_cpu_tree = lttv_attribute_find_subdir(main_tree, LTTV_STATS_CPU);
929 trace_cpu_tree = lttv_attribute_find_subdir_unnamed(trace_cpu_tree, name);
930 cpu_functions_tree = lttv_attribute_find_subdir(cpu_tree,
931 LTTV_STATS_FUNCTIONS);
932 nb_functions = lttv_attribute_get_number(cpu_functions_tree);
933
934 for(nf=0; nf < nb_functions; nf++) {
935 type = lttv_attribute_get(cpu_functions_tree, nf, &name, &value,
936 &is_named);
937 function_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
938 function_mode_types_tree = lttv_attribute_find_subdir(function_tree,
939 LTTV_STATS_MODE_TYPES);
940 nb_mode_type = lttv_attribute_get_number(function_mode_types_tree);
941 for(k = 0 ; k < nb_mode_type ; k++) {
942 type = lttv_attribute_get(function_mode_types_tree, k, &name, &value,
943 &is_named);
944 mode_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
945
946 submodes_tree = lttv_attribute_find_subdir(mode_tree,
947 LTTV_STATS_SUBMODES);
948 mode_events_tree = lttv_attribute_find_subdir(mode_tree,
949 LTTV_STATS_EVENTS);
950 mode_types_tree = lttv_attribute_find_subdir(mode_tree,
951 LTTV_STATS_MODE_TYPES);
952
953 nb_submode = lttv_attribute_get_number(submodes_tree);
954
955 for(l = 0 ; l < nb_submode ; l++) {
956 type = lttv_attribute_get(submodes_tree, l, &name, &value,
957 &is_named);
958 submode_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
959
960 event_types_tree = lttv_attribute_find_subdir(submode_tree,
961 LTTV_STATS_EVENT_TYPES);
962 nb_event_type = lttv_attribute_get_number(event_types_tree);
963
964 sum = 0;
965 for(m = 0 ; m < nb_event_type ; m++) {
966 type = lttv_attribute_get(event_types_tree, m, &name, &value,
967 &is_named);
968 sum += *(value.v_uint);
969 }
970 lttv_attribute_find(submode_tree, LTTV_STATS_EVENTS_COUNT,
971 LTTV_UINT, &value);
972 *(value.v_uint) = sum;
973
974 type = lttv_attribute_get(submodes_tree, l, &name, &value,
975 &is_named);
976 submode_tree = LTTV_ATTRIBUTE(*(value.v_gobject));
977 if(!trace_is_summed) {
978 lttv_attribute_recursive_add(mode_events_tree, event_types_tree);
979 lttv_attribute_recursive_add(mode_types_tree, submode_tree);
980 }
981 }
982 if(!trace_is_summed) {
983 lttv_attribute_recursive_add(function_tree, mode_types_tree);
984 }
985 }
986 if(!trace_is_summed) {
987 lttv_attribute_recursive_add(cpu_tree, function_tree);
988 lttv_attribute_recursive_add(process_tree, function_tree);
989 lttv_attribute_recursive_add(trace_cpu_tree, function_tree);
990 lttv_attribute_recursive_add(main_tree, function_tree);
991 }
992 lttv_attribute_recursive_add(ts_stats, function_tree);
993 }
994 }
995 }
996 }
997
998
999 gboolean lttv_stats_sum_traceset_hook(void *hook_data, void *call_data)
1000 {
1001 lttv_stats_sum_traceset((LttvTracesetStats *)call_data);
1002 return 0;
1003 }
1004
1005 void
1006 lttv_stats_sum_traceset(LttvTracesetStats *self)
1007 {
1008 LttvTraceset *traceset = self->parent.parent.ts;
1009 LttvAttribute *sum_container = self->stats;
1010
1011 LttvTraceStats *tcs;
1012
1013 int i, nb_trace;
1014
1015 LttvAttribute *main_tree;
1016
1017 LttvAttributeValue value;
1018
1019 lttv_attribute_find(sum_container, LTTV_STATS_SUMMED,
1020 LTTV_UINT, &value);
1021 if(*(value.v_uint) != 0) return;
1022 *(value.v_uint) = 1;
1023
1024 nb_trace = lttv_traceset_number(traceset);
1025
1026 for(i = 0 ; i < nb_trace ; i++) {
1027 tcs = (LttvTraceStats *)(self->parent.parent.traces[i]);
1028 lttv_stats_sum_trace(tcs, self->stats);
1029 // lttv_attribute_recursive_add(sum_container, tcs->stats);
1030 }
1031 }
1032
1033
1034 // Hook wrapper. call_data is a traceset context.
1035 gboolean lttv_stats_hook_add_event_hooks(void *hook_data, void *call_data)
1036 {
1037 LttvTracesetStats *tss = (LttvTracesetStats*)call_data;
1038
1039 lttv_stats_add_event_hooks(tss);
1040
1041 return 0;
1042 }
1043
1044 void lttv_stats_add_event_hooks(LttvTracesetStats *self)
1045 {
1046 LttvTraceset *traceset = self->parent.parent.ts;
1047
1048 guint i, j, k, l, nb_trace, nb_tracefile;
1049
1050 LttvTraceStats *ts;
1051
1052 LttvTracefileStats *tfs;
1053
1054 GArray *hooks, *before_hooks, *after_hooks;
1055
1056 LttvTraceHook *hook;
1057
1058 LttvTraceHookByFacility *thf;
1059
1060 LttvAttributeValue val;
1061
1062 gint ret;
1063 gint hn;
1064
1065 nb_trace = lttv_traceset_number(traceset);
1066 for(i = 0 ; i < nb_trace ; i++) {
1067 ts = (LttvTraceStats *)self->parent.parent.traces[i];
1068
1069 /* Find the eventtype id for the following events and register the
1070 associated by id hooks. */
1071
1072 hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 16);
1073 g_array_set_size(hooks, 16);
1074 hn=0;
1075
1076 ret = lttv_trace_find_hook(ts->parent.parent.t,
1077 LTT_FACILITY_KERNEL_ARCH, LTT_EVENT_SYSCALL_ENTRY,
1078 LTT_FIELD_SYSCALL_ID, 0, 0,
1079 before_syscall_entry, NULL,
1080 &g_array_index(hooks, LttvTraceHook, hn++));
1081 if(ret) hn--;
1082
1083 ret = lttv_trace_find_hook(ts->parent.parent.t,
1084 LTT_FACILITY_KERNEL_ARCH, LTT_EVENT_SYSCALL_EXIT,
1085 0, 0, 0,
1086 before_syscall_exit, NULL,
1087 &g_array_index(hooks, LttvTraceHook, hn++));
1088 if(ret) hn--;
1089
1090 ret = lttv_trace_find_hook(ts->parent.parent.t,
1091 LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_ENTRY,
1092 LTT_FIELD_TRAP_ID, 0, 0,
1093 before_trap_entry, NULL,
1094 &g_array_index(hooks, LttvTraceHook, hn++));
1095 if(ret) hn--;
1096
1097 ret = lttv_trace_find_hook(ts->parent.parent.t,
1098 LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_EXIT,
1099 0, 0, 0,
1100 before_trap_exit, NULL,
1101 &g_array_index(hooks, LttvTraceHook, hn++));
1102 if(ret) hn--;
1103
1104 ret = lttv_trace_find_hook(ts->parent.parent.t,
1105 LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_ENTRY,
1106 LTT_FIELD_IRQ_ID, 0, 0,
1107 before_irq_entry, NULL,
1108 &g_array_index(hooks, LttvTraceHook, hn++));
1109 if(ret) hn--;
1110
1111 ret = lttv_trace_find_hook(ts->parent.parent.t,
1112 LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_EXIT,
1113 0, 0, 0,
1114 before_irq_exit, NULL,
1115 &g_array_index(hooks, LttvTraceHook, hn++));
1116 if(ret) hn--;
1117
1118 ret = lttv_trace_find_hook(ts->parent.parent.t,
1119 LTT_FACILITY_KERNEL, LTT_EVENT_SOFT_IRQ_ENTRY,
1120 LTT_FIELD_SOFT_IRQ_ID, 0, 0,
1121 before_soft_irq_entry, NULL,
1122 &g_array_index(hooks, LttvTraceHook, hn++));
1123 if(ret) hn--;
1124
1125 ret = lttv_trace_find_hook(ts->parent.parent.t,
1126 LTT_FACILITY_KERNEL, LTT_EVENT_SOFT_IRQ_EXIT,
1127 0, 0, 0,
1128 before_soft_irq_exit, NULL,
1129 &g_array_index(hooks, LttvTraceHook, hn++));
1130 if(ret) hn--;
1131
1132 ret = lttv_trace_find_hook(ts->parent.parent.t,
1133 LTT_FACILITY_PROCESS, LTT_EVENT_SCHEDCHANGE,
1134 LTT_FIELD_OUT, LTT_FIELD_IN, LTT_FIELD_OUT_STATE,
1135 before_schedchange, NULL,
1136 &g_array_index(hooks, LttvTraceHook, hn++));
1137 if(ret) hn--;
1138
1139 ret = lttv_trace_find_hook(ts->parent.parent.t,
1140 LTT_FACILITY_USER_GENERIC, LTT_EVENT_FUNCTION_ENTRY,
1141 LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE, 0,
1142 before_function_entry, NULL,
1143 &g_array_index(hooks, LttvTraceHook, hn++));
1144 if(ret) hn--;
1145
1146 ret = lttv_trace_find_hook(ts->parent.parent.t,
1147 LTT_FACILITY_USER_GENERIC, LTT_EVENT_FUNCTION_EXIT,
1148 LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE, 0,
1149 before_function_exit, NULL,
1150 &g_array_index(hooks, LttvTraceHook, hn++));
1151 if(ret) hn--;
1152
1153 /* statedump-related hooks */
1154 ret = lttv_trace_find_hook(ts->parent.parent.t,
1155 LTT_FACILITY_STATEDUMP, LTT_EVENT_ENUM_PROCESS_STATE,
1156 LTT_FIELD_PID, LTT_FIELD_PARENT_PID, LTT_FIELD_NAME,
1157 before_enum_process_state, NULL,
1158 &g_array_index(hooks, LttvTraceHook, hn++));
1159 if(ret) hn--;
1160
1161 ret = lttv_trace_find_hook(ts->parent.parent.t,
1162 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_START,
1163 0, 0, 0,
1164 xenoltt_before_change_state, NULL,
1165 &g_array_index(hooks, LttvTraceHook, hn++));
1166 if(ret) hn--;
1167
1168 ret = lttv_trace_find_hook(ts->parent.parent.t,
1169 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_RESUME,
1170 0, 0, 0,
1171 xenoltt_before_change_state, NULL,
1172 &g_array_index(hooks, LttvTraceHook, hn++));
1173 if(ret) hn--;
1174
1175 ret = lttv_trace_find_hook(ts->parent.parent.t,
1176 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_WAIT_PERIOD,
1177 0, 0, 0,
1178 xenoltt_before_change_state, NULL,
1179 &g_array_index(hooks, LttvTraceHook, hn++));
1180 if(ret) hn--;
1181
1182 ret = lttv_trace_find_hook(ts->parent.parent.t,
1183 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_SUSPEND,
1184 0, 0, 0,
1185 xenoltt_before_change_state, NULL,
1186 &g_array_index(hooks, LttvTraceHook, hn++));
1187 if(ret) hn--;
1188
1189 ret = lttv_trace_find_hook(ts->parent.parent.t,
1190 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_SWITCH,
1191 0, 0, 0,
1192 xenoltt_before_change_state, NULL,
1193 &g_array_index(hooks, LttvTraceHook, hn++));
1194 if(ret) hn--;
1195
1196 ret = lttv_trace_find_hook(ts->parent.parent.t,
1197 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_SYNCH_UNLOCK,
1198 LTT_FIELD_XENOLTT_SYNCH, 0, 0,
1199 xenoltt_synch_unblock, NULL,
1200 &g_array_index(hooks, LttvTraceHook, hn++));
1201 if(ret) hn--;
1202
1203 g_array_set_size(hooks, hn);
1204
1205 before_hooks = hooks;
1206
1207 hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 24);
1208 g_array_set_size(hooks, 24);
1209 hn=0;
1210
1211 ret = lttv_trace_find_hook(ts->parent.parent.t,
1212 LTT_FACILITY_KERNEL_ARCH, LTT_EVENT_SYSCALL_ENTRY,
1213 LTT_FIELD_SYSCALL_ID, 0, 0,
1214 after_syscall_entry, NULL,
1215 &g_array_index(hooks, LttvTraceHook, hn++));
1216 if(ret) hn--;
1217
1218 ret = lttv_trace_find_hook(ts->parent.parent.t,
1219 LTT_FACILITY_KERNEL_ARCH, LTT_EVENT_SYSCALL_EXIT,
1220 0, 0, 0,
1221 after_syscall_exit, NULL,
1222 &g_array_index(hooks, LttvTraceHook, hn++));
1223 if(ret) hn--;
1224
1225 ret = lttv_trace_find_hook(ts->parent.parent.t,
1226 LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_ENTRY,
1227 LTT_FIELD_TRAP_ID, 0, 0,
1228 after_trap_entry, NULL,
1229 &g_array_index(hooks, LttvTraceHook, hn++));
1230 if(ret) hn--;
1231
1232 ret = lttv_trace_find_hook(ts->parent.parent.t,
1233 LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_EXIT,
1234 0, 0, 0,
1235 after_trap_exit, NULL,
1236 &g_array_index(hooks, LttvTraceHook, hn++));
1237 if(ret) hn--;
1238
1239 ret = lttv_trace_find_hook(ts->parent.parent.t,
1240 LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_ENTRY,
1241 LTT_FIELD_IRQ_ID, 0, 0,
1242 after_irq_entry, NULL,
1243 &g_array_index(hooks, LttvTraceHook, hn++));
1244 if(ret) hn--;
1245
1246 ret = lttv_trace_find_hook(ts->parent.parent.t,
1247 LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_EXIT,
1248 0, 0, 0,
1249 after_irq_exit, NULL,
1250 &g_array_index(hooks, LttvTraceHook, hn++));
1251 if(ret) hn--;
1252
1253 ret = lttv_trace_find_hook(ts->parent.parent.t,
1254 LTT_FACILITY_KERNEL, LTT_EVENT_SOFT_IRQ_ENTRY,
1255 LTT_FIELD_SOFT_IRQ_ID, 0, 0,
1256 after_irq_entry, NULL,
1257 &g_array_index(hooks, LttvTraceHook, hn++));
1258 if(ret) hn--;
1259
1260 ret = lttv_trace_find_hook(ts->parent.parent.t,
1261 LTT_FACILITY_KERNEL, LTT_EVENT_SOFT_IRQ_EXIT,
1262 0, 0, 0,
1263 after_soft_irq_exit, NULL,
1264 &g_array_index(hooks, LttvTraceHook, hn++));
1265 if(ret) hn--;
1266
1267 ret = lttv_trace_find_hook(ts->parent.parent.t,
1268 LTT_FACILITY_PROCESS, LTT_EVENT_SCHEDCHANGE,
1269 LTT_FIELD_OUT, LTT_FIELD_IN, LTT_FIELD_OUT_STATE,
1270 after_schedchange, NULL,
1271 &g_array_index(hooks, LttvTraceHook, hn++));
1272 if(ret) hn--;
1273
1274 ret = lttv_trace_find_hook(ts->parent.parent.t,
1275 LTT_FACILITY_PROCESS, LTT_EVENT_FORK,
1276 LTT_FIELD_PARENT_PID, LTT_FIELD_CHILD_PID, 0,
1277 process_fork, NULL,
1278 &g_array_index(hooks, LttvTraceHook, hn++));
1279 if(ret) hn--;
1280
1281 ret = lttv_trace_find_hook(ts->parent.parent.t,
1282 LTT_FACILITY_PROCESS, LTT_EVENT_EXIT,
1283 LTT_FIELD_PID, 0, 0,
1284 process_exit, NULL,
1285 &g_array_index(hooks, LttvTraceHook, hn++));
1286 if(ret) hn--;
1287
1288 ret = lttv_trace_find_hook(ts->parent.parent.t,
1289 LTT_FACILITY_PROCESS, LTT_EVENT_FREE,
1290 LTT_FIELD_PID, 0, 0,
1291 process_free, NULL,
1292 &g_array_index(hooks, LttvTraceHook, hn++));
1293 if(ret) hn--;
1294
1295 ret = lttv_trace_find_hook(ts->parent.parent.t,
1296 LTT_FACILITY_USER_GENERIC, LTT_EVENT_FUNCTION_ENTRY,
1297 LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE, 0,
1298 after_function_entry, NULL,
1299 &g_array_index(hooks, LttvTraceHook, hn++));
1300 if(ret) hn--;
1301
1302 ret = lttv_trace_find_hook(ts->parent.parent.t,
1303 LTT_FACILITY_USER_GENERIC, LTT_EVENT_FUNCTION_EXIT,
1304 LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE, 0,
1305 after_function_exit, NULL,
1306 &g_array_index(hooks, LttvTraceHook, hn++));
1307 if(ret) hn--;
1308
1309 /* statedump-related hooks */
1310 ret = lttv_trace_find_hook(ts->parent.parent.t,
1311 LTT_FACILITY_STATEDUMP, LTT_EVENT_ENUM_PROCESS_STATE,
1312 LTT_FIELD_PID, LTT_FIELD_PARENT_PID, LTT_FIELD_NAME,
1313 after_enum_process_state, NULL,
1314 &g_array_index(hooks, LttvTraceHook, hn++));
1315 if(ret) hn--;
1316
1317
1318 /* xenoltt-related hooks */
1319 ret = lttv_trace_find_hook(ts->parent.parent.t,
1320 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_INIT,
1321 LTT_FIELD_XENOLTT_NAME, 0, 0,
1322 xenoltt_thread_init, NULL,
1323 &g_array_index(hooks, LttvTraceHook, hn++));
1324 if(ret) hn--;
1325
1326 ret = lttv_trace_find_hook(ts->parent.parent.t,
1327 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_SET_PERIOD,
1328 0, 0, 0,
1329 xenoltt_thread_set_period, NULL,
1330 &g_array_index(hooks, LttvTraceHook, hn++));
1331 if(ret) hn--;
1332
1333 ret = lttv_trace_find_hook(ts->parent.parent.t,
1334 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_RENICE,
1335 0, 0, 0,
1336 xenoltt_thread_renice, NULL,
1337 &g_array_index(hooks, LttvTraceHook, hn++));
1338 if(ret) hn--;
1339
1340 ret = lttv_trace_find_hook(ts->parent.parent.t,
1341 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_MISSED_PERIOD,
1342 LTT_FIELD_XENOLTT_NAME, LTT_FIELD_XENOLTT_ADDRESS, LTT_FIELD_XENOLTT_OVERRUNS,
1343 xenoltt_thread_overruns, NULL,
1344 &g_array_index(hooks, LttvTraceHook, hn++));
1345 if(ret) hn--;
1346
1347 ret = lttv_trace_find_hook(ts->parent.parent.t,
1348 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_SYNCH_SET_OWNER,
1349 LTT_FIELD_XENOLTT_SYNCH, 0, 0,
1350 xenoltt_synch_owner, NULL,
1351 &g_array_index(hooks, LttvTraceHook, hn++));
1352 if(ret) hn--;
1353
1354 ret = lttv_trace_find_hook(ts->parent.parent.t,
1355 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_SYNCH_WAKEUPX,
1356 LTT_FIELD_XENOLTT_SYNCH, LTT_FIELD_XENOLTT_NAME, LTT_FIELD_XENOLTT_ADDRESS,
1357 xenoltt_synch_wakeup, NULL,
1358 &g_array_index(hooks, LttvTraceHook, hn++));
1359 if(ret) hn--;
1360
1361 ret = lttv_trace_find_hook(ts->parent.parent.t,
1362 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_SYNCH_WAKEUP1,
1363 LTT_FIELD_XENOLTT_SYNCH, LTT_FIELD_XENOLTT_NAME, LTT_FIELD_XENOLTT_ADDRESS,
1364 xenoltt_synch_wakeup, NULL,
1365 &g_array_index(hooks, LttvTraceHook, hn++));
1366 if(ret) hn--;
1367
1368 ret = lttv_trace_find_hook(ts->parent.parent.t,
1369 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_SYNCH_SLEEP_ON,
1370 LTT_FIELD_XENOLTT_SYNCH, LTT_FIELD_XENOLTT_NAME, LTT_FIELD_XENOLTT_ADDRESS,
1371 xenoltt_synch_wait, NULL,
1372 &g_array_index(hooks, LttvTraceHook, hn++));
1373 if(ret) hn--;
1374
1375 //SYNCH FLUSH
1376 ret = lttv_trace_find_hook(ts->parent.parent.t,
1377 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_SYNCH_FLUSH,
1378 LTT_FIELD_XENOLTT_SYNCH, 0, 0,
1379 xenoltt_synch_flush, NULL, &g_array_index(hooks, LttvTraceHook, hn++));
1380 if(ret) hn--;
1381
1382 //SYNCH FORGET
1383 ret = lttv_trace_find_hook(ts->parent.parent.t,
1384 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_SYNCH_FORGET,
1385 LTT_FIELD_XENOLTT_SYNCH, LTT_FIELD_XENOLTT_NAME, LTT_FIELD_XENOLTT_ADDRESS,
1386 xenoltt_synch_wakeup, NULL, &g_array_index(hooks, LttvTraceHook, hn++));
1387 if(ret) hn--;
1388
1389 ret = lttv_trace_find_hook(ts->parent.parent.t,
1390 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_START,
1391 0, 0, 0,
1392 xenoltt_after_change_state, NULL,
1393 &g_array_index(hooks, LttvTraceHook, hn++));
1394 if(ret) hn--;
1395
1396 ret = lttv_trace_find_hook(ts->parent.parent.t,
1397 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_RESUME,
1398 0, 0, 0,
1399 xenoltt_after_change_state, NULL,
1400 &g_array_index(hooks, LttvTraceHook, hn++));
1401 if(ret) hn--;
1402
1403 ret = lttv_trace_find_hook(ts->parent.parent.t,
1404 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_WAIT_PERIOD,
1405 0, 0, 0,
1406 xenoltt_after_change_state, NULL,
1407 &g_array_index(hooks, LttvTraceHook, hn++));
1408 if(ret) hn--;
1409
1410 ret = lttv_trace_find_hook(ts->parent.parent.t,
1411 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_SUSPEND,
1412 0, 0, 0,
1413 xenoltt_after_change_state, NULL,
1414 &g_array_index(hooks, LttvTraceHook, hn++));
1415 if(ret) hn--;
1416
1417 ret = lttv_trace_find_hook(ts->parent.parent.t,
1418 LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_SWITCH,
1419 0, 0, 0,
1420 xenoltt_after_change_state, NULL,
1421 &g_array_index(hooks, LttvTraceHook, hn++));
1422 if(ret) hn--;
1423
1424 g_array_set_size(hooks, hn);
1425
1426 after_hooks = hooks;
1427
1428 /* Add these hooks to each event_by_id hooks list */
1429
1430 nb_tracefile = ts->parent.parent.tracefiles->len;
1431
1432 for(j = 0 ; j < nb_tracefile ; j++) {
1433 tfs = LTTV_TRACEFILE_STATS(g_array_index(ts->parent.parent.tracefiles,
1434 LttvTracefileContext*, j));
1435 lttv_hooks_add(tfs->parent.parent.event, every_event, NULL,
1436 LTTV_PRIO_DEFAULT);
1437
1438 for(k = 0 ; k < before_hooks->len ; k++) {
1439 hook = &g_array_index(before_hooks, LttvTraceHook, k);
1440 for(l = 0; l<hook->fac_list->len;l++) {
1441 thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
1442 lttv_hooks_add(
1443 lttv_hooks_by_id_find(tfs->parent.parent.event_by_id, thf->id),
1444 thf->h,
1445 thf,
1446 LTTV_PRIO_STATS_BEFORE_STATE);
1447 }
1448 }
1449 for(k = 0 ; k < after_hooks->len ; k++) {
1450 hook = &g_array_index(after_hooks, LttvTraceHook, k);
1451 for(l = 0; l<hook->fac_list->len;l++) {
1452 thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
1453 lttv_hooks_add(
1454 lttv_hooks_by_id_find(tfs->parent.parent.event_by_id, thf->id),
1455 thf->h,
1456 thf,
1457 LTTV_PRIO_STATS_AFTER_STATE);
1458 }
1459 }
1460 }
1461 lttv_attribute_find(self->parent.parent.a, LTTV_STATS_BEFORE_HOOKS,
1462 LTTV_POINTER, &val);
1463 *(val.v_pointer) = before_hooks;
1464 lttv_attribute_find(self->parent.parent.a, LTTV_STATS_AFTER_HOOKS,
1465 LTTV_POINTER, &val);
1466 *(val.v_pointer) = after_hooks;
1467 }
1468 }
1469
1470 // Hook wrapper. call_data is a traceset context.
1471 gboolean lttv_stats_hook_remove_event_hooks(void *hook_data, void *call_data)
1472 {
1473 LttvTracesetStats *tss = (LttvTracesetStats*)call_data;
1474
1475 lttv_stats_remove_event_hooks(tss);
1476
1477 return 0;
1478 }
1479
1480 void lttv_stats_remove_event_hooks(LttvTracesetStats *self)
1481 {
1482 LttvTraceset *traceset = self->parent.parent.ts;
1483
1484 guint i, j, k, l, nb_trace, nb_tracefile;
1485
1486 LttvTraceStats *ts;
1487
1488 LttvTracefileStats *tfs;
1489
1490 void *hook_data;
1491
1492 GArray *before_hooks, *after_hooks;
1493
1494 LttvTraceHook *hook;
1495
1496 LttvTraceHookByFacility *thf;
1497
1498 LttvAttributeValue val;
1499
1500 nb_trace = lttv_traceset_number(traceset);
1501 for(i = 0 ; i < nb_trace ; i++) {
1502 ts = (LttvTraceStats*)self->parent.parent.traces[i];
1503 lttv_attribute_find(self->parent.parent.a, LTTV_STATS_BEFORE_HOOKS,
1504 LTTV_POINTER, &val);
1505 before_hooks = *(val.v_pointer);
1506 lttv_attribute_find(self->parent.parent.a, LTTV_STATS_AFTER_HOOKS,
1507 LTTV_POINTER, &val);
1508 after_hooks = *(val.v_pointer);
1509
1510 /* Remove these hooks from each event_by_id hooks list */
1511
1512 nb_tracefile = ts->parent.parent.tracefiles->len;
1513
1514 for(j = 0 ; j < nb_tracefile ; j++) {
1515 tfs = LTTV_TRACEFILE_STATS(g_array_index(ts->parent.parent.tracefiles,
1516 LttvTracefileContext*, j));
1517 lttv_hooks_remove_data(tfs->parent.parent.event, every_event,
1518 NULL);
1519
1520 for(k = 0 ; k < before_hooks->len ; k++) {
1521 hook = &g_array_index(before_hooks, LttvTraceHook, k);
1522 for(l = 0 ; l < hook->fac_list->len ; l++) {
1523 thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
1524 lttv_hooks_remove_data(
1525 lttv_hooks_by_id_find(tfs->parent.parent.event_by_id, thf->id),
1526 thf->h,
1527 thf);
1528 }
1529 }
1530 for(k = 0 ; k < after_hooks->len ; k++) {
1531 hook = &g_array_index(after_hooks, LttvTraceHook, k);
1532 for(l = 0 ; l < hook->fac_list->len ; l++) {
1533 thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
1534 lttv_hooks_remove_data(
1535 lttv_hooks_by_id_find(tfs->parent.parent.event_by_id, thf->id),
1536 thf->h,
1537 thf);
1538 }
1539 }
1540 }
1541 g_debug("lttv_stats_remove_event_hooks()");
1542 g_array_free(before_hooks, TRUE);
1543 g_array_free(after_hooks, TRUE);
1544 }
1545 }
1546
1547
1548
1549 /****************************************************************************************************************************/
1550
1551 void lttv_xeno_stats_sum_trace(LttvTraceStats *self, LttvAttribute *ts_stats){
1552 LttvAttribute *sum_container = self->xenoltt_stats;
1553 LttvAttributeType type;
1554 LttvAttributeValue value;
1555 LttvAttributeName name;
1556 gboolean is_named;
1557 unsigned sum;
1558 int trace_is_summed;
1559 int nb_threads;
1560
1561 LttvAttribute *main_tree, *threads_tree, *thread_tree;
1562
1563 main_tree = sum_container;
1564
1565 lttv_attribute_find(sum_container,LTTV_STATS_SUMMED, LTTV_UINT, &value);
1566 trace_is_summed = *(value.v_uint);
1567 *(value.v_uint) = 1;
1568
1569 /* First cleanup the state : sum all stalled information (never ending
1570 * states). */
1571 if(!trace_is_summed) lttv_stats_cleanup_state(self);
1572
1573 // First level of Xenomai Tasks Statistics Tree
1574 threads_tree = lttv_attribute_find_subdir(main_tree, LTTV_XENO_STATS_THREADS);
1575 nb_threads = lttv_attribute_get_number(threads_tree);
1576
1577 }
1578
1579
1580 void lttv_xeno_stats_sum_traceset(LttvTracesetStats *self){
1581 LttvTraceset *traceset = self->parent.parent.ts;
1582 LttvAttribute *sum_container = self->xenoltt_stats;
1583
1584 LttvTraceStats *tcs;
1585
1586 int i, nb_trace;
1587
1588 LttvAttribute *main_tree;
1589
1590 LttvAttributeValue value;
1591
1592 lttv_attribute_find(sum_container, LTTV_STATS_SUMMED,
1593 LTTV_UINT, &value);
1594 if(*(value.v_uint) != 0) return;
1595 *(value.v_uint) = 1;
1596
1597 nb_trace = lttv_traceset_number(traceset);
1598
1599 for(i = 0 ; i < nb_trace ; i++) {
1600 tcs = (LttvTraceStats *)(self->parent.parent.traces[i]);
1601 lttv_xeno_stats_sum_trace(tcs, self->xenoltt_stats);
1602 }
1603 }
1604
1605
1606 /****************************************************************************
1607 - Task Name ( Address, Priority, Period )
1608 - Periods
1609 * Running Avg, Max, Min
1610 * Suspend Avg, Max, Min
1611 * Ready Avg, Max, Min
1612 - Overruns
1613 - # ( ticks missed, time )
1614 - Status
1615 - Status name (#, total time, avg)
1616 - Ressources
1617 - Name
1618 - Possession (#, time, avg)
1619 - Waiting (#, time, avg)
1620 - Events
1621 *****************************************************************************/
1622
1623 static void xeno_find_task_tree(LttvTracefileStats *tfcs, GQuark name, gulong address, guint cpu,
1624 LttvAttribute **events_tree, LttvAttribute **event_types_tree){
1625 LttvAttribute *a, *task_tree, *period_tree, *state_tree, *synch_tree;
1626
1627 LttvAttributeValue thread_name, thread_address, prio, period;
1628
1629 LttvTraceStats *tcs = (LttvTraceStats*)tfcs->parent.parent.t_context;
1630 task_tree = lttv_attribute_find_subdir(tcs->xenoltt_stats, LTTV_XENO_STATS_THREADS);
1631
1632 task_tree = lttv_attribute_find_subdir(task_tree, name);
1633 lttv_attribute_find(task_tree, LTTV_XENO_STATS_THREAD_ADDRESS, LTTV_POINTER, &thread_address);
1634 *(thread_address.v_pointer) = address;
1635
1636 lttv_attribute_find(task_tree, LTTV_XENO_STATS_THREAD_PERIOD, LTTV_UINT, &period);
1637 lttv_attribute_find(task_tree, LTTV_XENO_STATS_THREAD_PRIO, LTTV_UINT, &prio);
1638 *events_tree = task_tree;
1639 /*
1640 period_tree = lttv_attribute_find_subdir(task_tree, LTTV_XENO_STATS_PERIOD);
1641 lttv_attribute_find(period_tree, LTTV_XENO_STATS_THREAD_PERIOD, LTTV_UINT, &period);
1642 lttv_attribute_find(period_tree, LTTV_XENO_STATS_NB_PERIOD, LTTV_UINT, &period);
1643
1644 lttv_attribute_find(period_tree, LTTV_XENO_STATE_READY, LTTV_STRING, &prio);
1645 *(prio.v_string) = "";
1646 lttv_attribute_find(period_tree, LTTV_XENO_STATS_TEXT_READY_AVG, LTTV_UINT, &prio);
1647 lttv_attribute_find(period_tree, LTTV_XENO_STATS_TEXT_READY_MAX, LTTV_UINT, &prio);
1648 lttv_attribute_find(period_tree, LTTV_XENO_STATS_TEXT_READY_MIN, LTTV_UINT, &prio);
1649 lttv_attribute_find(period_tree, LTTV_XENO_STATE_RUN, LTTV_STRING, &prio);
1650 *(prio.v_string) = "";
1651 lttv_attribute_find(period_tree, LTTV_XENO_STATS_TEXT_RUNNING_AVG, LTTV_UINT, &prio);
1652 lttv_attribute_find(period_tree, LTTV_XENO_STATS_TEXT_RUNNING_MAX, LTTV_UINT, &prio);
1653 lttv_attribute_find(period_tree, LTTV_XENO_STATS_TEXT_RUNNING_MIN, LTTV_UINT, &prio);
1654 lttv_attribute_find(period_tree, LTTV_XENO_STATE_SUSPEND, LTTV_STRING, &prio);
1655 *(prio.v_string) = "";
1656 lttv_attribute_find(period_tree, LTTV_XENO_STATS_TEXT_SUSPEND_AVG, LTTV_UINT, &prio);
1657 lttv_attribute_find(period_tree, LTTV_XENO_STATS_TEXT_SUSPEND_MAX, LTTV_UINT, &prio);
1658 lttv_attribute_find(period_tree, LTTV_XENO_STATS_TEXT_SUSPEND_MIN, LTTV_UINT, &prio);
1659
1660 */
1661 lttv_attribute_find_subdir(task_tree, LTTV_XENO_STATS_PERIOD_OVERRUNS);
1662
1663
1664 state_tree = lttv_attribute_find_subdir(task_tree, LTTV_XENO_STATS_STATE);
1665
1666 synch_tree = lttv_attribute_find_subdir(task_tree, LTTV_XENO_STATS_SYNCH);
1667
1668 a = lttv_attribute_find_subdir(task_tree, LTTV_STATS_EVENT_TYPES);
1669 *event_types_tree = a;
1670 }
1671
1672 gboolean xenoltt_thread_init(void *hook_data, void *call_data){
1673 LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
1674 LttvTraceState *ts = (LttvTraceState*)tfcs->parent.parent.t_context;
1675 LttvXenoThreadState *thread;
1676 LttvAttributeValue prio;
1677 guint cpu = tfcs->parent.cpu;
1678 thread = ts->running_thread[cpu];
1679
1680 xeno_find_task_tree(tfcs, thread->name, thread->address,cpu, &(tfcs->current_events_tree), &(tfcs->current_event_types_tree));
1681
1682 lttv_attribute_find(tfcs->current_events_tree, LTTV_XENO_STATS_THREAD_PRIO, LTTV_UINT, &prio);
1683 *(prio.v_uint) = thread->prio;
1684
1685 xenoltt_after_change_state(hook_data,call_data);
1686
1687 printf("init %s\n",g_quark_to_string(thread->name));
1688 return FALSE;
1689 }
1690
1691 gboolean xenoltt_thread_renice(void *hook_data, void *call_data){
1692 LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
1693 LttvTraceState *ts = (LttvTraceState*)tfcs->parent.parent.t_context;
1694 LttvXenoThreadState *thread;
1695 LttvAttributeValue prio;
1696 guint cpu = tfcs->parent.cpu;
1697 thread = ts->running_thread[cpu];
1698
1699 xeno_find_task_tree(tfcs, thread->name, thread->address,cpu, &(tfcs->current_events_tree), &(tfcs->current_event_types_tree));
1700
1701 lttv_attribute_find(tfcs->current_events_tree, LTTV_XENO_STATS_THREAD_PRIO, LTTV_UINT, &prio);
1702 *(prio.v_uint) = thread->prio;
1703
1704 return FALSE;
1705 }
1706
1707 gboolean xenoltt_thread_set_period(void *hook_data, void *call_data){
1708 LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
1709 LttvTraceState *ts = (LttvTraceState*)tfcs->parent.parent.t_context;
1710 LttvXenoThreadState *thread;
1711 LttvAttributeValue period, *period_tree;
1712 guint cpu = tfcs->parent.cpu;
1713 thread = ts->running_thread[cpu];
1714
1715 // Find corresponding task
1716 xeno_find_task_tree(tfcs, thread->name, thread->address,cpu, &(tfcs->current_events_tree), &(tfcs->current_event_types_tree));
1717
1718 // Write the period of the task
1719 lttv_attribute_find(tfcs->current_events_tree, LTTV_XENO_STATS_THREAD_PERIOD, LTTV_UINT, &period);
1720 *(period.v_uint) = thread->period;
1721
1722 period_tree = lttv_attribute_find_subdir(tfcs->current_events_tree, LTTV_XENO_STATS_PERIOD);
1723 lttv_attribute_find(period_tree, LTTV_XENO_STATS_THREAD_PERIOD, LTTV_UINT, &period);
1724 *(period.v_uint) = thread->period;
1725
1726 return FALSE;
1727 }
1728
1729 gboolean xenoltt_thread_overruns(void *hook_data, void *call_data){
1730 LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
1731 LttvTraceState *ts = (LttvTraceState*)tfcs->parent.parent.t_context;
1732 LttEvent *e = ltt_tracefile_get_event(tfcs->parent.parent.tf);
1733 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
1734 LttvAttributeValue overrun, *overrun_tree;
1735 guint cpu = tfcs->parent.cpu;
1736
1737 g_assert(thf->f1 != NULL);
1738 GQuark name = g_quark_from_string(ltt_event_get_string(e, thf->f1));
1739 g_assert(thf->f2 != NULL);
1740 gulong address = ltt_event_get_long_unsigned(e, thf->f2);
1741 g_assert(thf->f3 != NULL);
1742 guint overruns = ltt_event_get_long_unsigned(e, thf->f3);
1743 LttvXenoThreadState *thread = lttv_xeno_state_find_thread(ts,cpu,address);
1744 xeno_find_task_tree(tfcs, name, address,cpu, &(tfcs->current_events_tree), &(tfcs->current_event_types_tree));
1745
1746 // overrun_tree = lttv_attribute_find_subdir(tfcs->current_events_tree, LTTV_XENO_STATS_PERIOD);
1747 overrun_tree = lttv_attribute_find_subdir(tfcs->current_events_tree, LTTV_XENO_STATS_PERIOD_OVERRUNS);
1748
1749 gchar overrun_time[MAX_64_HEX_STRING_LEN];
1750 sprintf(overrun_time,"%lu,%lu", tfcs->parent.parent.timestamp.tv_sec,tfcs->parent.parent.timestamp.tv_nsec);
1751 overrun_tree = lttv_attribute_find_subdir(overrun_tree, g_quark_from_string(overrun_time));
1752
1753 lttv_attribute_find(overrun_tree, LTTV_XENO_STATS_TEXT_TICKS, LTTV_UINT, &overrun);
1754 *(overrun.v_uint) = overruns;
1755
1756 LttTime delta = ltt_time_sub(tfcs->parent.parent.timestamp, thread->state->overrun_start);
1757 lttv_attribute_find(overrun_tree, LTTV_XENO_STATS_TEXT_TOTAL, LTTV_TIME, &overrun);
1758 *(overrun.v_time) = delta;
1759 return FALSE;
1760 }
1761
1762 gboolean xenoltt_before_change_state(void *hook_data, void *call_data){
1763 LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
1764 LttvTraceState *ts = (LttvTraceState*)tfcs->parent.parent.t_context;
1765 LttvXenoThreadState *thread;
1766 LttvAttributeValue *a, state_count, state_time, state_time_average, time, period_count, time_ready, time_run, time_suspend;
1767 guint cpu = tfcs->parent.cpu;
1768 thread = ts->running_thread[cpu];
1769 LttTime total;
1770
1771 xeno_find_task_tree(tfcs, thread->name, thread->address,cpu, &(tfcs->current_events_tree), &(tfcs->current_event_types_tree));
1772
1773 // Create or go to State subtree
1774 a = lttv_attribute_find_subdir(tfcs->current_events_tree, LTTV_XENO_STATS_STATE);
1775 // Create or go to the current state subtree
1776 a = lttv_attribute_find_subdir(a, thread->state->status);
1777 lttv_attribute_find(a, g_quark_from_string("Number of times in this state"), LTTV_UINT, &state_count);
1778
1779 LttTime delta = ltt_time_sub(tfcs->parent.parent.timestamp, thread->state->change);
1780 lttv_attribute_find(a, g_quark_from_string("Cumulative time"), LTTV_TIME, &state_time);
1781 *(state_time.v_time) = ltt_time_add(*(state_time.v_time), delta);
1782
1783 lttv_attribute_find(a, g_quark_from_string("Average elapsed time"), LTTV_TIME, &state_time_average);
1784 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);
1785 else *(state_time_average.v_time) = ltt_time_div(*(state_time.v_time), *(state_count.v_uint));
1786 /*
1787 // When wait_period is called, this means that the thread as finished executing the current period
1788 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
1789 LttEvent *e = ltt_tracefile_get_event(tfc->tf);
1790 GQuark event_name = ltt_eventtype_name(ltt_event_eventtype(e));
1791 if (event_name == LTT_EVENT_XENOLTT_THREAD_WAIT_PERIOD){
1792 a = lttv_attribute_find_subdir(tfcs->current_events_tree, LTTV_XENO_STATS_PERIOD);
1793 lttv_attribute_find(a, LTTV_XENO_STATS_NB_PERIOD, LTTV_UINT, &period_count);
1794 // Now we need to update all fields
1795 a = lttv_attribute_find_subdir(tfcs->current_events_tree, LTTV_XENO_STATS_PERIOD);
1796
1797 lttv_attribute_find(a, LTTV_XENO_STATE_READY, LTTV_TIME, &time_ready);
1798
1799 lttv_attribute_find(a, LTTV_XENO_STATS_TEXT_READY_AVG, LTTV_TIME, &time);
1800 total = ltt_time_mul(*(time_ready.v_time),*(period_count.v_uint));
1801 total = ltt_time_add(*(time.v_time),total);
1802 if (ltt_time_compare(total,ltt_time_zero) != 0) *(time.v_time) = ltt_time_div(total,(*(period_count.v_uint)+1));
1803
1804 lttv_attribute_find(a, LTTV_XENO_STATS_TEXT_READY_MAX, LTTV_TIME, &time);
1805 if(ltt_time_compare(*(time_ready.v_time),*(time.v_time)) == 1) *(time.v_time) = *(time_ready.v_time);
1806
1807 lttv_attribute_find(a, LTTV_XENO_STATS_TEXT_READY_MIN, LTTV_TIME, &time);
1808 if(ltt_time_compare(*(time_ready.v_time),*(time.v_time)) == -1) *(time.v_time) = *(time_ready.v_time);
1809
1810 *(time_ready.v_time) = ltt_time_zero;
1811
1812 lttv_attribute_find(a, LTTV_XENO_STATE_RUN, LTTV_TIME, &time_run);
1813 lttv_attribute_find(a, LTTV_XENO_STATS_TEXT_RUNNING_AVG, LTTV_TIME, &time);
1814 total = ltt_time_mul(*(time_run.v_time),*(period_count.v_uint));
1815 total = ltt_time_add(*(time.v_time),total);
1816 if (ltt_time_compare(total,ltt_time_zero) != 0) *(time.v_time) = ltt_time_div(total,(*(period_count.v_uint)+1));
1817
1818 lttv_attribute_find(a, LTTV_XENO_STATS_TEXT_RUNNING_MAX, LTTV_TIME, &time);
1819 if(ltt_time_compare(*(time_run.v_time),*(time.v_time)) == 1) *(time.v_time) = *(time_run.v_time);
1820
1821 lttv_attribute_find(a, LTTV_XENO_STATS_TEXT_RUNNING_MIN, LTTV_TIME, &time);
1822 if(ltt_time_compare(*(time_run.v_time),*(time.v_time)) == -1) *(time.v_time) = *(time_run.v_time);
1823
1824 *(time_run.v_time) = ltt_time_zero;
1825
1826 lttv_attribute_find(a, LTTV_XENO_STATE_SUSPEND, LTTV_TIME, &time_suspend);
1827 lttv_attribute_find(a, LTTV_XENO_STATS_TEXT_SUSPEND_AVG, LTTV_TIME, &time);
1828 total = ltt_time_mul(*(time_suspend.v_time),*(period_count.v_uint));
1829 total = ltt_time_add(*(time.v_time),total);
1830 if (ltt_time_compare(total,ltt_time_zero) != 0) *(time.v_time) = ltt_time_div(total,(*(period_count.v_uint)+1));
1831
1832 lttv_attribute_find(a, LTTV_XENO_STATS_TEXT_SUSPEND_MAX, LTTV_TIME, &time);
1833 if(ltt_time_compare(*(time_suspend.v_time),*(time.v_time)) == 1) *(time.v_time) = *(time_suspend.v_time);
1834
1835 lttv_attribute_find(a, LTTV_XENO_STATS_TEXT_SUSPEND_MIN, LTTV_TIME, &time);
1836 if(ltt_time_compare(*(time_suspend.v_time),*(time.v_time)) == -1) *(time.v_time) = *(time_suspend.v_time);
1837
1838 *(time_suspend.v_time) = ltt_time_zero;
1839
1840 *(period_count.v_uint) = *(period_count.v_uint) + 1;
1841
1842 }
1843
1844 // We want to update the period specific information about the state of the task
1845 if (thread->state->status == LTTV_XENO_STATE_READY){
1846 printf("add ready\n");
1847 a = lttv_attribute_find_subdir(tfcs->current_events_tree, LTTV_XENO_STATS_PERIOD);
1848 lttv_attribute_find(a, LTTV_XENO_STATE_READY, LTTV_TIME, &time);
1849 *(time.v_time) = ltt_time_add(*(time.v_time),delta);
1850 }
1851 else if (thread->state->status == LTTV_XENO_STATE_RUN){
1852 printf("add run\n");
1853 a = lttv_attribute_find_subdir(tfcs->current_events_tree, LTTV_XENO_STATS_PERIOD);
1854 lttv_attribute_find(a, LTTV_XENO_STATE_RUN, LTTV_TIME, &time);
1855 *(time.v_time) = ltt_time_add(*(time.v_time),delta);
1856 }
1857 else if (thread->state->status == LTTV_XENO_STATE_SUSPEND){
1858 a = lttv_attribute_find_subdir(tfcs->current_events_tree, LTTV_XENO_STATS_PERIOD);
1859 lttv_attribute_find(a, LTTV_XENO_STATE_SUSPEND, LTTV_TIME, &time);
1860 *(time.v_time) = ltt_time_add(*(time.v_time),delta);
1861 printf("add suspend\n");
1862 }
1863 */
1864 return FALSE;
1865 }
1866
1867 gboolean xenoltt_after_change_state(void *hook_data, void *call_data){
1868 LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
1869 LttvTraceState *ts = (LttvTraceState*)tfcs->parent.parent.t_context;
1870 LttvXenoThreadState *thread;
1871 LttvAttributeValue *a, state_count, state_time, state_time_average;
1872 guint cpu = tfcs->parent.cpu;
1873 thread = ts->running_thread[cpu];
1874
1875 xeno_find_task_tree(tfcs, thread->name, thread->address,cpu, &(tfcs->current_events_tree), &(tfcs->current_event_types_tree));
1876
1877 // Create or go to State subtree
1878 a = lttv_attribute_find_subdir(tfcs->current_events_tree, LTTV_XENO_STATS_STATE);
1879 // Create or go to the current state subtree
1880 a = lttv_attribute_find_subdir(a, thread->state->status);
1881 lttv_attribute_find(a, g_quark_from_string("Number of times in this state"), LTTV_UINT, &state_count);
1882 *(state_count.v_uint) = *(state_count.v_uint) + 1;
1883
1884 LttTime delta = ltt_time_sub(tfcs->parent.parent.timestamp, thread->state->entry);
1885 lttv_attribute_find(a, g_quark_from_string("Cumulative time"), LTTV_TIME, &state_time);
1886 *(state_time.v_time) = ltt_time_add(*(state_time.v_time), delta);
1887
1888 lttv_attribute_find(a, g_quark_from_string("Average elapsed time"), LTTV_TIME, &state_time_average);
1889 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);
1890 else *(state_time_average.v_time) = ltt_time_div(*(state_time.v_time), *(state_count.v_uint));
1891
1892
1893 return FALSE;
1894 }
1895
1896 gboolean xenoltt_synch_owner(void *hook_data, void *call_data){
1897 LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
1898 LttvTraceState *ts = (LttvTraceState*)tfcs->parent.parent.t_context;
1899 LttEvent *e = ltt_tracefile_get_event(tfcs->parent.parent.tf);
1900 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
1901 LttvAttributeValue synch, total_time, avg_time, max_time, min_time,*synch_tree;
1902 guint cpu = tfcs->parent.cpu;
1903 LttvXenoThreadState *thread = ts->running_thread[cpu];
1904
1905 if (thread->state->started == TRUE){
1906 g_assert(thf->f1 != NULL);
1907 gulong synch_address = ltt_event_get_long_unsigned(e, thf->f1);
1908
1909 xeno_find_task_tree(tfcs, thread->name, thread->address,cpu, &(tfcs->current_events_tree), &(tfcs->current_event_types_tree));
1910
1911 synch_tree = lttv_attribute_find_subdir(tfcs->current_events_tree, LTTV_XENO_STATS_SYNCH);
1912
1913 gchar synch_id[MAX_64_HEX_STRING_LEN];
1914 sprintf(synch_id,"%p", synch_address);
1915 synch_tree = lttv_attribute_find_subdir(synch_tree, g_quark_from_string(synch_id));
1916
1917 lttv_attribute_find(synch_tree, LTTV_XENO_STATS_TEXT_OWNER, LTTV_UINT, &synch);
1918 *(synch.v_uint) = *(synch.v_uint) + 1;
1919 }
1920 return FALSE;
1921 }
1922
1923 // When sleep-on is called
1924 gboolean xenoltt_synch_wait(void *hook_data, void *call_data){
1925 LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
1926 LttvTraceState *ts = (LttvTraceState*)tfcs->parent.parent.t_context;
1927 LttEvent *e = ltt_tracefile_get_event(tfcs->parent.parent.tf);
1928 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
1929 LttvAttributeValue synch, total_time, avg_time, max_time, min_time, *synch_tree;
1930 guint cpu = tfcs->parent.cpu;
1931 LttvXenoThreadState *thread;
1932 thread = ts->running_thread[cpu];
1933
1934 g_assert(thf->f1 != NULL);
1935 gulong synch_address = ltt_event_get_long_unsigned(e, thf->f1);
1936 g_assert(thf->f2 != NULL);
1937 GQuark name = g_quark_from_string(ltt_event_get_string(e, thf->f2));
1938 g_assert(thf->f3 != NULL);
1939 gulong address = ltt_event_get_long_unsigned(e, thf->f3);
1940
1941 xeno_find_task_tree(tfcs, name, address,cpu, &(tfcs->current_events_tree), &(tfcs->current_event_types_tree));
1942
1943 synch_tree = lttv_attribute_find_subdir(tfcs->current_events_tree, LTTV_XENO_STATS_SYNCH);
1944
1945 gchar synch_id[MAX_64_HEX_STRING_LEN];
1946 sprintf(synch_id,"%p", synch_address);
1947 synch_tree = lttv_attribute_find_subdir(synch_tree, g_quark_from_string(synch_id));
1948
1949 // We have one more waiting call to register
1950 lttv_attribute_find(synch_tree, LTTV_XENO_STATS_TEXT_WAITING, LTTV_UINT, &synch);
1951 *(synch.v_uint) = *(synch.v_uint) + 1;
1952
1953 return FALSE;
1954 }
1955
1956 gboolean xenoltt_synch_wakeup(void *hook_data, void *call_data){
1957 LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
1958 LttvTraceState *ts = (LttvTraceState*)tfcs->parent.parent.t_context;
1959 LttEvent *e = ltt_tracefile_get_event(tfcs->parent.parent.tf);
1960 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
1961 LttvAttributeValue synch, total_time, avg_time, max_time, min_time,*synch_tree;
1962 guint cpu = tfcs->parent.cpu;
1963 GQuark event_name = ltt_eventtype_name(ltt_event_eventtype(e));
1964
1965 g_assert(thf->f1 != NULL);
1966 gulong synch_address = ltt_event_get_long_unsigned(e, thf->f1);
1967 g_assert(thf->f2 != NULL);
1968 GQuark name = g_quark_from_string(ltt_event_get_string(e, thf->f2));
1969 g_assert(thf->f3 != NULL);
1970 gulong address = ltt_event_get_long_unsigned(e, thf->f3);
1971 LttvXenoSynchState *synch_state = lttv_xeno_state_find_synch(ts,synch_address);
1972 LttvXenoThreadState *thread = lttv_xeno_state_find_thread(ts,cpu,address);
1973 if (synch_state != NULL && thread != NULL ){
1974 xeno_find_task_tree(tfcs, name, address,cpu, &(tfcs->current_events_tree), &(tfcs->current_event_types_tree));
1975
1976 synch_tree = lttv_attribute_find_subdir(tfcs->current_events_tree, LTTV_XENO_STATS_SYNCH);
1977
1978 gchar synch_id[MAX_64_HEX_STRING_LEN];
1979 sprintf(synch_id,"%p", synch_address);
1980 synch_tree = lttv_attribute_find_subdir(synch_tree, g_quark_from_string(synch_id));
1981
1982 if (event_name != LTT_EVENT_XENOLTT_SYNCH_FORGET){
1983 lttv_attribute_find(synch_tree, LTTV_XENO_STATS_TEXT_OWNER, LTTV_UINT, &synch);
1984 *(synch.v_uint) = *(synch.v_uint) + 1;
1985 }
1986
1987 lttv_attribute_find(synch_tree, LTTV_XENO_STATS_TEXT_WAITING, LTTV_UINT, &synch);
1988
1989
1990 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);
1993
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));
1997
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;
2001
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;
2006
2007
2008 }
2009 return FALSE;
2010 }
2011
2012 gboolean xenoltt_synch_flush(void *hook_data, void *call_data){
2013 LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
2014 LttvTraceState *ts = (LttvTraceState*)tfcs->parent.parent.t_context;
2015 LttEvent *e = ltt_tracefile_get_event(tfcs->parent.parent.tf);
2016 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
2017 LttvAttributeValue synch, total_time, avg_time, max_time, min_time,*synch_tree;
2018 guint cpu = tfcs->parent.cpu;
2019 GQuark event_name = ltt_eventtype_name(ltt_event_eventtype(e));
2020
2021 g_assert(thf->f1 != NULL);
2022 gulong synch_address = ltt_event_get_long_unsigned(e, thf->f1);
2023
2024 LttvXenoSynchState *synch_state = lttv_xeno_state_find_synch(ts,synch_address);
2025 LttvXenoThreadState *thread;
2026 if (synch_state != NULL && thread != NULL ){
2027 int i;
2028 for(i=0;i<synch_state->state->waiting_threads->len;i++){
2029 thread = g_array_index(synch_state->state->waiting_threads, LttvXenoThreadState*, i);
2030
2031 xeno_find_task_tree(tfcs, thread->name, thread->address,cpu, &(tfcs->current_events_tree), &(tfcs->current_event_types_tree));
2032
2033 synch_tree = lttv_attribute_find_subdir(tfcs->current_events_tree, LTTV_XENO_STATS_SYNCH);
2034
2035 gchar synch_id[MAX_64_HEX_STRING_LEN];
2036 sprintf(synch_id,"%p", synch_address);
2037 synch_tree = lttv_attribute_find_subdir(synch_tree, g_quark_from_string(synch_id));
2038
2039 if (event_name != LTT_EVENT_XENOLTT_SYNCH_FORGET){
2040 lttv_attribute_find(synch_tree, LTTV_XENO_STATS_TEXT_OWNER, LTTV_UINT, &synch);
2041 *(synch.v_uint) = *(synch.v_uint) + 1;
2042 }
2043
2044 lttv_attribute_find(synch_tree, LTTV_XENO_STATS_TEXT_WAITING, LTTV_UINT, &synch);
2045
2046 LttTime delta = ltt_time_sub(tfcs->parent.parent.timestamp, thread->start_wait_synch);
2047 lttv_attribute_find(synch_tree, LTTV_XENO_STATS_TEXT_WAITING_TOTAL, LTTV_TIME, &total_time);
2048 *(total_time.v_time) = ltt_time_add(*(total_time.v_time), delta);
2049
2050 lttv_attribute_find(synch_tree, LTTV_XENO_STATS_TEXT_WAITING_AVG, LTTV_TIME, &avg_time);
2051 if (*(synch.v_uint) == 0 || ltt_time_compare(*(total_time.v_time),ltt_time_zero) == 0) *(avg_time.v_time) = *(total_time.v_time);
2052 else *(avg_time.v_time) = ltt_time_div(*(total_time.v_time), *(synch.v_uint));
2053
2054 lttv_attribute_find(synch_tree, LTTV_XENO_STATS_TEXT_WAITING_MAX, LTTV_TIME, &max_time);
2055 // If this owning time is longer than any other before
2056 if (ltt_time_compare(delta,*(max_time.v_time)) == 1) *(max_time.v_time) = delta;
2057
2058 lttv_attribute_find(synch_tree, LTTV_XENO_STATS_TEXT_WAITING_MIN, LTTV_TIME, &min_time);
2059 // If this owning time is shorter than any other before
2060 if (*(synch.v_uint) == 1) *(min_time.v_time) = delta;
2061 else if (ltt_time_compare(*(min_time.v_time), delta) == 1) *(min_time.v_time) = delta;
2062 }
2063 }
2064 return FALSE;
2065 }
2066
2067 gboolean xenoltt_synch_unblock(void *hook_data, void *call_data){
2068 LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
2069 LttvTraceState *ts = (LttvTraceState*)tfcs->parent.parent.t_context;
2070 LttEvent *e = ltt_tracefile_get_event(tfcs->parent.parent.tf);
2071 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
2072 LttvAttributeValue synch, total_time, avg_time, max_time, min_time, *synch_tree;
2073 guint cpu = tfcs->parent.cpu;
2074 LttvXenoThreadState *thread = ts->running_thread[cpu];
2075
2076 g_assert(thf->f1 != NULL);
2077 gulong synch_address = ltt_event_get_long_unsigned(e, thf->f1);
2078 LttvXenoSynchState *synch_state = lttv_xeno_state_find_synch(ts,synch_address);
2079 if (synch_state != NULL){
2080
2081 xeno_find_task_tree(tfcs, thread->name, thread->address,cpu, &(tfcs->current_events_tree), &(tfcs->current_event_types_tree));
2082
2083 synch_tree = lttv_attribute_find_subdir(tfcs->current_events_tree, LTTV_XENO_STATS_SYNCH);
2084
2085 gchar synch_id[MAX_64_HEX_STRING_LEN];
2086 sprintf(synch_id,"%p", synch_address);
2087 synch_tree = lttv_attribute_find_subdir(synch_tree, g_quark_from_string(synch_id));
2088
2089 lttv_attribute_find(synch_tree, LTTV_XENO_STATS_TEXT_OWNER, LTTV_UINT, &synch);
2090
2091 LttTime delta = ltt_time_sub(tfcs->parent.parent.timestamp, synch_state->state->start_time);
2092 lttv_attribute_find(synch_tree, LTTV_XENO_STATS_TEXT_OWNER_TOTAL, LTTV_TIME, &total_time);
2093 *(total_time.v_time) = ltt_time_add(*(total_time.v_time), delta);
2094
2095 lttv_attribute_find(synch_tree, LTTV_XENO_STATS_TEXT_OWNER_AVG, LTTV_TIME, &avg_time);
2096 if (*(synch.v_uint) == 0 || ltt_time_compare(*(total_time.v_time),ltt_time_zero) == 0) *(avg_time.v_time) = *(total_time.v_time);
2097 else *(avg_time.v_time) = ltt_time_div(*(total_time.v_time), *(synch.v_uint));
2098
2099 lttv_attribute_find(synch_tree, LTTV_XENO_STATS_TEXT_OWNER_MAX, LTTV_TIME, &max_time);
2100 // If this owning time is longer than any other before
2101 if (ltt_time_compare(delta,*(max_time.v_time)) == 1) *(max_time.v_time) = delta;
2102
2103 lttv_attribute_find(synch_tree, LTTV_XENO_STATS_TEXT_OWNER_MIN, LTTV_TIME, &min_time);
2104 // If this owning time is shorter than any other before
2105 if (*(synch.v_uint) == 1) *(min_time.v_time) = delta;
2106 else if (ltt_time_compare(*(min_time.v_time), delta) == 1) *(min_time.v_time) = delta;
2107
2108
2109 }
2110 return FALSE;
2111
2112 }
2113
2114 /****************************************************************************************************************************/
2115
2116
2117
2118
2119 static void module_init()
2120 {
2121 LTTV_STATS_PROCESS_UNKNOWN = g_quark_from_string("unknown process");
2122 LTTV_STATS_PROCESSES = g_quark_from_string("processes");
2123 LTTV_STATS_CPU = g_quark_from_string("cpu");
2124 LTTV_STATS_MODE_TYPES = g_quark_from_string("mode_types");
2125 LTTV_STATS_MODES = g_quark_from_string("modes");
2126 LTTV_STATS_SUBMODES = g_quark_from_string("submodes");
2127 LTTV_STATS_FUNCTIONS = g_quark_from_string("functions");
2128 LTTV_STATS_EVENT_TYPES = g_quark_from_string("event_types");
2129 LTTV_STATS_CPU_TIME = g_quark_from_string("cpu time");
2130 LTTV_STATS_CUMULATIVE_CPU_TIME = g_quark_from_string("cumulative cpu time (includes nested routines and modes)");
2131 LTTV_STATS_ELAPSED_TIME = g_quark_from_string("elapsed time (includes per process waiting time)");
2132 LTTV_STATS_EVENTS = g_quark_from_string("events");
2133 LTTV_STATS_EVENTS_COUNT = g_quark_from_string("events count");
2134 LTTV_STATS_BEFORE_HOOKS = g_quark_from_string("saved stats before hooks");
2135 LTTV_STATS_AFTER_HOOKS = g_quark_from_string("saved stats after hooks");
2136 LTTV_STATS_USE_COUNT = g_quark_from_string("stats_use_count");
2137 LTTV_STATS = g_quark_from_string("statistics");
2138 LTTV_STATS_TRACEFILES = g_quark_from_string("tracefiles statistics");
2139 LTTV_STATS_SUMMED = g_quark_from_string("statistics summed");
2140 /****************************************************************************************************************************/
2141 LTTV_XENO_STATS_THREADS = g_quark_from_string("Xenomai Tasks");
2142 LTTV_XENO_STATS_PERIOD = g_quark_from_string("Periods");
2143 LTTV_XENO_STATS_STATE = g_quark_from_string("Status");
2144 LTTV_XENO_STATS_SYNCH = g_quark_from_string("Resources");
2145 LTTV_XENO_STATS_THREAD_ADDRESS = g_quark_from_string("Address");
2146 LTTV_XENO_STATS_THREAD_PRIO = g_quark_from_string("Priority");
2147 LTTV_XENO_STATS_THREAD_PERIOD = g_quark_from_string("Period");
2148 LTTV_XENO_STATS_PERIOD_OVERRUNS = g_quark_from_string("Overruns(s)");
2149 LTTV_XENO_STATS_TEXT_OVERRUNS = g_quark_from_string("Overrun(s)");
2150 LTTV_XENO_STATS_TEXT_TICKS = g_quark_from_string("Number of ticks");
2151 LTTV_XENO_STATS_TEXT_OWNER = g_quark_from_string("Owner");
2152 LTTV_XENO_STATS_TEXT_OWNER_TOTAL = g_quark_from_string("\tTotal time");
2153 LTTV_XENO_STATS_TEXT_OWNER_MAX = g_quark_from_string("\tMax time");
2154 LTTV_XENO_STATS_TEXT_OWNER_MIN = g_quark_from_string("\tMin time");
2155 LTTV_XENO_STATS_TEXT_OWNER_AVG = g_quark_from_string("\tAverage time");
2156 LTTV_XENO_STATS_TEXT_WAITING = g_quark_from_string("Waiting");
2157 LTTV_XENO_STATS_TEXT_WAITING_TOTAL = g_quark_from_string("\tTotal time waiting");
2158 LTTV_XENO_STATS_TEXT_WAITING_MAX = g_quark_from_string("\tMax time waiting");
2159 LTTV_XENO_STATS_TEXT_WAITING_MIN = g_quark_from_string("\tMin time waiting");
2160 LTTV_XENO_STATS_TEXT_WAITING_AVG = g_quark_from_string("\tAverage time waiting");
2161 LTTV_XENO_STATS_TEXT_TOTAL = g_quark_from_string("\tTotal time");
2162 LTTV_XENO_STATS_TEXT_READY_MAX = g_quark_from_string("\tMax time in readyq");
2163 LTTV_XENO_STATS_TEXT_READY_MIN = g_quark_from_string("\tMin time in readyq");
2164 LTTV_XENO_STATS_TEXT_READY_AVG = g_quark_from_string("\tAverage time in readyq");
2165 LTTV_XENO_STATS_TEXT_RUNNING_MAX = g_quark_from_string("\tMax time running");
2166 LTTV_XENO_STATS_TEXT_RUNNING_MIN = g_quark_from_string("\tMin time running");
2167 LTTV_XENO_STATS_TEXT_RUNNING_AVG = g_quark_from_string("\tAverage time running");
2168 LTTV_XENO_STATS_TEXT_SUSPEND_MAX = g_quark_from_string("\tMax time suspended");
2169 LTTV_XENO_STATS_TEXT_SUSPEND_MIN = g_quark_from_string("\tMin time suspended");
2170 LTTV_XENO_STATS_TEXT_SUSPEND_AVG = g_quark_from_string("\tAverage time suspended");
2171 LTTV_XENO_STATS_NB_PERIOD = g_quark_from_string("Number of periods executed");
2172 /****************************************************************************************************************************/
2173 }
2174
2175 static void module_destroy()
2176 {
2177 }
2178
2179
2180 LTTV_MODULE("stats", "Compute processes statistics", \
2181 "Accumulate statistics for event types, processes and CPUs", \
2182 module_init, module_destroy, "state");
2183
2184 /* Change the places where stats are called (create/read/write stats)
2185
2186 Check for options in batchtest.c to reduce writing and see what tests are
2187 best candidates for performance analysis. Once OK, commit, move to main
2188 and run tests. Update the gui for statistics. */
This page took 0.113051 seconds and 4 git commands to generate.