Commit | Line | Data |
---|---|---|
ca9f27f3 FD |
1 | /* |
2 | * Babeltrace - Mapping of IR metadata and data object between input and output | |
3 | * trace | |
4 | * | |
5 | * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation | |
6 | * Copyright (c) 2018 Philippe Proulx <pproulx@efficios.com> | |
7 | * Copyright (c) 2019 Francis Deslauriers <francis.deslauriers@efficios.com> | |
8 | * | |
9 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
10 | * of this software and associated documentation files (the "Software"), to deal | |
11 | * in the Software without restriction, including without limitation the rights | |
12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
13 | * copies of the Software, and to permit persons to whom the Software is | |
14 | * furnished to do so, subject to the following conditions: | |
15 | * | |
16 | * The above copyright notice and this permission notice shall be included in | |
17 | * all copies or substantial portions of the Software. | |
18 | * | |
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
25 | * SOFTWARE. | |
26 | */ | |
27 | ||
91bc8451 | 28 | #define BT_COMP_LOG_SELF_COMP (ir_maps->self_comp) |
3a3d15f3 | 29 | #define BT_LOG_OUTPUT_LEVEL (ir_maps->log_level) |
350ad6c1 | 30 | #define BT_LOG_TAG "PLUGIN/FLT.LTTNG-UTILS.DEBUG-INFO/TRACE-IR-MAPPING" |
d9c39b0a | 31 | #include "logging/comp-logging.h" |
ca9f27f3 | 32 | |
578e048b | 33 | #include "common/assert.h" |
3fadfbc0 | 34 | #include <babeltrace2/babeltrace.h> |
ca9f27f3 FD |
35 | |
36 | #include "debug-info.h" | |
37 | #include "trace-ir-data-copy.h" | |
38 | #include "trace-ir-mapping.h" | |
39 | #include "trace-ir-metadata-copy.h" | |
40 | ||
41 | static | |
42 | bt_trace_class *create_new_mapped_trace_class(struct trace_ir_maps *ir_maps, | |
43 | const bt_trace_class *in_trace_class) | |
44 | { | |
3b34b490 FD |
45 | bt_self_component *self_comp = ir_maps->self_comp; |
46 | enum debug_info_trace_ir_mapping_status status; | |
db5d746d | 47 | struct trace_ir_metadata_maps *metadata_maps; |
ca9f27f3 | 48 | |
91bc8451 | 49 | BT_COMP_LOGD("Creating new mapped trace class: in-tc-addr=%p", in_trace_class); |
ca9f27f3 FD |
50 | |
51 | BT_ASSERT(ir_maps); | |
52 | BT_ASSERT(in_trace_class); | |
53 | ||
db5d746d FD |
54 | metadata_maps = borrow_metadata_maps_from_input_trace_class(ir_maps, |
55 | in_trace_class); | |
56 | ||
57 | BT_ASSERT(!metadata_maps->output_trace_class); | |
58 | ||
ca9f27f3 | 59 | /* Create the ouput trace class. */ |
db5d746d FD |
60 | metadata_maps->output_trace_class = |
61 | bt_trace_class_create(ir_maps->self_comp); | |
62 | if (!metadata_maps->output_trace_class) { | |
3b34b490 FD |
63 | BT_COMP_LOGE_APPEND_CAUSE(self_comp, |
64 | "Error create output trace class"); | |
65 | goto error; | |
ca9f27f3 FD |
66 | } |
67 | ||
db5d746d | 68 | /* Copy the content over and add to the mapping. */ |
3b34b490 | 69 | status = copy_trace_class_content(ir_maps, in_trace_class, |
db5d746d FD |
70 | metadata_maps->output_trace_class, ir_maps->log_level, |
71 | ir_maps->self_comp); | |
3b34b490 FD |
72 | if (status != DEBUG_INFO_TRACE_IR_MAPPING_STATUS_OK) { |
73 | BT_COMP_LOGE_APPEND_CAUSE(self_comp, | |
74 | "Error copy content to output trace class" | |
75 | "in-tc-addr=%p, out-tc-addr=%p", in_trace_class, | |
76 | metadata_maps->output_trace_class); | |
77 | goto error; | |
ca9f27f3 FD |
78 | } |
79 | ||
3b34b490 FD |
80 | BT_COMP_LOGD("Created new mapped trace class: " |
81 | "in-tc-addr=%p, out-tc-addr=%p", | |
db5d746d | 82 | in_trace_class, metadata_maps->output_trace_class); |
ca9f27f3 | 83 | |
3b34b490 FD |
84 | goto end; |
85 | error: | |
86 | BT_TRACE_CLASS_PUT_REF_AND_RESET(metadata_maps->output_trace_class); | |
ca9f27f3 | 87 | end: |
db5d746d | 88 | return metadata_maps->output_trace_class; |
ca9f27f3 FD |
89 | } |
90 | ||
91 | static | |
92 | bt_trace *create_new_mapped_trace(struct trace_ir_maps *ir_maps, | |
93 | const bt_trace *in_trace) | |
94 | { | |
3b34b490 FD |
95 | bt_self_component *self_comp = ir_maps->self_comp; |
96 | enum debug_info_trace_ir_mapping_status status; | |
ca9f27f3 | 97 | struct trace_ir_metadata_maps *metadata_maps; |
8aca077e FD |
98 | const bt_trace_class *in_trace_class; |
99 | bt_trace *out_trace; | |
ca9f27f3 | 100 | |
91bc8451 | 101 | BT_COMP_LOGD("Creating new mapped trace: in-t-addr=%p", in_trace); |
ca9f27f3 FD |
102 | BT_ASSERT(ir_maps); |
103 | BT_ASSERT(in_trace); | |
104 | ||
105 | in_trace_class = bt_trace_borrow_class_const(in_trace); | |
106 | metadata_maps = borrow_metadata_maps_from_input_trace_class(ir_maps, | |
bc463d34 | 107 | in_trace_class); |
ca9f27f3 FD |
108 | |
109 | if (!metadata_maps->output_trace_class) { | |
8aca077e FD |
110 | /* |
111 | * If there is no output trace class yet, create a one and add | |
112 | * it to the mapping. | |
113 | */ | |
ca9f27f3 FD |
114 | metadata_maps->output_trace_class = |
115 | create_new_mapped_trace_class(ir_maps, in_trace_class); | |
116 | if (!metadata_maps->output_trace_class) { | |
3b34b490 FD |
117 | BT_COMP_LOGE_APPEND_CAUSE(self_comp, |
118 | "Error create output trace class"); | |
ca9f27f3 FD |
119 | out_trace = NULL; |
120 | goto end; | |
121 | } | |
122 | } | |
123 | ||
8aca077e | 124 | /* Create the output trace from the output trace class. */ |
ca9f27f3 FD |
125 | out_trace = bt_trace_create(metadata_maps->output_trace_class); |
126 | if (!out_trace) { | |
3b34b490 FD |
127 | BT_COMP_LOGE_APPEND_CAUSE(self_comp, |
128 | "Error create output trace"); | |
ca9f27f3 FD |
129 | goto end; |
130 | } | |
131 | ||
8aca077e | 132 | /* Copy the content over to the output trace. */ |
3b34b490 | 133 | status = copy_trace_content(in_trace, out_trace, ir_maps->log_level, |
91bc8451 | 134 | ir_maps->self_comp); |
3b34b490 FD |
135 | if (status != DEBUG_INFO_TRACE_IR_MAPPING_STATUS_OK) { |
136 | BT_COMP_LOGE_APPEND_CAUSE(self_comp, | |
137 | "Error copy content to output trace" | |
138 | "in-t-addr=%p, out-t-addr=%p", in_trace, out_trace); | |
139 | goto error; | |
140 | } | |
ca9f27f3 | 141 | |
91bc8451 | 142 | BT_COMP_LOGD("Created new mapped trace: in-t-addr=%p, out-t-addr=%p", |
bc463d34 | 143 | in_trace, out_trace); |
3b34b490 FD |
144 | goto end; |
145 | ||
146 | error: | |
147 | BT_TRACE_PUT_REF_AND_RESET(out_trace); | |
ca9f27f3 FD |
148 | end: |
149 | return out_trace; | |
150 | } | |
151 | ||
db5d746d FD |
152 | BT_HIDDEN |
153 | bt_stream_class *trace_ir_mapping_borrow_mapped_stream_class( | |
154 | struct trace_ir_maps *ir_maps, | |
ca9f27f3 FD |
155 | const bt_stream_class *in_stream_class) |
156 | { | |
db5d746d | 157 | BT_ASSERT_DBG(ir_maps); |
98b15851 | 158 | BT_ASSERT_DBG(in_stream_class); |
ca9f27f3 | 159 | |
db5d746d FD |
160 | struct trace_ir_metadata_maps *md_maps = |
161 | borrow_metadata_maps_from_input_stream_class(ir_maps, | |
162 | in_stream_class); | |
ca9f27f3 | 163 | return g_hash_table_lookup(md_maps->stream_class_map, |
bc463d34 | 164 | (gpointer) in_stream_class); |
ca9f27f3 FD |
165 | } |
166 | ||
db5d746d FD |
167 | BT_HIDDEN |
168 | bt_stream_class *trace_ir_mapping_create_new_mapped_stream_class( | |
169 | struct trace_ir_maps *ir_maps, | |
ca9f27f3 FD |
170 | const bt_stream_class *in_stream_class) |
171 | { | |
3b34b490 FD |
172 | bt_self_component *self_comp = ir_maps->self_comp; |
173 | enum debug_info_trace_ir_mapping_status status; | |
ca9f27f3 | 174 | struct trace_ir_metadata_maps *md_maps; |
8aca077e | 175 | bt_stream_class *out_stream_class; |
ca9f27f3 | 176 | |
91bc8451 | 177 | BT_COMP_LOGD("Creating new mapped stream class: in-sc-addr=%p", |
bc463d34 | 178 | in_stream_class); |
ca9f27f3 | 179 | |
8aca077e FD |
180 | BT_ASSERT(ir_maps); |
181 | BT_ASSERT(in_stream_class); | |
db5d746d FD |
182 | BT_ASSERT(!trace_ir_mapping_borrow_mapped_stream_class(ir_maps, |
183 | in_stream_class)); | |
8aca077e | 184 | |
ca9f27f3 | 185 | md_maps = borrow_metadata_maps_from_input_stream_class(ir_maps, |
bc463d34 | 186 | in_stream_class); |
ca9f27f3 FD |
187 | |
188 | BT_ASSERT(md_maps); | |
ca9f27f3 | 189 | |
8aca077e | 190 | /* Create the output stream class. */ |
ca9f27f3 | 191 | out_stream_class = bt_stream_class_create_with_id( |
bc463d34 FD |
192 | md_maps->output_trace_class, |
193 | bt_stream_class_get_id(in_stream_class)); | |
ca9f27f3 | 194 | if (!out_stream_class) { |
3b34b490 FD |
195 | BT_COMP_LOGE_APPEND_CAUSE(self_comp, |
196 | "Error create output stream class"); | |
ca9f27f3 FD |
197 | goto end; |
198 | } | |
199 | ||
3b34b490 | 200 | /* Add it to the mapping. The mapping now owns out_stream_class. */ |
db5d746d FD |
201 | g_hash_table_insert(md_maps->stream_class_map, |
202 | (gpointer) in_stream_class, out_stream_class); | |
203 | ||
8aca077e | 204 | /* Copy the content over to the output stream class. */ |
3b34b490 | 205 | status = copy_stream_class_content(ir_maps, in_stream_class, |
bc463d34 | 206 | out_stream_class); |
3b34b490 FD |
207 | if (status != DEBUG_INFO_TRACE_IR_MAPPING_STATUS_OK) { |
208 | BT_COMP_LOGE_APPEND_CAUSE(self_comp, | |
209 | "Error copy content to output stream class: " | |
210 | "in-sc-addr=%p, out-sc-addr=%p", in_stream_class, | |
211 | out_stream_class); | |
212 | goto error; | |
ca9f27f3 FD |
213 | } |
214 | ||
3b34b490 FD |
215 | BT_COMP_LOGD("Created new mapped stream class: " |
216 | "in-sc-addr=%p, out-sc-addr=%p", | |
bc463d34 | 217 | in_stream_class, out_stream_class); |
ca9f27f3 | 218 | |
3b34b490 FD |
219 | goto end; |
220 | error: | |
221 | out_stream_class = NULL; | |
ca9f27f3 FD |
222 | end: |
223 | return out_stream_class; | |
224 | } | |
225 | ||
226 | static | |
227 | bt_stream *borrow_mapped_stream(struct trace_ir_data_maps *d_maps, | |
228 | const bt_stream *in_stream) | |
229 | { | |
98b15851 PP |
230 | BT_ASSERT_DBG(d_maps); |
231 | BT_ASSERT_DBG(in_stream); | |
ca9f27f3 FD |
232 | |
233 | return g_hash_table_lookup(d_maps->stream_map, (gpointer) in_stream); | |
234 | } | |
235 | ||
236 | BT_HIDDEN | |
237 | bt_stream *trace_ir_mapping_create_new_mapped_stream( | |
8aca077e | 238 | struct trace_ir_maps *ir_maps, const bt_stream *in_stream) |
ca9f27f3 | 239 | { |
3b34b490 FD |
240 | bt_self_component *self_comp = ir_maps->self_comp; |
241 | enum debug_info_trace_ir_mapping_status status; | |
ca9f27f3 | 242 | struct trace_ir_data_maps *d_maps; |
ca9f27f3 FD |
243 | const bt_stream_class *in_stream_class; |
244 | const bt_trace *in_trace; | |
245 | bt_stream_class *out_stream_class; | |
246 | bt_stream *out_stream = NULL; | |
247 | ||
ca9f27f3 FD |
248 | BT_ASSERT(ir_maps); |
249 | BT_ASSERT(in_stream); | |
91bc8451 | 250 | BT_COMP_LOGD("Creating new mapped stream: in-s-addr=%p", in_stream); |
ca9f27f3 FD |
251 | |
252 | in_trace = bt_stream_borrow_trace_const(in_stream); | |
253 | ||
254 | d_maps = borrow_data_maps_from_input_trace(ir_maps, in_trace); | |
255 | if (!d_maps->output_trace) { | |
8aca077e | 256 | /* Create the output trace for this input trace. */ |
ca9f27f3 FD |
257 | d_maps->output_trace = create_new_mapped_trace(ir_maps, in_trace); |
258 | if (!d_maps->output_trace) { | |
3b34b490 FD |
259 | BT_COMP_LOGE_APPEND_CAUSE(self_comp, |
260 | "Error creating mapped trace"); | |
261 | goto error; | |
ca9f27f3 FD |
262 | } |
263 | } | |
264 | ||
265 | BT_ASSERT(d_maps->output_trace); | |
266 | BT_ASSERT(!borrow_mapped_stream(d_maps, in_stream)); | |
267 | ||
268 | in_stream_class = bt_stream_borrow_class_const(in_stream); | |
db5d746d FD |
269 | out_stream_class = trace_ir_mapping_borrow_mapped_stream_class(ir_maps, |
270 | in_stream_class); | |
271 | ||
ca9f27f3 | 272 | if (!out_stream_class) { |
8aca077e | 273 | /* Create the output stream class for this input stream class. */ |
db5d746d FD |
274 | out_stream_class = trace_ir_mapping_create_new_mapped_stream_class( |
275 | ir_maps, in_stream_class); | |
ca9f27f3 | 276 | if (!out_stream_class) { |
3b34b490 FD |
277 | BT_COMP_LOGE_APPEND_CAUSE(self_comp, |
278 | "Error creating mapped stream class"); | |
279 | goto error; | |
ca9f27f3 FD |
280 | } |
281 | } | |
282 | BT_ASSERT(out_stream_class); | |
283 | ||
8aca077e | 284 | /* Create the output stream for this input stream. */ |
ca9f27f3 | 285 | out_stream = bt_stream_create_with_id(out_stream_class, |
8aca077e | 286 | d_maps->output_trace, bt_stream_get_id(in_stream)); |
ca9f27f3 | 287 | if (!out_stream) { |
3b34b490 FD |
288 | BT_COMP_LOGE_APPEND_CAUSE(self_comp, |
289 | "Error creating output stream"); | |
290 | goto error; | |
ca9f27f3 | 291 | } |
ca9f27f3 | 292 | |
3b34b490 | 293 | /* Add it to the mapping. The mapping now owns out_stream.*/ |
ca9f27f3 | 294 | g_hash_table_insert(d_maps->stream_map, (gpointer) in_stream, |
bc463d34 | 295 | out_stream); |
ca9f27f3 | 296 | |
db5d746d | 297 | /* Copy the content over to the output stream. */ |
3b34b490 | 298 | status = copy_stream_content(in_stream, out_stream, ir_maps->log_level, |
db5d746d | 299 | ir_maps->self_comp); |
3b34b490 FD |
300 | if (status != DEBUG_INFO_TRACE_IR_MAPPING_STATUS_OK) { |
301 | BT_COMP_LOGE_APPEND_CAUSE(self_comp, | |
302 | "Error copy content to output stream: " | |
303 | "in-s-addr=%p, out-s-addr=%p", in_stream, out_stream); | |
304 | goto error; | |
305 | } | |
db5d746d | 306 | |
91bc8451 | 307 | BT_COMP_LOGD("Created new mapped stream: in-s-addr=%p, out-s-addr=%p", |
bc463d34 | 308 | in_stream, out_stream); |
ca9f27f3 | 309 | |
3b34b490 FD |
310 | goto end; |
311 | error: | |
312 | out_stream = NULL; | |
ca9f27f3 FD |
313 | end: |
314 | return out_stream; | |
315 | } | |
316 | ||
317 | BT_HIDDEN | |
318 | bt_stream *trace_ir_mapping_borrow_mapped_stream(struct trace_ir_maps *ir_maps, | |
319 | const bt_stream *in_stream) | |
320 | { | |
8aca077e FD |
321 | struct trace_ir_data_maps *d_maps; |
322 | ||
98b15851 PP |
323 | BT_ASSERT_DBG(ir_maps); |
324 | BT_ASSERT_DBG(in_stream); | |
ca9f27f3 FD |
325 | |
326 | d_maps = borrow_data_maps_from_input_stream(ir_maps, in_stream); | |
327 | /* Return the mapped stream. */ | |
328 | return borrow_mapped_stream(d_maps, in_stream); | |
329 | } | |
330 | ||
331 | static inline | |
332 | bt_event_class *borrow_mapped_event_class(struct trace_ir_metadata_maps *md_maps, | |
333 | const bt_event_class *in_event_class) | |
334 | { | |
335 | return g_hash_table_lookup(md_maps->event_class_map, | |
bc463d34 | 336 | (gpointer) in_event_class); |
ca9f27f3 FD |
337 | } |
338 | ||
339 | BT_HIDDEN | |
340 | bt_event_class *trace_ir_mapping_create_new_mapped_event_class( | |
341 | struct trace_ir_maps *ir_maps, | |
342 | const bt_event_class *in_event_class) | |
343 | { | |
3b34b490 FD |
344 | bt_self_component *self_comp = ir_maps->self_comp; |
345 | enum debug_info_trace_ir_mapping_status status; | |
8aca077e | 346 | struct trace_ir_metadata_maps *md_maps; |
ca9f27f3 FD |
347 | const bt_stream_class *in_stream_class; |
348 | bt_stream_class *out_stream_class; | |
8aca077e | 349 | bt_event_class *out_event_class; |
ca9f27f3 | 350 | |
8aca077e FD |
351 | BT_COMP_LOGD("Creating new mapped event class: in-ec-addr=%p", |
352 | in_event_class); | |
353 | ||
ca9f27f3 FD |
354 | BT_ASSERT(ir_maps); |
355 | BT_ASSERT(in_event_class); | |
356 | ||
8aca077e | 357 | in_stream_class = bt_event_class_borrow_stream_class_const(in_event_class); |
ca9f27f3 | 358 | |
8aca077e | 359 | BT_ASSERT(in_stream_class); |
ca9f27f3 | 360 | |
8aca077e FD |
361 | md_maps = borrow_metadata_maps_from_input_stream_class(ir_maps, |
362 | in_stream_class); | |
ca9f27f3 | 363 | |
8aca077e FD |
364 | BT_ASSERT(md_maps); |
365 | BT_ASSERT(!borrow_mapped_event_class(md_maps, in_event_class)); | |
ca9f27f3 | 366 | |
8aca077e | 367 | /* Get the right output stream class to add the new event class to it. */ |
db5d746d FD |
368 | out_stream_class = trace_ir_mapping_borrow_mapped_stream_class( |
369 | ir_maps, in_stream_class); | |
ca9f27f3 FD |
370 | BT_ASSERT(out_stream_class); |
371 | ||
372 | /* Create an output event class. */ | |
373 | out_event_class = bt_event_class_create_with_id(out_stream_class, | |
bc463d34 | 374 | bt_event_class_get_id(in_event_class)); |
ca9f27f3 | 375 | if (!out_event_class) { |
3b34b490 FD |
376 | BT_COMP_LOGE_APPEND_CAUSE(self_comp, |
377 | "Error creating output event class"); | |
ca9f27f3 FD |
378 | goto end; |
379 | } | |
380 | ||
3b34b490 FD |
381 | /* Add it to the mapping. The mapping now owns out_event_class. */ |
382 | g_hash_table_insert(md_maps->event_class_map, (gpointer) in_event_class, | |
383 | out_event_class); | |
db5d746d | 384 | |
8aca077e | 385 | /* Copy the content over to the output event class. */ |
3b34b490 | 386 | status = copy_event_class_content(ir_maps, in_event_class, |
bc463d34 | 387 | out_event_class); |
3b34b490 FD |
388 | if (status != DEBUG_INFO_TRACE_IR_MAPPING_STATUS_OK) { |
389 | BT_COMP_LOGE_APPEND_CAUSE(self_comp, | |
390 | "Error copy content to output event class: " | |
391 | "in-ec-addr=%p, out-ec-addr=%p", in_event_class, | |
392 | out_event_class); | |
393 | goto error; | |
ca9f27f3 FD |
394 | } |
395 | ||
91bc8451 | 396 | BT_COMP_LOGD("Created new mapped event class: in-ec-addr=%p, out-ec-addr=%p", |
bc463d34 | 397 | in_event_class, out_event_class); |
ca9f27f3 | 398 | |
3b34b490 FD |
399 | goto end; |
400 | error: | |
401 | out_event_class = NULL; | |
ca9f27f3 FD |
402 | end: |
403 | return out_event_class; | |
404 | } | |
405 | ||
406 | BT_HIDDEN | |
407 | bt_event_class *trace_ir_mapping_borrow_mapped_event_class( | |
408 | struct trace_ir_maps *ir_maps, | |
409 | const bt_event_class *in_event_class) | |
410 | { | |
411 | struct trace_ir_metadata_maps *md_maps; | |
412 | ||
98b15851 PP |
413 | BT_ASSERT_DBG(ir_maps); |
414 | BT_ASSERT_DBG(in_event_class); | |
ca9f27f3 | 415 | |
bc463d34 FD |
416 | md_maps = borrow_metadata_maps_from_input_event_class(ir_maps, |
417 | in_event_class); | |
ca9f27f3 FD |
418 | |
419 | /* Return the mapped event_class. */ | |
420 | return borrow_mapped_event_class(md_maps, in_event_class); | |
421 | } | |
422 | ||
423 | static inline | |
424 | bt_packet *borrow_mapped_packet(struct trace_ir_data_maps *d_maps, | |
425 | const bt_packet *in_packet) | |
426 | { | |
98b15851 PP |
427 | BT_ASSERT_DBG(d_maps); |
428 | BT_ASSERT_DBG(in_packet); | |
ca9f27f3 | 429 | |
bc463d34 | 430 | return g_hash_table_lookup(d_maps->packet_map, (gpointer) in_packet); |
ca9f27f3 FD |
431 | } |
432 | ||
433 | BT_HIDDEN | |
434 | bt_packet *trace_ir_mapping_create_new_mapped_packet( | |
435 | struct trace_ir_maps *ir_maps, | |
436 | const bt_packet *in_packet) | |
437 | { | |
3b34b490 FD |
438 | bt_self_component *self_comp = ir_maps->self_comp; |
439 | enum debug_info_trace_ir_mapping_status status; | |
ca9f27f3 | 440 | struct trace_ir_data_maps *d_maps; |
ca9f27f3 | 441 | const bt_stream *in_stream; |
8aca077e | 442 | const bt_trace *in_trace; |
ca9f27f3 FD |
443 | bt_packet *out_packet; |
444 | bt_stream *out_stream; | |
445 | ||
91bc8451 | 446 | BT_COMP_LOGD("Creating new mapped packet: in-p-addr=%p", in_packet); |
ca9f27f3 FD |
447 | |
448 | in_stream = bt_packet_borrow_stream_const(in_packet); | |
449 | in_trace = bt_stream_borrow_trace_const(in_stream); | |
450 | d_maps = borrow_data_maps_from_input_trace(ir_maps, in_trace); | |
451 | ||
8aca077e | 452 | /* There should never be a mapped packet already. */ |
ca9f27f3 | 453 | BT_ASSERT(!borrow_mapped_packet(d_maps, in_packet)); |
ca9f27f3 FD |
454 | BT_ASSERT(in_stream); |
455 | ||
456 | /* Get output stream corresponding to this input stream. */ | |
457 | out_stream = borrow_mapped_stream(d_maps, in_stream); | |
458 | BT_ASSERT(out_stream); | |
459 | ||
460 | /* Create the output packet. */ | |
461 | out_packet = bt_packet_create(out_stream); | |
462 | if (!out_packet) { | |
3b34b490 FD |
463 | BT_COMP_LOGE_APPEND_CAUSE(self_comp, |
464 | "Error create output packet"); | |
465 | goto error; | |
ca9f27f3 FD |
466 | } |
467 | ||
3b34b490 FD |
468 | /* Add it to the mapping. The mapping now owns out_packet. */ |
469 | g_hash_table_insert(d_maps->packet_map, (gpointer) in_packet, | |
470 | out_packet); | |
ca9f27f3 | 471 | |
db5d746d | 472 | /* Copy the content over to the output packet. */ |
3b34b490 | 473 | status = copy_packet_content(in_packet, out_packet, ir_maps->log_level, |
db5d746d | 474 | ir_maps->self_comp); |
3b34b490 FD |
475 | if (status != DEBUG_INFO_TRACE_IR_MAPPING_STATUS_OK) { |
476 | BT_COMP_LOGE_APPEND_CAUSE(self_comp, | |
477 | "Error copy content to output packet: " | |
478 | "in-p-addr=%p, out-p-addr=%p", in_packet, out_packet); | |
479 | goto error; | |
480 | } | |
db5d746d | 481 | |
91bc8451 | 482 | BT_COMP_LOGD("Created new mapped packet: in-p-addr=%p, out-p-addr=%p", |
bc463d34 | 483 | in_packet, out_packet); |
ca9f27f3 | 484 | |
3b34b490 FD |
485 | goto end; |
486 | error: | |
487 | out_packet = NULL; | |
ca9f27f3 FD |
488 | end: |
489 | return out_packet; | |
490 | } | |
491 | ||
492 | BT_HIDDEN | |
493 | bt_packet *trace_ir_mapping_borrow_mapped_packet(struct trace_ir_maps *ir_maps, | |
494 | const bt_packet *in_packet) | |
495 | { | |
496 | struct trace_ir_data_maps *d_maps; | |
98b15851 PP |
497 | BT_ASSERT_DBG(ir_maps); |
498 | BT_ASSERT_DBG(in_packet); | |
ca9f27f3 FD |
499 | |
500 | d_maps = borrow_data_maps_from_input_packet(ir_maps, in_packet); | |
501 | ||
502 | return borrow_mapped_packet(d_maps, in_packet); | |
503 | } | |
504 | ||
505 | BT_HIDDEN | |
506 | void trace_ir_mapping_remove_mapped_packet(struct trace_ir_maps *ir_maps, | |
507 | const bt_packet *in_packet) | |
508 | { | |
8aca077e | 509 | struct trace_ir_data_maps *d_maps; |
ca9f27f3 FD |
510 | gboolean ret; |
511 | ||
ca9f27f3 FD |
512 | BT_ASSERT(ir_maps); |
513 | BT_ASSERT(in_packet); | |
514 | ||
515 | d_maps = borrow_data_maps_from_input_packet(ir_maps, in_packet); | |
516 | ||
517 | ret = g_hash_table_remove(d_maps->packet_map, in_packet); | |
518 | ||
519 | BT_ASSERT(ret); | |
520 | } | |
521 | ||
522 | BT_HIDDEN | |
523 | void trace_ir_mapping_remove_mapped_stream(struct trace_ir_maps *ir_maps, | |
524 | const bt_stream *in_stream) | |
525 | { | |
ca9f27f3 | 526 | struct trace_ir_data_maps *d_maps; |
8aca077e | 527 | gboolean ret; |
ca9f27f3 FD |
528 | |
529 | BT_ASSERT(ir_maps); | |
530 | BT_ASSERT(in_stream); | |
531 | ||
532 | d_maps = borrow_data_maps_from_input_stream(ir_maps, in_stream); | |
533 | ||
534 | ret = g_hash_table_remove(d_maps->stream_map, in_stream); | |
535 | ||
536 | BT_ASSERT(ret); | |
537 | } | |
538 | ||
539 | static | |
540 | void trace_ir_metadata_maps_remove_func(const bt_trace_class *in_trace_class, | |
541 | void *data) | |
542 | { | |
543 | struct trace_ir_maps *maps = (struct trace_ir_maps *) data; | |
544 | if (maps->metadata_maps) { | |
545 | gboolean ret; | |
546 | ret = g_hash_table_remove(maps->metadata_maps, | |
bc463d34 | 547 | (gpointer) in_trace_class); |
ca9f27f3 FD |
548 | BT_ASSERT(ret); |
549 | } | |
550 | } | |
551 | ||
552 | static | |
553 | void trace_ir_data_maps_remove_func(const bt_trace *in_trace, void *data) | |
554 | { | |
555 | struct trace_ir_maps *maps = (struct trace_ir_maps *) data; | |
556 | if (maps->data_maps) { | |
557 | gboolean ret; | |
558 | ret = g_hash_table_remove(maps->data_maps, (gpointer) in_trace); | |
559 | BT_ASSERT(ret); | |
560 | } | |
561 | } | |
562 | ||
563 | struct trace_ir_data_maps *trace_ir_data_maps_create(struct trace_ir_maps *ir_maps, | |
564 | const bt_trace *in_trace) | |
565 | { | |
3b34b490 | 566 | bt_self_component *self_comp = ir_maps->self_comp; |
b80991f6 | 567 | bt_trace_add_listener_status add_listener_status; |
8aca077e | 568 | struct trace_ir_data_maps *d_maps = g_new0(struct trace_ir_data_maps, 1); |
b80991f6 | 569 | |
ca9f27f3 | 570 | if (!d_maps) { |
3b34b490 FD |
571 | BT_COMP_LOGE_APPEND_CAUSE(self_comp, |
572 | "Error allocating trace_ir_maps"); | |
ca9f27f3 FD |
573 | goto error; |
574 | } | |
575 | ||
3a3d15f3 | 576 | d_maps->log_level = ir_maps->log_level; |
91bc8451 | 577 | d_maps->self_comp = ir_maps->self_comp; |
ca9f27f3 FD |
578 | d_maps->input_trace = in_trace; |
579 | ||
580 | /* Create the hashtables used to map data objects. */ | |
581 | d_maps->stream_map = g_hash_table_new_full(g_direct_hash, | |
8aca077e | 582 | g_direct_equal, NULL,(GDestroyNotify) bt_stream_put_ref); |
ca9f27f3 | 583 | d_maps->packet_map = g_hash_table_new_full(g_direct_hash, |
8aca077e | 584 | g_direct_equal, NULL,(GDestroyNotify) bt_packet_put_ref); |
ca9f27f3 | 585 | |
b80991f6 PP |
586 | add_listener_status = bt_trace_add_destruction_listener( |
587 | in_trace, trace_ir_data_maps_remove_func, | |
588 | ir_maps, &d_maps->destruction_listener_id); | |
589 | BT_ASSERT(add_listener_status == BT_TRACE_ADD_LISTENER_STATUS_OK); | |
590 | ||
ca9f27f3 FD |
591 | error: |
592 | return d_maps; | |
593 | } | |
594 | ||
595 | struct trace_ir_metadata_maps *trace_ir_metadata_maps_create( | |
596 | struct trace_ir_maps *ir_maps, | |
597 | const bt_trace_class *in_trace_class) | |
598 | { | |
3b34b490 | 599 | bt_self_component *self_comp = ir_maps->self_comp; |
8aca077e | 600 | bt_trace_class_add_listener_status add_listener_status; |
ca9f27f3 FD |
601 | struct trace_ir_metadata_maps *md_maps = |
602 | g_new0(struct trace_ir_metadata_maps, 1); | |
b80991f6 | 603 | |
ca9f27f3 | 604 | if (!md_maps) { |
3b34b490 FD |
605 | BT_COMP_LOGE_APPEND_CAUSE(self_comp, |
606 | "Error allocating trace_ir_maps"); | |
ca9f27f3 FD |
607 | goto error; |
608 | } | |
609 | ||
3a3d15f3 | 610 | md_maps->log_level = ir_maps->log_level; |
91bc8451 | 611 | md_maps->self_comp = ir_maps->self_comp; |
ca9f27f3 FD |
612 | md_maps->input_trace_class = in_trace_class; |
613 | /* | |
614 | * Create the field class resolving context. This is needed to keep | |
615 | * track of the field class already copied in order to do the field | |
616 | * path resolution correctly. | |
617 | */ | |
618 | md_maps->fc_resolving_ctx = | |
619 | g_new0(struct field_class_resolving_context, 1); | |
620 | if (!md_maps->fc_resolving_ctx) { | |
3b34b490 FD |
621 | BT_COMP_LOGE_APPEND_CAUSE(self_comp, |
622 | "Error allocating field_class_resolving_context"); | |
ca9f27f3 FD |
623 | goto error; |
624 | } | |
625 | ||
626 | /* Create the hashtables used to map metadata objects. */ | |
627 | md_maps->stream_class_map = g_hash_table_new_full(g_direct_hash, | |
bc463d34 | 628 | g_direct_equal, NULL, (GDestroyNotify) bt_stream_class_put_ref); |
ca9f27f3 | 629 | md_maps->event_class_map = g_hash_table_new_full(g_direct_hash, |
bc463d34 | 630 | g_direct_equal, NULL, (GDestroyNotify) bt_event_class_put_ref); |
ca9f27f3 | 631 | md_maps->field_class_map = g_hash_table_new_full(g_direct_hash, |
bc463d34 | 632 | g_direct_equal, NULL, (GDestroyNotify) bt_field_class_put_ref); |
ca9f27f3 | 633 | md_maps->clock_class_map = g_hash_table_new_full(g_direct_hash, |
bc463d34 | 634 | g_direct_equal, NULL, (GDestroyNotify) bt_clock_class_put_ref); |
ca9f27f3 | 635 | |
b80991f6 | 636 | add_listener_status = bt_trace_class_add_destruction_listener( |
bc463d34 FD |
637 | in_trace_class, trace_ir_metadata_maps_remove_func, |
638 | ir_maps, &md_maps->destruction_listener_id); | |
639 | BT_ASSERT(add_listener_status == BT_TRACE_CLASS_ADD_LISTENER_STATUS_OK); | |
b80991f6 | 640 | |
ca9f27f3 FD |
641 | error: |
642 | return md_maps; | |
643 | } | |
644 | ||
645 | BT_HIDDEN | |
646 | void trace_ir_data_maps_destroy(struct trace_ir_data_maps *maps) | |
647 | { | |
d24d5663 PP |
648 | bt_trace_remove_listener_status status; |
649 | ||
ca9f27f3 FD |
650 | if (!maps) { |
651 | return; | |
652 | } | |
653 | ||
654 | if (maps->packet_map) { | |
655 | g_hash_table_destroy(maps->packet_map); | |
656 | } | |
657 | ||
658 | if (maps->stream_map) { | |
659 | g_hash_table_destroy(maps->stream_map); | |
660 | } | |
661 | ||
662 | if (maps->output_trace) { | |
663 | bt_trace_put_ref(maps->output_trace); | |
664 | } | |
665 | ||
666 | status = bt_trace_remove_destruction_listener(maps->input_trace, | |
d24d5663 PP |
667 | maps->destruction_listener_id); |
668 | if (status != BT_TRACE_REMOVE_LISTENER_STATUS_OK) { | |
91bc8451 PP |
669 | BT_COMP_LOG_CUR_LVL(BT_LOG_DEBUG, maps->log_level, |
670 | maps->self_comp, | |
3a3d15f3 | 671 | "Trace destruction listener removal failed."); |
b80991f6 | 672 | bt_current_thread_clear_error(); |
3b40fbf9 | 673 | } |
ca9f27f3 FD |
674 | |
675 | g_free(maps); | |
676 | } | |
677 | ||
678 | BT_HIDDEN | |
679 | void trace_ir_metadata_maps_destroy(struct trace_ir_metadata_maps *maps) | |
680 | { | |
d24d5663 PP |
681 | bt_trace_class_remove_listener_status status; |
682 | ||
ca9f27f3 FD |
683 | if (!maps) { |
684 | return; | |
685 | } | |
686 | ||
687 | if (maps->stream_class_map) { | |
688 | g_hash_table_destroy(maps->stream_class_map); | |
689 | } | |
690 | ||
691 | if (maps->event_class_map) { | |
692 | g_hash_table_destroy(maps->event_class_map); | |
693 | } | |
694 | ||
695 | if (maps->field_class_map) { | |
696 | g_hash_table_destroy(maps->field_class_map); | |
697 | } | |
698 | ||
699 | if (maps->clock_class_map) { | |
700 | g_hash_table_destroy(maps->clock_class_map); | |
701 | } | |
702 | ||
19bbdc9b | 703 | g_free(maps->fc_resolving_ctx); |
ca9f27f3 FD |
704 | |
705 | if (maps->output_trace_class) { | |
706 | bt_trace_class_put_ref(maps->output_trace_class); | |
707 | } | |
708 | ||
d24d5663 | 709 | status = bt_trace_class_remove_destruction_listener( |
bc463d34 | 710 | maps->input_trace_class, maps->destruction_listener_id); |
d24d5663 | 711 | if (status != BT_TRACE_CLASS_REMOVE_LISTENER_STATUS_OK) { |
91bc8451 PP |
712 | BT_COMP_LOG_CUR_LVL(BT_LOG_DEBUG, maps->log_level, |
713 | maps->self_comp, | |
3a3d15f3 | 714 | "Trace destruction listener removal failed."); |
b80991f6 | 715 | bt_current_thread_clear_error(); |
3b40fbf9 | 716 | } |
ca9f27f3 FD |
717 | |
718 | g_free(maps); | |
719 | } | |
720 | ||
721 | void trace_ir_maps_clear(struct trace_ir_maps *maps) | |
722 | { | |
723 | if (maps->data_maps) { | |
724 | g_hash_table_remove_all(maps->data_maps); | |
725 | } | |
726 | ||
727 | if (maps->metadata_maps) { | |
728 | g_hash_table_remove_all(maps->metadata_maps); | |
729 | } | |
730 | } | |
731 | ||
732 | BT_HIDDEN | |
733 | void trace_ir_maps_destroy(struct trace_ir_maps *maps) | |
734 | { | |
735 | if (!maps) { | |
736 | return; | |
737 | } | |
738 | ||
19bbdc9b | 739 | g_free(maps->debug_info_field_class_name); |
ca9f27f3 FD |
740 | |
741 | if (maps->data_maps) { | |
742 | g_hash_table_destroy(maps->data_maps); | |
743 | maps->data_maps = NULL; | |
744 | } | |
745 | ||
746 | if (maps->metadata_maps) { | |
747 | g_hash_table_destroy(maps->metadata_maps); | |
748 | maps->metadata_maps = NULL; | |
749 | } | |
750 | ||
751 | g_free(maps); | |
752 | } | |
753 | ||
754 | BT_HIDDEN | |
755 | struct trace_ir_maps *trace_ir_maps_create(bt_self_component *self_comp, | |
3a3d15f3 | 756 | const char *debug_info_field_name, bt_logging_level log_level) |
ca9f27f3 | 757 | { |
8aca077e | 758 | struct trace_ir_maps *ir_maps = g_new0(struct trace_ir_maps, 1); |
3a3d15f3 | 759 | if (!ir_maps) { |
91bc8451 | 760 | BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, log_level, self_comp, |
3a3d15f3 | 761 | "Error allocating trace_ir_maps"); |
ca9f27f3 FD |
762 | goto error; |
763 | } | |
764 | ||
3a3d15f3 | 765 | ir_maps->log_level = log_level; |
91bc8451 | 766 | ir_maps->self_comp = self_comp; |
3a3d15f3 | 767 | |
ca9f27f3 | 768 | /* Copy debug info field name received from the user. */ |
8aca077e | 769 | ir_maps->debug_info_field_class_name = g_strdup(debug_info_field_name); |
3a3d15f3 | 770 | if (!ir_maps->debug_info_field_class_name) { |
3b34b490 FD |
771 | BT_COMP_LOGE_APPEND_CAUSE(self_comp, |
772 | "Cannot copy debug info field name"); | |
ca9f27f3 FD |
773 | goto error; |
774 | } | |
775 | ||
3a3d15f3 | 776 | ir_maps->self_comp = self_comp; |
ca9f27f3 | 777 | |
3a3d15f3 | 778 | ir_maps->data_maps = g_hash_table_new_full(g_direct_hash, |
bc463d34 FD |
779 | g_direct_equal, (GDestroyNotify) NULL, |
780 | (GDestroyNotify) trace_ir_data_maps_destroy); | |
ca9f27f3 | 781 | |
3a3d15f3 | 782 | ir_maps->metadata_maps = g_hash_table_new_full(g_direct_hash, |
bc463d34 FD |
783 | g_direct_equal, (GDestroyNotify) NULL, |
784 | (GDestroyNotify) trace_ir_metadata_maps_destroy); | |
ca9f27f3 FD |
785 | |
786 | goto end; | |
787 | error: | |
3a3d15f3 PP |
788 | trace_ir_maps_destroy(ir_maps); |
789 | ir_maps = NULL; | |
ca9f27f3 | 790 | end: |
3a3d15f3 | 791 | return ir_maps; |
ca9f27f3 | 792 | } |