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