Commit | Line | Data |
---|---|---|
46322b33 MD |
1 | /* |
2 | * babeltrace-lib.c | |
3 | * | |
4 | * Babeltrace Trace Converter Library | |
5 | * | |
6 | * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
7 | * | |
8 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
9 | * of this software and associated documentation files (the "Software"), to deal | |
10 | * in the Software without restriction, including without limitation the rights | |
11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
12 | * copies of the Software, and to permit persons to whom the Software is | |
13 | * furnished to do so, subject to the following conditions: | |
14 | * | |
15 | * The above copyright notice and this permission notice shall be included in | |
16 | * all copies or substantial portions of the Software. | |
17 | */ | |
18 | ||
19 | #include <stdlib.h> | |
20 | #include <errno.h> | |
21 | #include <stdio.h> | |
847bf71a | 22 | #include <inttypes.h> |
46322b33 MD |
23 | #include <babeltrace/babeltrace.h> |
24 | #include <babeltrace/format.h> | |
25 | #include <babeltrace/ctf/types.h> | |
26 | #include <babeltrace/ctf/metadata.h> | |
27 | #include <babeltrace/ctf-text/types.h> | |
0d0f5149 | 28 | #include <babeltrace/prio_heap.h> |
46322b33 | 29 | |
0d0f5149 | 30 | static int read_event(struct ctf_file_stream *sin) |
46322b33 MD |
31 | { |
32 | int ret; | |
33 | ||
0d0f5149 MD |
34 | ret = sin->pos.parent.event_cb(&sin->pos.parent, &sin->stream); |
35 | if (ret == EOF) | |
36 | return EOF; | |
37 | else if (ret) { | |
38 | fprintf(stdout, "[error] Reading event failed.\n"); | |
39 | return ret; | |
46322b33 | 40 | } |
46322b33 | 41 | return 0; |
0d0f5149 | 42 | } |
46322b33 | 43 | |
0d0f5149 MD |
44 | /* |
45 | * returns true if a < b, false otherwise. | |
46 | */ | |
47 | int stream_compare(void *a, void *b) | |
48 | { | |
49 | struct ctf_file_stream *s_a = a, *s_b = b; | |
50 | ||
51 | if (s_a->stream.timestamp < s_b->stream.timestamp) | |
52 | return 1; | |
53 | else | |
54 | return 0; | |
46322b33 MD |
55 | } |
56 | ||
847bf71a MD |
57 | int convert_trace(struct trace_descriptor *td_write, |
58 | struct trace_descriptor *td_read) | |
46322b33 MD |
59 | { |
60 | struct ctf_trace *tin = container_of(td_read, struct ctf_trace, parent); | |
847bf71a MD |
61 | struct ctf_text_stream_pos *sout = |
62 | container_of(td_write, struct ctf_text_stream_pos, trace_descriptor); | |
0d0f5149 MD |
63 | int stream_id; |
64 | int ret = 0; | |
65 | ||
66 | tin->stream_heap = g_new(struct ptr_heap, 1); | |
67 | heap_init(tin->stream_heap, 0, stream_compare); | |
46322b33 | 68 | |
0d0f5149 | 69 | /* Populate heap with each stream */ |
46322b33 | 70 | for (stream_id = 0; stream_id < tin->streams->len; stream_id++) { |
aa6bffae | 71 | struct ctf_stream_class *stream = g_ptr_array_index(tin->streams, stream_id); |
0d0f5149 | 72 | int filenr; |
46322b33 MD |
73 | |
74 | if (!stream) | |
75 | continue; | |
76 | for (filenr = 0; filenr < stream->files->len; filenr++) { | |
77 | struct ctf_file_stream *file_stream = g_ptr_array_index(stream->files, filenr); | |
0d0f5149 MD |
78 | ret = read_event(file_stream); |
79 | if (ret == EOF) { | |
80 | ret = 0; | |
81 | continue; | |
82 | } else if (ret) | |
83 | goto end; | |
84 | /* Add to heap */ | |
85 | ret = heap_insert(tin->stream_heap, file_stream); | |
46322b33 | 86 | if (ret) { |
0d0f5149 MD |
87 | fprintf(stdout, "[error] Out of memory.\n"); |
88 | goto end; | |
46322b33 MD |
89 | } |
90 | } | |
91 | } | |
92 | ||
0d0f5149 MD |
93 | /* Replace heap entries until EOF for each stream (heap empty) */ |
94 | for (;;) { | |
95 | struct ctf_file_stream *file_stream, *removed; | |
96 | ||
97 | file_stream = heap_maximum(tin->stream_heap); | |
98 | if (!file_stream) { | |
99 | /* end of file for all streams */ | |
100 | ret = 0; | |
101 | break; | |
102 | } | |
103 | ret = sout->parent.event_cb(&sout->parent, &file_stream->stream); | |
104 | if (ret) { | |
105 | fprintf(stdout, "[error] Writing event failed.\n"); | |
106 | goto end; | |
107 | } | |
108 | ret = read_event(file_stream); | |
109 | if (ret == EOF) { | |
110 | removed = heap_remove(tin->stream_heap); | |
111 | assert(removed == file_stream); | |
112 | ret = 0; | |
113 | continue; | |
114 | } else if (ret) | |
115 | goto end; | |
116 | /* Reinsert the file stream into the heap, and rebalance. */ | |
117 | removed = heap_replace_max(tin->stream_heap, file_stream); | |
118 | assert(removed == file_stream); | |
119 | } | |
46322b33 | 120 | |
0d0f5149 MD |
121 | end: |
122 | heap_free(tin->stream_heap); | |
123 | g_free(tin->stream_heap); | |
46322b33 MD |
124 | return ret; |
125 | } |