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