Document libbabeltrace2's C API
[babeltrace.git] / src / plugins / lttng-utils / debug-info / trace-ir-mapping.c
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
28 #define BT_COMP_LOG_SELF_COMP (ir_maps->self_comp)
29 #define BT_LOG_OUTPUT_LEVEL (ir_maps->log_level)
30 #define BT_LOG_TAG "PLUGIN/FLT.LTTNG-UTILS.DEBUG-INFO/TRACE-IR-MAPPING"
31 #include "logging/comp-logging.h"
32
33 #include "common/assert.h"
34 #include <babeltrace2/babeltrace.h>
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 {
45 bt_self_component *self_comp = ir_maps->self_comp;
46 enum debug_info_trace_ir_mapping_status status;
47 struct trace_ir_metadata_maps *metadata_maps;
48
49 BT_COMP_LOGD("Creating new mapped trace class: in-tc-addr=%p", in_trace_class);
50
51 BT_ASSERT(ir_maps);
52 BT_ASSERT(in_trace_class);
53
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
59 /* Create the ouput trace class. */
60 metadata_maps->output_trace_class =
61 bt_trace_class_create(ir_maps->self_comp);
62 if (!metadata_maps->output_trace_class) {
63 BT_COMP_LOGE_APPEND_CAUSE(self_comp,
64 "Error create output trace class");
65 goto error;
66 }
67
68 /* Copy the content over and add to the mapping. */
69 status = copy_trace_class_content(ir_maps, in_trace_class,
70 metadata_maps->output_trace_class, ir_maps->log_level,
71 ir_maps->self_comp);
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;
78 }
79
80 BT_COMP_LOGD("Created new mapped trace class: "
81 "in-tc-addr=%p, out-tc-addr=%p",
82 in_trace_class, metadata_maps->output_trace_class);
83
84 goto end;
85 error:
86 BT_TRACE_CLASS_PUT_REF_AND_RESET(metadata_maps->output_trace_class);
87 end:
88 return metadata_maps->output_trace_class;
89 }
90
91 static
92 bt_trace *create_new_mapped_trace(struct trace_ir_maps *ir_maps,
93 const bt_trace *in_trace)
94 {
95 bt_self_component *self_comp = ir_maps->self_comp;
96 enum debug_info_trace_ir_mapping_status status;
97 struct trace_ir_metadata_maps *metadata_maps;
98 const bt_trace_class *in_trace_class;
99 bt_trace *out_trace;
100
101 BT_COMP_LOGD("Creating new mapped trace: in-t-addr=%p", in_trace);
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,
107 in_trace_class);
108
109 if (!metadata_maps->output_trace_class) {
110 /*
111 * If there is no output trace class yet, create a one and add
112 * it to the mapping.
113 */
114 metadata_maps->output_trace_class =
115 create_new_mapped_trace_class(ir_maps, in_trace_class);
116 if (!metadata_maps->output_trace_class) {
117 BT_COMP_LOGE_APPEND_CAUSE(self_comp,
118 "Error create output trace class");
119 out_trace = NULL;
120 goto end;
121 }
122 }
123
124 /* Create the output trace from the output trace class. */
125 out_trace = bt_trace_create(metadata_maps->output_trace_class);
126 if (!out_trace) {
127 BT_COMP_LOGE_APPEND_CAUSE(self_comp,
128 "Error create output trace");
129 goto end;
130 }
131
132 /* Copy the content over to the output trace. */
133 status = copy_trace_content(in_trace, out_trace, ir_maps->log_level,
134 ir_maps->self_comp);
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 }
141
142 BT_COMP_LOGD("Created new mapped trace: in-t-addr=%p, out-t-addr=%p",
143 in_trace, out_trace);
144 goto end;
145
146 error:
147 BT_TRACE_PUT_REF_AND_RESET(out_trace);
148 end:
149 return out_trace;
150 }
151
152 BT_HIDDEN
153 bt_stream_class *trace_ir_mapping_borrow_mapped_stream_class(
154 struct trace_ir_maps *ir_maps,
155 const bt_stream_class *in_stream_class)
156 {
157 BT_ASSERT_DBG(ir_maps);
158 BT_ASSERT_DBG(in_stream_class);
159
160 struct trace_ir_metadata_maps *md_maps =
161 borrow_metadata_maps_from_input_stream_class(ir_maps,
162 in_stream_class);
163 return g_hash_table_lookup(md_maps->stream_class_map,
164 (gpointer) in_stream_class);
165 }
166
167 BT_HIDDEN
168 bt_stream_class *trace_ir_mapping_create_new_mapped_stream_class(
169 struct trace_ir_maps *ir_maps,
170 const bt_stream_class *in_stream_class)
171 {
172 bt_self_component *self_comp = ir_maps->self_comp;
173 enum debug_info_trace_ir_mapping_status status;
174 struct trace_ir_metadata_maps *md_maps;
175 bt_stream_class *out_stream_class;
176
177 BT_COMP_LOGD("Creating new mapped stream class: in-sc-addr=%p",
178 in_stream_class);
179
180 BT_ASSERT(ir_maps);
181 BT_ASSERT(in_stream_class);
182 BT_ASSERT(!trace_ir_mapping_borrow_mapped_stream_class(ir_maps,
183 in_stream_class));
184
185 md_maps = borrow_metadata_maps_from_input_stream_class(ir_maps,
186 in_stream_class);
187
188 BT_ASSERT(md_maps);
189
190 /* Create the output stream class. */
191 out_stream_class = bt_stream_class_create_with_id(
192 md_maps->output_trace_class,
193 bt_stream_class_get_id(in_stream_class));
194 if (!out_stream_class) {
195 BT_COMP_LOGE_APPEND_CAUSE(self_comp,
196 "Error create output stream class");
197 goto end;
198 }
199
200 /* Add it to the mapping. The mapping now owns out_stream_class. */
201 g_hash_table_insert(md_maps->stream_class_map,
202 (gpointer) in_stream_class, out_stream_class);
203
204 /* Copy the content over to the output stream class. */
205 status = copy_stream_class_content(ir_maps, in_stream_class,
206 out_stream_class);
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;
213 }
214
215 BT_COMP_LOGD("Created new mapped stream class: "
216 "in-sc-addr=%p, out-sc-addr=%p",
217 in_stream_class, out_stream_class);
218
219 goto end;
220 error:
221 out_stream_class = NULL;
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 {
230 BT_ASSERT_DBG(d_maps);
231 BT_ASSERT_DBG(in_stream);
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(
238 struct trace_ir_maps *ir_maps, const bt_stream *in_stream)
239 {
240 bt_self_component *self_comp = ir_maps->self_comp;
241 enum debug_info_trace_ir_mapping_status status;
242 struct trace_ir_data_maps *d_maps;
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
248 BT_ASSERT(ir_maps);
249 BT_ASSERT(in_stream);
250 BT_COMP_LOGD("Creating new mapped stream: in-s-addr=%p", in_stream);
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) {
256 /* Create the output trace for this input trace. */
257 d_maps->output_trace = create_new_mapped_trace(ir_maps, in_trace);
258 if (!d_maps->output_trace) {
259 BT_COMP_LOGE_APPEND_CAUSE(self_comp,
260 "Error creating mapped trace");
261 goto error;
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);
269 out_stream_class = trace_ir_mapping_borrow_mapped_stream_class(ir_maps,
270 in_stream_class);
271
272 if (!out_stream_class) {
273 /* Create the output stream class for this input stream class. */
274 out_stream_class = trace_ir_mapping_create_new_mapped_stream_class(
275 ir_maps, in_stream_class);
276 if (!out_stream_class) {
277 BT_COMP_LOGE_APPEND_CAUSE(self_comp,
278 "Error creating mapped stream class");
279 goto error;
280 }
281 }
282 BT_ASSERT(out_stream_class);
283
284 /* Create the output stream for this input stream. */
285 out_stream = bt_stream_create_with_id(out_stream_class,
286 d_maps->output_trace, bt_stream_get_id(in_stream));
287 if (!out_stream) {
288 BT_COMP_LOGE_APPEND_CAUSE(self_comp,
289 "Error creating output stream");
290 goto error;
291 }
292
293 /* Add it to the mapping. The mapping now owns out_stream.*/
294 g_hash_table_insert(d_maps->stream_map, (gpointer) in_stream,
295 out_stream);
296
297 /* Copy the content over to the output stream. */
298 status = copy_stream_content(in_stream, out_stream, ir_maps->log_level,
299 ir_maps->self_comp);
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 }
306
307 BT_COMP_LOGD("Created new mapped stream: in-s-addr=%p, out-s-addr=%p",
308 in_stream, out_stream);
309
310 goto end;
311 error:
312 out_stream = NULL;
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 {
321 struct trace_ir_data_maps *d_maps;
322
323 BT_ASSERT_DBG(ir_maps);
324 BT_ASSERT_DBG(in_stream);
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,
336 (gpointer) in_event_class);
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 {
344 bt_self_component *self_comp = ir_maps->self_comp;
345 enum debug_info_trace_ir_mapping_status status;
346 struct trace_ir_metadata_maps *md_maps;
347 const bt_stream_class *in_stream_class;
348 bt_stream_class *out_stream_class;
349 bt_event_class *out_event_class;
350
351 BT_COMP_LOGD("Creating new mapped event class: in-ec-addr=%p",
352 in_event_class);
353
354 BT_ASSERT(ir_maps);
355 BT_ASSERT(in_event_class);
356
357 in_stream_class = bt_event_class_borrow_stream_class_const(in_event_class);
358
359 BT_ASSERT(in_stream_class);
360
361 md_maps = borrow_metadata_maps_from_input_stream_class(ir_maps,
362 in_stream_class);
363
364 BT_ASSERT(md_maps);
365 BT_ASSERT(!borrow_mapped_event_class(md_maps, in_event_class));
366
367 /* Get the right output stream class to add the new event class to it. */
368 out_stream_class = trace_ir_mapping_borrow_mapped_stream_class(
369 ir_maps, in_stream_class);
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,
374 bt_event_class_get_id(in_event_class));
375 if (!out_event_class) {
376 BT_COMP_LOGE_APPEND_CAUSE(self_comp,
377 "Error creating output event class");
378 goto end;
379 }
380
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);
384
385 /* Copy the content over to the output event class. */
386 status = copy_event_class_content(ir_maps, in_event_class,
387 out_event_class);
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;
394 }
395
396 BT_COMP_LOGD("Created new mapped event class: in-ec-addr=%p, out-ec-addr=%p",
397 in_event_class, out_event_class);
398
399 goto end;
400 error:
401 out_event_class = NULL;
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
413 BT_ASSERT_DBG(ir_maps);
414 BT_ASSERT_DBG(in_event_class);
415
416 md_maps = borrow_metadata_maps_from_input_event_class(ir_maps,
417 in_event_class);
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 {
427 BT_ASSERT_DBG(d_maps);
428 BT_ASSERT_DBG(in_packet);
429
430 return g_hash_table_lookup(d_maps->packet_map, (gpointer) in_packet);
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 {
438 bt_self_component *self_comp = ir_maps->self_comp;
439 enum debug_info_trace_ir_mapping_status status;
440 struct trace_ir_data_maps *d_maps;
441 const bt_stream *in_stream;
442 const bt_trace *in_trace;
443 bt_packet *out_packet;
444 bt_stream *out_stream;
445
446 BT_COMP_LOGD("Creating new mapped packet: in-p-addr=%p", in_packet);
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
452 /* There should never be a mapped packet already. */
453 BT_ASSERT(!borrow_mapped_packet(d_maps, in_packet));
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) {
463 BT_COMP_LOGE_APPEND_CAUSE(self_comp,
464 "Error create output packet");
465 goto error;
466 }
467
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);
471
472 /* Copy the content over to the output packet. */
473 status = copy_packet_content(in_packet, out_packet, ir_maps->log_level,
474 ir_maps->self_comp);
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 }
481
482 BT_COMP_LOGD("Created new mapped packet: in-p-addr=%p, out-p-addr=%p",
483 in_packet, out_packet);
484
485 goto end;
486 error:
487 out_packet = NULL;
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;
497 BT_ASSERT_DBG(ir_maps);
498 BT_ASSERT_DBG(in_packet);
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 {
509 struct trace_ir_data_maps *d_maps;
510 gboolean ret;
511
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 {
526 struct trace_ir_data_maps *d_maps;
527 gboolean ret;
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,
547 (gpointer) in_trace_class);
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 {
566 bt_self_component *self_comp = ir_maps->self_comp;
567 bt_trace_add_listener_status add_listener_status;
568 struct trace_ir_data_maps *d_maps = g_new0(struct trace_ir_data_maps, 1);
569
570 if (!d_maps) {
571 BT_COMP_LOGE_APPEND_CAUSE(self_comp,
572 "Error allocating trace_ir_maps");
573 goto error;
574 }
575
576 d_maps->log_level = ir_maps->log_level;
577 d_maps->self_comp = ir_maps->self_comp;
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,
582 g_direct_equal, NULL,(GDestroyNotify) bt_stream_put_ref);
583 d_maps->packet_map = g_hash_table_new_full(g_direct_hash,
584 g_direct_equal, NULL,(GDestroyNotify) bt_packet_put_ref);
585
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
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 {
599 bt_self_component *self_comp = ir_maps->self_comp;
600 bt_trace_class_add_listener_status add_listener_status;
601 struct trace_ir_metadata_maps *md_maps =
602 g_new0(struct trace_ir_metadata_maps, 1);
603
604 if (!md_maps) {
605 BT_COMP_LOGE_APPEND_CAUSE(self_comp,
606 "Error allocating trace_ir_maps");
607 goto error;
608 }
609
610 md_maps->log_level = ir_maps->log_level;
611 md_maps->self_comp = ir_maps->self_comp;
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) {
621 BT_COMP_LOGE_APPEND_CAUSE(self_comp,
622 "Error allocating field_class_resolving_context");
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,
628 g_direct_equal, NULL, (GDestroyNotify) bt_stream_class_put_ref);
629 md_maps->event_class_map = g_hash_table_new_full(g_direct_hash,
630 g_direct_equal, NULL, (GDestroyNotify) bt_event_class_put_ref);
631 md_maps->field_class_map = g_hash_table_new_full(g_direct_hash,
632 g_direct_equal, NULL, (GDestroyNotify) bt_field_class_put_ref);
633 md_maps->clock_class_map = g_hash_table_new_full(g_direct_hash,
634 g_direct_equal, NULL, (GDestroyNotify) bt_clock_class_put_ref);
635
636 add_listener_status = bt_trace_class_add_destruction_listener(
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);
640
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 {
648 bt_trace_remove_listener_status status;
649
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,
667 maps->destruction_listener_id);
668 if (status != BT_TRACE_REMOVE_LISTENER_STATUS_OK) {
669 BT_COMP_LOG_CUR_LVL(BT_LOG_DEBUG, maps->log_level,
670 maps->self_comp,
671 "Trace destruction listener removal failed.");
672 bt_current_thread_clear_error();
673 }
674
675 g_free(maps);
676 }
677
678 BT_HIDDEN
679 void trace_ir_metadata_maps_destroy(struct trace_ir_metadata_maps *maps)
680 {
681 bt_trace_class_remove_listener_status status;
682
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
703 g_free(maps->fc_resolving_ctx);
704
705 if (maps->output_trace_class) {
706 bt_trace_class_put_ref(maps->output_trace_class);
707 }
708
709 status = bt_trace_class_remove_destruction_listener(
710 maps->input_trace_class, maps->destruction_listener_id);
711 if (status != BT_TRACE_CLASS_REMOVE_LISTENER_STATUS_OK) {
712 BT_COMP_LOG_CUR_LVL(BT_LOG_DEBUG, maps->log_level,
713 maps->self_comp,
714 "Trace destruction listener removal failed.");
715 bt_current_thread_clear_error();
716 }
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
739 g_free(maps->debug_info_field_class_name);
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,
756 const char *debug_info_field_name, bt_logging_level log_level)
757 {
758 struct trace_ir_maps *ir_maps = g_new0(struct trace_ir_maps, 1);
759 if (!ir_maps) {
760 BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, log_level, self_comp,
761 "Error allocating trace_ir_maps");
762 goto error;
763 }
764
765 ir_maps->log_level = log_level;
766 ir_maps->self_comp = self_comp;
767
768 /* Copy debug info field name received from the user. */
769 ir_maps->debug_info_field_class_name = g_strdup(debug_info_field_name);
770 if (!ir_maps->debug_info_field_class_name) {
771 BT_COMP_LOGE_APPEND_CAUSE(self_comp,
772 "Cannot copy debug info field name");
773 goto error;
774 }
775
776 ir_maps->self_comp = self_comp;
777
778 ir_maps->data_maps = g_hash_table_new_full(g_direct_hash,
779 g_direct_equal, (GDestroyNotify) NULL,
780 (GDestroyNotify) trace_ir_data_maps_destroy);
781
782 ir_maps->metadata_maps = g_hash_table_new_full(g_direct_hash,
783 g_direct_equal, (GDestroyNotify) NULL,
784 (GDestroyNotify) trace_ir_metadata_maps_destroy);
785
786 goto end;
787 error:
788 trace_ir_maps_destroy(ir_maps);
789 ir_maps = NULL;
790 end:
791 return ir_maps;
792 }
This page took 0.046956 seconds and 4 git commands to generate.