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