Changed automake files to reflect the new header files.
[lttv.git] / ltt / branches / poly / lttv / processTrace.c
CommitLineData
dc877563 1
2#include <lttv/processTrace.h>
3
4void lttv_context_init(LttvTracesetContext *self)
5{
6 LTTV_TRACESET_CONTEXT_GET_CLASS(self)->init(self);
7}
8
9
10void lttv_context_fini(LttvTracesetContext *self)
11{
12 LTTV_TRACESET_CONTEXT_GET_CLASS(self)->fini(self);
13}
14
15
16LttvTracesetContext *
17lttv_context_new_traceset_context(LttvTracesetContext *self)
18{
19 return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_traceset_context(self);
20}
21
22
23
24
25LttvTraceContext *
26lttv_context_new_trace_context(LttvTracesetContext *self)
27{
28 return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self);
29}
30
31
32LttvTracefileContext *
33lttv_context_new_tracefile_context(LttvTracesetContext *self)
34{
35 LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self);
36}
37
38
39static void
40init(LttvTracesetContext *self, LttvTraceset *ts)
41{
42 guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
43
44 LttvTraceContext *tc;
45
46 LttvTracefileContext *tfc;
47
48 nb_trace = lttv_traceset_number(ts);
49 self->ts = ts;
50 self->traces = g_new((LttvTraceContext *), nb_trace);
51 self->before = lttv_hooks_new();
52 self->after = lttv_hooks_new();
53 self->attributes = g_object_new(LTTV_ATTRIBUTE_TYPE);
54 for(i = 0 ; i < nb_trace ; i++) {
55 tc = self->new_trace_context();
56 self->traces[i] = tc;
57
58 tc->ts_context = self;
59 tc->index = i;
60 tc->t = lttv_traceset_get(ts, i);
61 tc->check = lttv_hooks_new();
62 tc->before = lttv_hooks_new();
63 tc->after = lttv_hooks_new();
64 tc->attributes = g_object_new(LTTV_ATTRIBUTE_TYPE);
65 nb_control = ltt_trace_control_tracefile_number(tc->t);
66 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
67 nb_tracefile = nb_control + nb_per_cpu;
68 tc->control_tracefiles = g_new((LttvTracefileContext *), nb_control);
69 tc->per_cpu_tracefiles = g_new((LttvTracefileContext *), nb_per_cpu);
70
71 for(j = 0 ; j < nb_tracefile ; j++) {
72 tfc = self->new_tracefile_context();
73 if(j < nb_control) {
74 tc->control_tracefiles[j] = tfc;
75 tfc->control = TRUE;
76 tfc->index = j;
77 tfc->tf = ltt_trace_control_tracefile_get(j);
78 }
79 else {
80 tc->per_cpu_tracefiles[j - nb_control] = tfc;
81 tfc->control = FALSE;
82 tfc->index = j - nb_control;
83 tfc->tf = ltt_trace_per_cpu_tracefile_get(j - nb_control);
84 }
85 tfc->t_context = tc;
86 tfc->check = lttv_hooks_new();
87 tfc->before = lttv_hooks_new();
88 tfc->after = lttv_hooks_new();
89 tfc->check_event = lttv_hooks_new();
90 tfc->before_event = lttv_hooks_new();
91 tfc->before_event_by_id = lttv_hooks_by_id_new();
92 tfc->after_event = lttv_hooks_new();
93 tfc->after_event_by_id = lttv_hooks_by_id_new();
94 tfc->attributes = g_object_new(LTTV_ATTRIBUTE_TYPE);
95 }
96 }
97}
98
99
100void fini(LttvTracesetContext *self)
101{
102 guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
103
104 LttvTraceContext *tc;
105
106 LttvTracefileContext *tfc;
107
108 LttvTraceset *ts = tc->ts;
109
110 lttv_hooks_destroy(self->before);
111 lttv_hooks_destroy(self->after);
112 g_object_unref(self->attributes);
113
114 nb_trace = lttv_traceset_number(ts);
115
116 for(i = 0 ; i < nb_trace ; i++) {
117 tc = self->traces[i];
118
119 lttv_hooks_destroy(tc->check);
120 lttv_hooks_destroy(tc->before);
121 lttv_hooks_destroy(tc->after);
122 g_object_unref(tc->attributes);
123
124 nb_control = ltt_trace_control_tracefile_number(tc->t);
125 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
126 nb_tracefile = nb_control + nb_per_cpu;
127
128 for(j = 0 ; j < nb_tracefile ; j++) {
129 if(j < nb_control) tfc = tc->control_tracefiles[j];
130 else tfc = tc->per_cpu_tracefiles[j - nb_control];
131
132 lttv_hooks_destroy(tfc->check);
133 lttv_hooks_destroy(tfc->before);
134 lttv_hooks_destroy(tfc->after);
135 lttv_hooks_destroy(tfc->check_event);
136 lttv_hooks_destroy(tfc->before_event);
137 lttv_hooks_by_id_destroy(tfc->before_event_by_id);
138 lttv_hooks_destroy(tfc->after_event);
139 lttv_hooks_by_id_destroy(tfc->after_event_by_id);
140 g_object_unref(tfc->attributes);
141 g_object_unref(tfc);
142 }
143 g_free(tc->control_tracefiles);
144 g_free(tc->per_cpu_tracefiles);
145 g_object_unref(tc);
146 }
147 g_free(self->traces);
148}
149
150
151void lttv_traceset_context_add_hooks(LttvTracesetContext *self,
152 LttvHooks *before_traceset,
153 LttvHooks *after_traceset,
154 LttvHooks *check_trace,
155 LttvHooks *before_trace,
156 LttvHooks *after_trace,
157 LttvHooks *check_event,
158 LttvHooks *before_event,
159 LttvHooks *after_event)
160{
161 LttvTraceset *ts = self->ts;
162
163 guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
164
165 LttvTraceContext *tc;
166
167 LttvTracefileContext *tfc;
168
169 void *hook_data;
170
171 lttv_hooks_add_list(self->before, before_traceset);
172 lttv_hooks_add_list(self->after, after_traceset);
173 nb_trace = lttv_traceset_number(ts);
174
175 for(i = 0 ; i < nb_trace ; i++) {
176 tc = self->traces[i];
177 lttv_hooks_add_list(tc->check, check_trace);
178 lttv_hooks_add_list(tc->before, before_trace);
179 lttv_hooks_add_list(tc->after, after_trace);
180 nb_control = ltt_trace_control_tracefile_number(tc->t);
181 nb_per_cpu = ltt_trace_control_tracefile_number(tc->t);
182 nb_tracefile = nb_control + nb_per_cpu;
183
184 for(j = 0 ; j < nb_tracefile ; j++) {
185 if(j < nb_control) {
186 tfc = tc->control_tracefiles[j];
187 }
188 else {
189 tfc = tc->per_cpu_tracefiles[j];
190 }
191 lttv_hooks_add_list(tfc->check, check_tracefile);
192 lttv_hooks_add_list(tfc->before, before_tracefile);
193 lttv_hooks_add_list(tfc->after, after_tracefile);
194 lttv_hooks_add_list(tfc->check_event, check_event);
195 lttv_hooks_add_list(tfc->before_event, before_event);
196 lttv_hooks_add_list(tfc->after_event, after_event);
197 }
198 }
199}
200
201
202void lttv_traceset_context_remove_hooks(LttvTracesetContext *self,
203 LttvHooks *before_traceset,
204 LttvHooks *after_traceset,
205 LttvHooks *check_trace,
206 LttvHooks *before_trace,
207 LttvHooks *after_trace,
208 LttvHooks *check_event,
209 LttvHooks *before_event,
210 LttvHooks *after_event)
211{
212 LttvTraceset *ts = self->ts;
213
214 guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
215
216 LttvTraceContext *tc;
217
218 LttvTracefileContext *tfc;
219
220 void *hook_data;
221
222 lttv_hooks_remove_list(self->before, before_traceset);
223 lttv_hooks_remove_list(self->after, after_traceset);
224 nb_trace = lttv_traceset_number(ts);
225
226 for(i = 0 ; i < nb_trace ; i++) {
227 tc = self->traces[i];
228 lttv_hooks_remove_list(tc->check, check_trace);
229 lttv_hooks_remove_list(tc->before, before_trace);
230 lttv_hooks_remove_list(tc->after, after_trace);
231 nb_control = ltt_trace_control_tracefile_number(tc->t);
232 nb_per_cpu = ltt_trace_control_tracefile_number(tc->t);
233 nb_tracefile = nb_control + nb_per_cpu;
234
235 for(j = 0 ; j < nb_tracefile ; j++) {
236 if(j < nb_control) {
237 tfc = tc->control_tracefiles[j];
238 }
239 else {
240 tfc = tc->per_cpu_tracefiles[j];
241 }
242 lttv_hooks_remove_list(tfc->check, check_tracefile);
243 lttv_hooks_remove_list(tfc->before, before_tracefile);
244 lttv_hooks_remove_list(tfc->after, after_tracefile);
245 lttv_hooks_remove_list(tfc->check_event, check_event);
246 lttv_hooks_remove_list(tfc->before_event, before_event);
247 lttv_hooks_remove_list(tfc->after_event, after_event);
248 }
249 }
250}
251
252
253LttvTracesetContext *
254new_traceset_context(LttvTracesetContext *self)
255{
256 return g_object_new(LTTV_TRACESET_CONTEXT_TYPE);
257}
258
259
260LttvTraceContext *
261new_trace_context(LttvTracesetContext *self)
262{
263 return g_object_new(LTTV_TRACE_CONTEXT_TYPE);
264}
265
266
267LttvTracefileContext *
268new_tracefile_context(LttvTracesetContext *self)
269{
270 return g_object_new(LTTV_TRACEFILE_CONTEXT_TYPE);
271}
272
273
274GType
275lttv_traceset_context_get_type(void)
276{
277 static GType type = 0;
278 if (type == 0) {
279 static const GTypeInfo info = {
280 sizeof (LttvTracesetContextClass),
281 NULL, /* base_init */
282 NULL, /* base_finalize */
283 traceset_context_class_init, /* class_init */
284 NULL, /* class_finalize */
285 NULL, /* class_data */
286 sizeof (LttvTracesetContext),
287 0, /* n_preallocs */
288 traceset_context_instance_init /* instance_init */
289 };
290
291 type = g_type_register_static (G_TYPE_OBJECT, "LttvTracesetContextType",
292 &info, 0);
293 }
294 return type;
295}
296
297
298static void
299traceset_context_instance_init (GTypeInstance *instance, gpointer g_class)
300{
301 /* Be careful of anything which would not work well with shallow copies */
302}
303
304
305static void
306traceset_context_finalize (LttvTracesetContext *self)
307{
308 G_OBJECT_CLASS(g_type_class_peek_parent(LTTV_TRACESET_CONTEXT_TYPE))->finalize(self);
309}
310
311
312static void
313traceset_context_class_init (LttvTracesetContextClass *klass)
314{
315 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
316
317 gobject_class->finalize = traceset_context_finalize;
318 klass->init = init;
319 klass->fini = fini;
320 klass->new_traceset_context = new_traceset_context;
321 klass->new_trace_context = new_trace_context;
322 klass->new_tracefile_context = new_tracefile_context;
323}
324
325
326GType
327lttv_trace_context_get_type(void)
328{
329 static GType type = 0;
330 if (type == 0) {
331 static const GTypeInfo info = {
332 sizeof (LttvTraceContextClass),
333 NULL, /* base_init */
334 NULL, /* base_finalize */
335 trace_context_class_init, /* class_init */
336 NULL, /* class_finalize */
337 NULL, /* class_data */
338 sizeof (LttvTraceSetContext),
339 0, /* n_preallocs */
340 trace_context_instance_init /* instance_init */
341 };
342
343 type = g_type_register_static (G_TYPE_OBJECT, "LttvTraceContextType",
344 &info, 0);
345 }
346 return type;
347}
348
349
350static void
351trace_context_instance_init (GTypeInstance *instance, gpointer g_class)
352{
353 /* Be careful of anything which would not work well with shallow copies */
354}
355
356
357static void
358trace_context_finalize (LttvTraceContext *self)
359{
360 G_OBJECT_CLASS(g_type_class_peek_parent(LTTV_TRACE_CONTEXT_TYPE))->finalize(self);
361}
362
363
364static void
365trace_context_class_init (LttvTraceContextClass *klass)
366{
367 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
368
369 gobject_class->finalize = trace_context_finalize;
370}
371
372
373GType
374lttv_tracefile_context_get_type(void)
375{
376 static GType type = 0;
377 if (type == 0) {
378 static const GTypeInfo info = {
379 sizeof (LttvTracefileContextClass),
380 NULL, /* base_init */
381 NULL, /* base_finalize */
382 tracefile_context_class_init, /* class_init */
383 NULL, /* class_finalize */
384 NULL, /* class_data */
385 sizeof (LttvTracefileContext),
386 0, /* n_preallocs */
387 tracefile_context_instance_init /* instance_init */
388 };
389
390 type = g_type_register_static (G_TYPE_OBJECT, "LttvTracefileContextType",
391 &info, 0);
392 }
393 return type;
394}
395
396
397static void
398tracefile_context_instance_init (GTypeInstance *instance, gpointer g_class)
399{
400 /* Be careful of anything which would not work well with shallow copies */
401}
402
403
404static void
405tracefile_context_finalize (LttvTracefileContext *self)
406{
407 G_OBJECT_CLASS(g_type_class_peek_parent(LTTV_TRACEFILE_CONTEXT_TYPE))->finalize(self);
408}
409
410
411static void
412tracefile_context_class_init (LttvTracefileContextClass *klass)
413{
414 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
415
416 gobject_class->finalize = tracefile_context_finalize;
417}
418
419
420guint compare_tracefile(gconstpointer a, gconstpointer b)
421{
422 if((LttvTime *)a->tv_sec > (LttvTime *)b->tv_sec) return 1;
423 if((LttvTime *)a->tv_sec < (LttvTime *)b->tv_sec) return -1;
424 if((LttvTime *)a->tv_nsec > (LttvTime *)b->tv_nsec) return 1;
425 if((LttvTime *)a->tv_nsec < (LttvTime *)b->tv_nsec) return -1;
426 return 0;
427}
428
429
430gboolean get_first(gpointer key, gpointer value, gpointer user_data) {
431 *((LttvTracefileContext **)user_data) = (LttvTracefileContext *)value;
432 return TRUE;
433}
434
435
436void lttv_process_trace(LttvTime start, LttvTime end, LttvTraceset *traceset,
437 LttvTracesetContext *context)
438{
439 GPtrArray *traces = g_ptr_array_new();
440
441 GPtrArray *tracefiles = g_ptr_array_new();
442
443 GTree *pqueue = g_tree_new(compare_tracefile);
444
445 guint i, j, nbi, nbj, id;
446
447 LttTrace *trace;
448
449 LttvTraceContext *tc;
450
451 LttTracefile *tracefile;
452
453 LttvTracefileContext *tfc;
454
455 LttEvent *event;
456
457 /* Call all before_traceset, before_trace, and before_tracefile hooks.
458 For all qualifying tracefiles, seek to the start time, create a context,
459 read one event and insert in the pqueue based on the event time. */
460
461 lttv_hooks_call(context->before, context);
462 nbi = ltt_trace_set_number(traceset);
463
464 for(i = 0 ; i < nbi ; i++) {
465 tc = context->traces[i];
466 trace = tc->t;
467
468 if(!lttv_hooks_call_check(tc->check, tc)) {
469 g_ptr_array_add(traces, tc);
470 lttv_hooks_call(tc->before, tc);
471 nb_control = ltt_trace_control_tracefile_number(trace);
472 nb_cpu = ltt_trace_per_cpu_tracefile_number(trace);
473 nbj = nb_control + nb_cpu;
474
475 for(j = 0 ; j < nbj ; j++) {
476 if(j < nb_control) {
477 tfc = tc->control_tracefiles[j];
478 }
479 else {
480 tfc = tc->per_cpu_tracefiles[j - nb_control];
481 }
482
483 tracefile = tfc->tf;
484
485 if(!lttv_hooks_call_check(tfc->check, tfc)) {
486 g_ptr_array_add(tracefiles, tfc);
487 lttv_hooks_call(tfc->before, tfc);
488
489 ltt_tracefile_seek_time(tracefile, start);
490 event = ltt_tracefile_read(tracefile);
491 tfc->e = event;
492
493 if(event != NULL) {
494 tfc->time = ltt_event_time(event);
495 g_tree_insert(pqueue, &(tfc->time), tfc);
496 }
497 }
498 }
499 }
500 }
501
502 /* Get the next event from the pqueue, call its hooks,
503 reinsert in the pqueue the following event from the same tracefile
504 unless the tracefile is finished or the event is later than the
505 start time. */
506
507 while() {
508 tfc = NULL;
509 g_tree_foreach(pqueue, get_first, &tfc);
510 if(tfc == NULL) break;
511
512 /* Get the tracefile with an event for the smallest time found. If two
513 or more tracefiles have events for the same time, hope that lookup
514 and remove are consistent. */
515
516 tfc = g_tree_lookup(pqueue, &(tfc->time));
517 g_tree_remove(pqueue, &(tfc->time));
518
519 if(!lttv_hooks_call(tfc->check_event, context)) {
520 id = lttv_event_id(tfc->e);
521 lttv_hooks_call(tfc->before_event, tfc);
522 lttv_hooks_call(lttv_hooks_by_id_get(tfc->before_event_by_id, id), tfc);
523 lttv_hooks_call(tfc->after_event, context);
524 lttv_hooks_call(lttv_hooks_by_id_get(tfc->after_event_by_id, id), tfc);
525 }
526
527 event = ltt_tracefile_read(tfc->tf);
528 if(event != NULL) {
529 tfc->e = event;
530 tfc->time = ltt_event_time(event);
531 g_tree_insert(pqueue, &(tfc->time), tfc);
532 }
533 }
534
535 /* Call all the after_tracefile, after_trace and after_traceset hooks. */
536
537 for(i = 0, j = 0 ; i < traces->len ; i++) {
538 tc = traces->pdata[i];
539 while(j < tracefiles->len) {
540 tfc = tracefiles->pdata[j];
541
542 if(tfc->t_context == tc) {
543 lttv_hooks_call(tfc->after, tfc);
544 j++;
545 }
546 else break;
547 }
548 lttv_hooks_call(tc->after, tc);
549 }
550
551 g_assert(j == tracefiles->len);
552 lttv_hooks_call(after_traceset, context);
553
554 /* Free the traces, tracefiles and pqueue */
555
556 g_ptr_array_free(tracefiles, TRUE);
557 g_ptr_array_free(traces, TRUE);
558 g_tree_destroy(pqueue, TRUE);
559}
This page took 0.040778 seconds and 4 git commands to generate.