git-svn-id: http://ltt.polymtl.ca/svn@309 04897980-b3bd-0310-b5e0-8ef037075253
[lttv.git] / ltt / branches / poly / lttv / processTrace.c
1
2 #include <lttv/processTrace.h>
3 #include <ltt/event.h>
4 #include <ltt/facility.h>
5
6 void lttv_context_init(LttvTracesetContext *self, LttvTraceset *ts)
7 {
8 LTTV_TRACESET_CONTEXT_GET_CLASS(self)->init(self, ts);
9 }
10
11
12 void lttv_context_fini(LttvTracesetContext *self)
13 {
14 LTTV_TRACESET_CONTEXT_GET_CLASS(self)->fini(self);
15 }
16
17
18 LttvTracesetContext *
19 lttv_context_new_traceset_context(LttvTracesetContext *self)
20 {
21 return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_traceset_context(self);
22 }
23
24
25
26
27 LttvTraceContext *
28 lttv_context_new_trace_context(LttvTracesetContext *self)
29 {
30 return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self);
31 }
32
33
34 LttvTracefileContext *
35 lttv_context_new_tracefile_context(LttvTracesetContext *self)
36 {
37 return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self);
38 }
39
40 /****************************************************************************
41 * lttv_traceset_context_compute_time_span
42 *
43 * Keep the Time_Span is sync with on the fly addition and removal of traces
44 * in a trace set. It must be called each time a trace is added/removed from
45 * the traceset. It could be more efficient to call it only once a bunch
46 * of traces are loaded, but the calculation is not long, so it's not
47 * critical.
48 *
49 * Author : Xang Xiu Yang
50 * Imported from gtkTraceSet.c by Mathieu Desnoyers
51 ***************************************************************************/
52 static void lttv_traceset_context_compute_time_span(
53 LttvTracesetContext *self,
54 TimeInterval *Time_Span)
55 {
56 LttvTraceset * traceset = self->ts;
57 int numTraces = lttv_traceset_number(traceset);
58 int i;
59 LttTime s, e;
60 LttvTraceContext *tc;
61 LttTrace * trace;
62
63 for(i=0; i<numTraces;i++){
64 tc = self->traces[i];
65 trace = tc->t;
66
67 ltt_trace_time_span_get(trace, &s, &e);
68
69 if(i==0){
70 Time_Span->startTime = s;
71 Time_Span->endTime = e;
72 }else{
73 if(s.tv_sec < Time_Span->startTime.tv_sec ||
74 (s.tv_sec == Time_Span->startTime.tv_sec
75 && s.tv_nsec < Time_Span->startTime.tv_nsec))
76 Time_Span->startTime = s;
77 if(e.tv_sec > Time_Span->endTime.tv_sec ||
78 (e.tv_sec == Time_Span->endTime.tv_sec &&
79 e.tv_nsec > Time_Span->endTime.tv_nsec))
80 Time_Span->endTime = e;
81 }
82 }
83 }
84
85
86 static void
87 init(LttvTracesetContext *self, LttvTraceset *ts)
88 {
89 guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
90
91 LttvTraceContext *tc;
92
93 LttvTracefileContext *tfc;
94
95 LttTime null_time = {0, 0};
96
97 nb_trace = lttv_traceset_number(ts);
98 self->ts = ts;
99 self->traces = g_new(LttvTraceContext *, nb_trace);
100 self->before = lttv_hooks_new();
101 self->after = lttv_hooks_new();
102 self->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
103 self->ts_a = lttv_traceset_attribute(ts);
104 for(i = 0 ; i < nb_trace ; i++) {
105 tc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self);
106 self->traces[i] = tc;
107
108 tc->ts_context = self;
109 tc->index = i;
110 tc->vt = lttv_traceset_get(ts, i);
111 tc->t = lttv_trace(tc->vt);
112 tc->check = lttv_hooks_new();
113 tc->before = lttv_hooks_new();
114 tc->after = lttv_hooks_new();
115 tc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
116 tc->t_a = lttv_trace_attribute(tc->vt);
117 nb_control = ltt_trace_control_tracefile_number(tc->t);
118 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
119 nb_tracefile = nb_control + nb_per_cpu;
120 tc->control_tracefiles = g_new(LttvTracefileContext *, nb_control);
121 tc->per_cpu_tracefiles = g_new(LttvTracefileContext *, nb_per_cpu);
122
123 for(j = 0 ; j < nb_tracefile ; j++) {
124 tfc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self);
125 if(j < nb_control) {
126 tc->control_tracefiles[j] = tfc;
127 tfc->control = TRUE;
128 tfc->index = j;
129 tfc->tf = ltt_trace_control_tracefile_get(tc->t, j);
130 }
131 else {
132 tc->per_cpu_tracefiles[j - nb_control] = tfc;
133 tfc->control = FALSE;
134 tfc->index = j - nb_control;
135 tfc->tf = ltt_trace_per_cpu_tracefile_get(tc->t, j - nb_control);
136 }
137 tfc->t_context = tc;
138 tfc->check = lttv_hooks_new();
139 tfc->before = lttv_hooks_new();
140 tfc->after = lttv_hooks_new();
141 tfc->check_event = lttv_hooks_new();
142 tfc->before_event = lttv_hooks_new();
143 tfc->before_event_by_id = lttv_hooks_by_id_new();
144 tfc->after_event = lttv_hooks_new();
145 tfc->after_event_by_id = lttv_hooks_by_id_new();
146 tfc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
147 }
148 }
149 lttv_process_traceset_seek_time(self, null_time);
150 /*CHECK why dynamically allocate the time span... and the casing is wroNg*/
151 self->Time_Span = g_new(TimeInterval,1);
152 lttv_traceset_context_compute_time_span(self, self->Time_Span);
153 }
154
155
156 void fini(LttvTracesetContext *self)
157 {
158 guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
159
160 LttvTraceContext *tc;
161
162 LttvTracefileContext *tfc;
163
164 LttvTraceset *ts = self->ts;
165
166 g_free(self->Time_Span);
167
168 lttv_hooks_destroy(self->before);
169 lttv_hooks_destroy(self->after);
170 //FIXME : segfault
171 g_object_unref(self->a);
172
173 nb_trace = lttv_traceset_number(ts);
174
175 for(i = 0 ; i < nb_trace ; i++) {
176 tc = self->traces[i];
177
178 lttv_hooks_destroy(tc->check);
179 lttv_hooks_destroy(tc->before);
180 lttv_hooks_destroy(tc->after);
181 g_object_unref(tc->a);
182
183 nb_control = ltt_trace_control_tracefile_number(tc->t);
184 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
185 nb_tracefile = nb_control + nb_per_cpu;
186
187 for(j = 0 ; j < nb_tracefile ; j++) {
188 if(j < nb_control) tfc = tc->control_tracefiles[j];
189 else tfc = tc->per_cpu_tracefiles[j - nb_control];
190
191 lttv_hooks_destroy(tfc->check);
192 lttv_hooks_destroy(tfc->before);
193 lttv_hooks_destroy(tfc->after);
194 lttv_hooks_destroy(tfc->check_event);
195 lttv_hooks_destroy(tfc->before_event);
196 lttv_hooks_by_id_destroy(tfc->before_event_by_id);
197 lttv_hooks_destroy(tfc->after_event);
198 lttv_hooks_by_id_destroy(tfc->after_event_by_id);
199 g_object_unref(tfc->a);
200 g_object_unref(tfc);
201 }
202 g_free(tc->control_tracefiles);
203 g_free(tc->per_cpu_tracefiles);
204 g_object_unref(tc);
205 }
206 g_free(self->traces);
207 }
208
209
210 void lttv_traceset_context_add_hooks(LttvTracesetContext *self,
211 LttvHooks *before_traceset,
212 LttvHooks *after_traceset,
213 LttvHooks *check_trace,
214 LttvHooks *before_trace,
215 LttvHooks *after_trace,
216 LttvHooks *check_tracefile,
217 LttvHooks *before_tracefile,
218 LttvHooks *after_tracefile,
219 LttvHooks *check_event,
220 LttvHooks *before_event,
221 LttvHooks *after_event)
222 {
223 LttvTraceset *ts = self->ts;
224
225 guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
226
227 LttvTraceContext *tc;
228
229 LttvTracefileContext *tfc;
230
231 void *hook_data;
232
233 lttv_hooks_add_list(self->before, before_traceset);
234 lttv_hooks_add_list(self->after, after_traceset);
235 nb_trace = lttv_traceset_number(ts);
236
237 for(i = 0 ; i < nb_trace ; i++) {
238 tc = self->traces[i];
239 lttv_hooks_add_list(tc->check, check_trace);
240 lttv_hooks_add_list(tc->before, before_trace);
241 lttv_hooks_add_list(tc->after, after_trace);
242 nb_control = ltt_trace_control_tracefile_number(tc->t);
243 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
244 nb_tracefile = nb_control + nb_per_cpu;
245
246 for(j = 0 ; j < nb_tracefile ; j++) {
247 if(j < nb_control) {
248 tfc = tc->control_tracefiles[j];
249 }
250 else {
251 tfc = tc->per_cpu_tracefiles[j-nb_control];
252 }
253 lttv_hooks_add_list(tfc->check, check_tracefile);
254 lttv_hooks_add_list(tfc->before, before_tracefile);
255 lttv_hooks_add_list(tfc->after, after_tracefile);
256 lttv_hooks_add_list(tfc->check_event, check_event);
257 lttv_hooks_add_list(tfc->before_event, before_event);
258 lttv_hooks_add_list(tfc->after_event, after_event);
259 }
260 }
261 }
262
263
264 void lttv_traceset_context_remove_hooks(LttvTracesetContext *self,
265 LttvHooks *before_traceset,
266 LttvHooks *after_traceset,
267 LttvHooks *check_trace,
268 LttvHooks *before_trace,
269 LttvHooks *after_trace,
270 LttvHooks *check_tracefile,
271 LttvHooks *before_tracefile,
272 LttvHooks *after_tracefile,
273 LttvHooks *check_event,
274 LttvHooks *before_event,
275 LttvHooks *after_event)
276 {
277 LttvTraceset *ts = self->ts;
278
279 guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
280
281 LttvTraceContext *tc;
282
283 LttvTracefileContext *tfc;
284
285 void *hook_data;
286
287 lttv_hooks_remove_list(self->before, before_traceset);
288 lttv_hooks_remove_list(self->after, after_traceset);
289 nb_trace = lttv_traceset_number(ts);
290
291 for(i = 0 ; i < nb_trace ; i++) {
292 tc = self->traces[i];
293 lttv_hooks_remove_list(tc->check, check_trace);
294 lttv_hooks_remove_list(tc->before, before_trace);
295 lttv_hooks_remove_list(tc->after, after_trace);
296 nb_control = ltt_trace_control_tracefile_number(tc->t);
297 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
298 nb_tracefile = nb_control + nb_per_cpu;
299
300 for(j = 0 ; j < nb_tracefile ; j++) {
301 if(j < nb_control) {
302 tfc = tc->control_tracefiles[j];
303 }
304 else {
305 tfc = tc->per_cpu_tracefiles[j-nb_control];
306 }
307 lttv_hooks_remove_list(tfc->check, check_tracefile);
308 lttv_hooks_remove_list(tfc->before, before_tracefile);
309 lttv_hooks_remove_list(tfc->after, after_tracefile);
310 lttv_hooks_remove_list(tfc->check_event, check_event);
311 lttv_hooks_remove_list(tfc->before_event, before_event);
312 lttv_hooks_remove_list(tfc->after_event, after_event);
313 }
314 }
315 }
316
317
318 static LttvTracesetContext *
319 new_traceset_context(LttvTracesetContext *self)
320 {
321 return g_object_new(LTTV_TRACESET_CONTEXT_TYPE, NULL);
322 }
323
324
325 static LttvTraceContext *
326 new_trace_context(LttvTracesetContext *self)
327 {
328 return g_object_new(LTTV_TRACE_CONTEXT_TYPE, NULL);
329 }
330
331
332 static LttvTracefileContext *
333 new_tracefile_context(LttvTracesetContext *self)
334 {
335 return g_object_new(LTTV_TRACEFILE_CONTEXT_TYPE, NULL);
336 }
337
338
339 static void
340 traceset_context_instance_init (GTypeInstance *instance, gpointer g_class)
341 {
342 /* Be careful of anything which would not work well with shallow copies */
343 }
344
345
346 static void
347 traceset_context_finalize (LttvTracesetContext *self)
348 {
349 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACESET_CONTEXT_TYPE)))
350 ->finalize(G_OBJECT(self));
351 }
352
353
354 static void
355 traceset_context_class_init (LttvTracesetContextClass *klass)
356 {
357 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
358
359 gobject_class->finalize = (void (*)(GObject *self))traceset_context_finalize;
360 klass->init = init;
361 klass->fini = fini;
362 klass->new_traceset_context = new_traceset_context;
363 klass->new_trace_context = new_trace_context;
364 klass->new_tracefile_context = new_tracefile_context;
365 }
366
367
368 GType
369 lttv_traceset_context_get_type(void)
370 {
371 static GType type = 0;
372 if (type == 0) {
373 static const GTypeInfo info = {
374 sizeof (LttvTracesetContextClass),
375 NULL, /* base_init */
376 NULL, /* base_finalize */
377 (GClassInitFunc) traceset_context_class_init, /* class_init */
378 NULL, /* class_finalize */
379 NULL, /* class_data */
380 sizeof (LttvTracesetContext),
381 0, /* n_preallocs */
382 (GInstanceInitFunc) traceset_context_instance_init /* instance_init */
383 };
384
385 type = g_type_register_static (G_TYPE_OBJECT, "LttvTracesetContextType",
386 &info, 0);
387 }
388 return type;
389 }
390
391
392 static void
393 trace_context_instance_init (GTypeInstance *instance, gpointer g_class)
394 {
395 /* Be careful of anything which would not work well with shallow copies */
396 }
397
398
399 static void
400 trace_context_finalize (LttvTraceContext *self)
401 {
402 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACE_CONTEXT_TYPE)))->
403 finalize(G_OBJECT(self));
404 }
405
406
407 static void
408 trace_context_class_init (LttvTraceContextClass *klass)
409 {
410 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
411
412 gobject_class->finalize = (void (*)(GObject *self)) trace_context_finalize;
413 }
414
415
416 GType
417 lttv_trace_context_get_type(void)
418 {
419 static GType type = 0;
420 if (type == 0) {
421 static const GTypeInfo info = {
422 sizeof (LttvTraceContextClass),
423 NULL, /* base_init */
424 NULL, /* base_finalize */
425 (GClassInitFunc) trace_context_class_init, /* class_init */
426 NULL, /* class_finalize */
427 NULL, /* class_data */
428 sizeof (LttvTraceContext),
429 0, /* n_preallocs */
430 (GInstanceInitFunc) trace_context_instance_init /* instance_init */
431 };
432
433 type = g_type_register_static (G_TYPE_OBJECT, "LttvTraceContextType",
434 &info, 0);
435 }
436 return type;
437 }
438
439
440 static void
441 tracefile_context_instance_init (GTypeInstance *instance, gpointer g_class)
442 {
443 /* Be careful of anything which would not work well with shallow copies */
444 }
445
446
447 static void
448 tracefile_context_finalize (LttvTracefileContext *self)
449 {
450 G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACEFILE_CONTEXT_TYPE)))
451 ->finalize(G_OBJECT(self));
452 }
453
454
455 static void
456 tracefile_context_class_init (LttvTracefileContextClass *klass)
457 {
458 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
459
460 gobject_class->finalize = (void (*)(GObject *self))tracefile_context_finalize;
461 }
462
463
464 GType
465 lttv_tracefile_context_get_type(void)
466 {
467 static GType type = 0;
468 if (type == 0) {
469 static const GTypeInfo info = {
470 sizeof (LttvTracefileContextClass),
471 NULL, /* base_init */
472 NULL, /* base_finalize */
473 (GClassInitFunc) tracefile_context_class_init, /* class_init */
474 NULL, /* class_finalize */
475 NULL, /* class_data */
476 sizeof (LttvTracefileContext),
477 0, /* n_preallocs */
478 (GInstanceInitFunc) tracefile_context_instance_init /* instance_init */
479 };
480
481 type = g_type_register_static (G_TYPE_OBJECT, "LttvTracefileContextType",
482 &info, 0);
483 }
484 return type;
485 }
486
487
488 gint compare_tracefile(gconstpointer a, gconstpointer b)
489 {
490 return ltt_time_compare(*((LttTime *)a), *((LttTime *)b));
491 }
492
493
494 gboolean get_first(gpointer key, gpointer value, gpointer user_data) {
495 *((LttvTracefileContext **)user_data) = (LttvTracefileContext *)value;
496 return TRUE;
497 }
498
499
500 void lttv_process_traceset(LttvTracesetContext *self, LttTime end,
501 unsigned maxNumEvents)
502 {
503 GPtrArray *traces = g_ptr_array_new();
504
505 GPtrArray *tracefiles = g_ptr_array_new();
506
507 GTree *pqueue = g_tree_new(compare_tracefile);
508
509 guint i, j, nbi, nbj, id, nb_control, nb_cpu;
510
511 LttTrace *trace;
512
513 LttvTraceContext *tc;
514
515 LttTracefile *tracefile;
516
517 LttvTracefileContext *tfc;
518
519 LttEvent *event;
520
521 unsigned count = 0;
522
523 LttTime previous_timestamp = {0, 0};
524
525 /* Call all before_traceset, before_trace, and before_tracefile hooks.
526 For all qualifying tracefiles, seek to the start time, create a context,
527 read one event and insert in the pqueue based on the event time. */
528
529 lttv_hooks_call(self->before, self);
530 nbi = lttv_traceset_number(self->ts);
531
532 for(i = 0 ; i < nbi ; i++) {
533 tc = self->traces[i];
534 trace = tc->t;
535
536 if(!lttv_hooks_call_check(tc->check, tc)) {
537 g_ptr_array_add(traces, tc);
538 lttv_hooks_call(tc->before, tc);
539 nb_control = ltt_trace_control_tracefile_number(trace);
540 nb_cpu = ltt_trace_per_cpu_tracefile_number(trace);
541 nbj = nb_control + nb_cpu;
542
543 for(j = 0 ; j < nbj ; j++) {
544 if(j < nb_control) {
545 tfc = tc->control_tracefiles[j];
546 }
547 else {
548 tfc = tc->per_cpu_tracefiles[j - nb_control];
549 }
550
551 tracefile = tfc->tf;
552
553 if(!lttv_hooks_call_check(tfc->check, tfc)) {
554 g_ptr_array_add(tracefiles, tfc);
555 lttv_hooks_call(tfc->before, tfc);
556
557 if(event != NULL) {
558 g_tree_insert(pqueue, &(tfc->timestamp), tfc);
559 }
560 }
561 }
562 }
563 }
564
565 /* Get the next event from the pqueue, call its hooks,
566 reinsert in the pqueue the following event from the same tracefile
567 unless the tracefile is finished or the event is later than the
568 start time. */
569
570 while(TRUE) {
571 tfc = NULL;
572 g_tree_foreach(pqueue, get_first, &tfc);
573 if(tfc == NULL) break;
574
575 /* Have we reached the maximum number of events specified? However,
576 continue for all the events with the same time stamp (CHECK?). Then,
577 empty the queue and break from the loop. */
578
579 count++;
580 if(count > maxNumEvents){
581 if(tfc->timestamp.tv_sec == previous_timestamp.tv_sec &&
582 tfc->timestamp.tv_nsec == previous_timestamp.tv_nsec) {
583 count--;
584 }else{
585 while(TRUE){
586 tfc = NULL;
587 g_tree_foreach(pqueue, get_first, &tfc);
588 if(tfc == NULL) break;
589 g_tree_remove(pqueue, &(tfc->timestamp));
590 }
591 break;
592 }
593 }
594 previous_timestamp = tfc->timestamp;
595
596
597 /* Get the tracefile with an event for the smallest time found. If two
598 or more tracefiles have events for the same time, hope that lookup
599 and remove are consistent. */
600
601 tfc = g_tree_lookup(pqueue, &(tfc->timestamp));
602 g_tree_remove(pqueue, &(tfc->timestamp));
603
604 if(!lttv_hooks_call(tfc->check_event, tfc)) {
605 id = ltt_event_eventtype_id(tfc->e);
606 lttv_hooks_call(tfc->before_event, tfc);
607 lttv_hooks_call(lttv_hooks_by_id_get(tfc->before_event_by_id, id), tfc);
608 lttv_hooks_call(tfc->after_event, tfc);
609 lttv_hooks_call(lttv_hooks_by_id_get(tfc->after_event_by_id, id), tfc);
610 }
611
612 event = ltt_tracefile_read(tfc->tf);
613 if(event != NULL) {
614 tfc->e = event;
615 tfc->timestamp = ltt_event_time(event);
616 if(tfc->timestamp.tv_sec < end.tv_sec ||
617 (tfc->timestamp.tv_sec == end.tv_sec && tfc->timestamp.tv_nsec <= end.tv_nsec))
618 g_tree_insert(pqueue, &(tfc->timestamp), tfc);
619 }
620 }
621
622 /* Call all the after_tracefile, after_trace and after_traceset hooks. */
623
624 for(i = 0, j = 0 ; i < traces->len ; i++) {
625 tc = traces->pdata[i];
626 while(j < tracefiles->len) {
627 tfc = tracefiles->pdata[j];
628
629 if(tfc->t_context == tc) {
630 lttv_hooks_call(tfc->after, tfc);
631 j++;
632 }
633 else break;
634 }
635 lttv_hooks_call(tc->after, tc);
636 }
637
638 g_assert(j == tracefiles->len);
639 lttv_hooks_call(self->after, self);
640
641 /* Free the traces, tracefiles and pqueue */
642
643 g_ptr_array_free(tracefiles, TRUE);
644 g_ptr_array_free(traces, TRUE);
645 g_tree_destroy(pqueue);
646 }
647
648
649 void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start)
650 {
651 guint i, nb_control, nb_per_cpu, nb_tracefile;
652
653 LttvTracefileContext *tfc;
654
655 LttEvent *event;
656
657 nb_control = ltt_trace_control_tracefile_number(self->t);
658 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(self->t);
659 nb_tracefile = nb_control + nb_per_cpu;
660 for(i = 0 ; i < nb_tracefile ; i++) {
661 if(i < nb_control) tfc = self->control_tracefiles[i];
662 else tfc = self->per_cpu_tracefiles[i - nb_control];
663
664 ltt_tracefile_seek_time(tfc->tf, start);
665 event = ltt_tracefile_read(tfc->tf);
666 tfc->e = event;
667 if(event != NULL) tfc->timestamp = ltt_event_time(event);
668 }
669 }
670
671
672 void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start)
673 {
674 guint i, nb_trace;
675
676 LttvTraceContext *tc;
677
678 nb_trace = lttv_traceset_number(self->ts);
679 for(i = 0 ; i < nb_trace ; i++) {
680 tc = self->traces[i];
681 lttv_process_trace_seek_time(tc, start);
682 }
683 }
684
685
686 static LttField *
687 find_field(LttEventType *et, const char *field)
688 {
689 LttType *t;
690
691 LttField *f;
692
693 guint i, nb;
694
695 char *name;
696
697 if(field == NULL) return NULL;
698
699 f = ltt_eventtype_field(et);
700 t = ltt_eventtype_type(et);
701 g_assert(ltt_type_class(t) == LTT_STRUCT);
702 nb = ltt_type_member_number(t);
703 for(i = 0 ; i < nb ; i++) {
704 ltt_type_member_type(t, i, &name);
705 if(strcmp(name, field) == 0) break;
706 }
707 g_assert(i < nb);
708 return ltt_field_member(f, i);
709 }
710
711
712 void
713 lttv_trace_find_hook(LttTrace *t, char *facility, char *event_type,
714 char *field1, char *field2, char *field3, LttvHook h, LttvTraceHook *th)
715 {
716 LttFacility *f;
717
718 LttEventType *et;
719
720 guint nb, pos, i;
721
722 char *name;
723
724 nb = ltt_trace_facility_find(t, facility, &pos);
725 if(nb < 1) g_error("No %s facility", facility);
726 f = ltt_trace_facility_get(t, pos);
727 et = ltt_facility_eventtype_get_by_name(f, event_type);
728 if(et == NULL) g_error("Event %s does not exist", event_type);
729
730 th->h = h;
731 th->id = ltt_eventtype_id(et);
732 th->f1 = find_field(et, field1);
733 th->f2 = find_field(et, field2);
734 th->f3 = find_field(et, field3);
735 }
736
737
This page took 0.045098 seconds and 4 git commands to generate.