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