Move to kernel style SPDX license identifiers
[babeltrace.git] / src / plugins / ctf / common / metadata / ctf-meta-update-in-ir.c
CommitLineData
44c440bc 1/*
0235b0db 2 * SPDX-License-Identifier: MIT
44c440bc 3 *
0235b0db 4 * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
44c440bc
PP
5 */
6
3fadfbc0 7#include <babeltrace2/babeltrace.h>
91d81473 8#include "common/macros.h"
578e048b
MJ
9#include "common/assert.h"
10#include "compat/glib.h"
44c440bc 11#include <glib.h>
c4f23e30 12#include <stdbool.h>
44c440bc
PP
13#include <stdint.h>
14#include <string.h>
15#include <inttypes.h>
578e048b 16#include "common/assert.h"
44c440bc
PP
17
18#include "ctf-meta-visitors.h"
19
83ebb7f1
PP
20static
21void force_update_field_class_in_ir(struct ctf_field_class *fc, bool in_ir)
22{
23 uint64_t i;
24
25 if (!fc) {
26 goto end;
27 }
28
29 fc->in_ir = in_ir;
30
31 switch (fc->type) {
32 case CTF_FIELD_CLASS_TYPE_STRUCT:
33 {
34 struct ctf_field_class_struct *struct_fc = (void *) fc;
35
36 for (i = 0; i < struct_fc->members->len; i++) {
37 struct ctf_named_field_class *named_fc =
38 ctf_field_class_struct_borrow_member_by_index(
39 struct_fc, i);
40
41 force_update_field_class_in_ir(named_fc->fc, in_ir);
42 }
43
44 break;
45 }
46 case CTF_FIELD_CLASS_TYPE_VARIANT:
47 {
48 struct ctf_named_field_class *named_fc;
49 struct ctf_field_class_variant *var_fc = (void *) fc;
50
51 for (i = 0; i < var_fc->options->len; i++) {
52 named_fc =
53 ctf_field_class_variant_borrow_option_by_index(
54 var_fc, i);
55
56 force_update_field_class_in_ir(named_fc->fc, in_ir);
57 }
58
59 break;
60 }
61 case CTF_FIELD_CLASS_TYPE_ARRAY:
62 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
63 {
64 struct ctf_field_class_array_base *array_fc = (void *) fc;
65
66 force_update_field_class_in_ir(array_fc->elem_fc, in_ir);
67 break;
68 }
69 default:
70 break;
71 }
72
73end:
74 return;
75}
76
44c440bc 77static
5cd6d0e5 78void update_field_class_in_ir(struct ctf_field_class *fc,
44c440bc
PP
79 GHashTable *ft_dependents)
80{
81 int64_t i;
82
5cd6d0e5 83 if (!fc) {
44c440bc
PP
84 goto end;
85 }
86
864cad70
PP
87 switch (fc->type) {
88 case CTF_FIELD_CLASS_TYPE_INT:
89 case CTF_FIELD_CLASS_TYPE_ENUM:
44c440bc 90 {
5cd6d0e5 91 struct ctf_field_class_int *int_fc = (void *) fc;
44c440bc 92
2de73462
PP
93 /*
94 * Conditions to be in trace IR; one of:
95 *
96 * 1. Does NOT have a mapped clock class AND does not
97 * have a special meaning.
98 * 2. Another field class depends on it.
99 */
100 if ((!int_fc->mapped_clock_class &&
101 int_fc->meaning == CTF_FIELD_CLASS_MEANING_NONE) ||
5cd6d0e5 102 bt_g_hash_table_contains(ft_dependents, fc)) {
5cd6d0e5 103 fc->in_ir = true;
44c440bc
PP
104 }
105
106 break;
107 }
864cad70 108 case CTF_FIELD_CLASS_TYPE_STRUCT:
44c440bc 109 {
5cd6d0e5 110 struct ctf_field_class_struct *struct_fc = (void *) fc;
44c440bc 111
b2c863b0
PP
112 /*
113 * Make it part of IR if it's empty because it was
114 * originally empty.
115 */
116 if (struct_fc->members->len == 0) {
117 fc->in_ir = true;
118 }
119
44c440bc 120 /* Reverse order */
5cd6d0e5
PP
121 for (i = (int64_t) struct_fc->members->len - 1; i >= 0; i--) {
122 struct ctf_named_field_class *named_fc =
123 ctf_field_class_struct_borrow_member_by_index(
124 struct_fc, i);
44c440bc 125
5cd6d0e5 126 update_field_class_in_ir(named_fc->fc, ft_dependents);
44c440bc 127
5cd6d0e5 128 if (named_fc->fc->in_ir) {
44c440bc 129 /* At least one member is part of IR */
5cd6d0e5 130 fc->in_ir = true;
44c440bc
PP
131 }
132 }
133
134 break;
135 }
864cad70 136 case CTF_FIELD_CLASS_TYPE_VARIANT:
44c440bc 137 {
5cd6d0e5
PP
138 struct ctf_named_field_class *named_fc;
139 struct ctf_field_class_variant *var_fc = (void *) fc;
44c440bc
PP
140
141 /*
142 * Reverse order, although it is not important for this
5cd6d0e5
PP
143 * loop because a field class within a variant field
144 * type's option cannot depend on a field class in
145 * another option of the same variant field class.
44c440bc 146 */
5cd6d0e5
PP
147 for (i = (int64_t) var_fc->options->len - 1; i >= 0; i--) {
148 named_fc =
149 ctf_field_class_variant_borrow_option_by_index(
150 var_fc, i);
44c440bc 151
5cd6d0e5 152 update_field_class_in_ir(named_fc->fc, ft_dependents);
44c440bc 153
5cd6d0e5 154 if (named_fc->fc->in_ir) {
44c440bc 155 /* At least one option is part of IR */
5cd6d0e5 156 fc->in_ir = true;
44c440bc
PP
157 }
158 }
159
5cd6d0e5 160 if (fc->in_ir) {
44c440bc
PP
161 /*
162 * At least one option will make it to IR. In
163 * this case, make all options part of IR
164 * because the variant's tag could still select
165 * (dynamically) a removed option. This can mean
166 * having an empty structure as an option, for
167 * example, but at least all the options are
168 * selectable.
169 */
5cd6d0e5
PP
170 for (i = 0; i < var_fc->options->len; i++) {
171 ctf_field_class_variant_borrow_option_by_index(
172 var_fc, i)->fc->in_ir = true;
44c440bc
PP
173 }
174
175 /*
5cd6d0e5
PP
176 * This variant field class is part of IR and
177 * depends on a tag field class (which must also
44c440bc
PP
178 * be part of IR).
179 */
5cd6d0e5
PP
180 g_hash_table_insert(ft_dependents, var_fc->tag_fc,
181 var_fc->tag_fc);
44c440bc
PP
182 }
183
184 break;
185 }
864cad70
PP
186 case CTF_FIELD_CLASS_TYPE_ARRAY:
187 case CTF_FIELD_CLASS_TYPE_SEQUENCE:
44c440bc 188 {
5cd6d0e5 189 struct ctf_field_class_array_base *array_fc = (void *) fc;
44c440bc 190
5cd6d0e5
PP
191 update_field_class_in_ir(array_fc->elem_fc, ft_dependents);
192 fc->in_ir = array_fc->elem_fc->in_ir;
44c440bc 193
864cad70 194 if (fc->type == CTF_FIELD_CLASS_TYPE_ARRAY) {
5cd6d0e5 195 struct ctf_field_class_array *arr_fc = (void *) fc;
44c440bc 196
5cd6d0e5
PP
197 assert(arr_fc->meaning == CTF_FIELD_CLASS_MEANING_NONE ||
198 arr_fc->meaning == CTF_FIELD_CLASS_MEANING_UUID);
44c440bc
PP
199
200 /*
5cd6d0e5 201 * UUID field class: nothing depends on this, so
44c440bc
PP
202 * it's not part of IR.
203 */
5cd6d0e5
PP
204 if (arr_fc->meaning == CTF_FIELD_CLASS_MEANING_UUID) {
205 fc->in_ir = false;
206 array_fc->elem_fc->in_ir = false;
44c440bc 207 }
864cad70 208 } else if (fc->type == CTF_FIELD_CLASS_TYPE_SEQUENCE) {
5cd6d0e5
PP
209 if (fc->in_ir) {
210 struct ctf_field_class_sequence *seq_fc = (void *) fc;
44c440bc
PP
211
212 /*
5cd6d0e5
PP
213 * This sequence field class is part of
214 * IR and depends on a length field class
44c440bc
PP
215 * (which must also be part of IR).
216 */
217 g_hash_table_insert(ft_dependents,
5cd6d0e5 218 seq_fc->length_fc, seq_fc->length_fc);
44c440bc
PP
219 }
220 }
221
222 break;
223 }
224 default:
5cd6d0e5 225 fc->in_ir = true;
44c440bc
PP
226 break;
227 }
228
229end:
230 return;
231}
232
233/*
5cd6d0e5
PP
234 * Scopes and field classes are processed in reverse order because we need
235 * to know if a given integer field class has dependents (sequence or
236 * variant field classes) when we reach it. Dependents can only be located
237 * after the length/tag field class in the metadata tree.
44c440bc
PP
238 */
239BT_HIDDEN
240int ctf_trace_class_update_in_ir(struct ctf_trace_class *ctf_tc)
241{
242 int ret = 0;
243 uint64_t i;
244
245 GHashTable *ft_dependents = g_hash_table_new(g_direct_hash,
246 g_direct_equal);
247
248 BT_ASSERT(ft_dependents);
249
250 for (i = 0; i < ctf_tc->stream_classes->len; i++) {
251 struct ctf_stream_class *sc = ctf_tc->stream_classes->pdata[i];
252 uint64_t j;
253
254 for (j = 0; j < sc->event_classes->len; j++) {
255 struct ctf_event_class *ec = sc->event_classes->pdata[j];
256
257 if (ec->is_translated) {
258 continue;
259 }
260
5cd6d0e5
PP
261 update_field_class_in_ir(ec->payload_fc, ft_dependents);
262 update_field_class_in_ir(ec->spec_context_fc,
44c440bc
PP
263 ft_dependents);
264 }
265
266 if (!sc->is_translated) {
5cd6d0e5 267 update_field_class_in_ir(sc->event_common_context_fc,
44c440bc 268 ft_dependents);
83ebb7f1
PP
269 force_update_field_class_in_ir(sc->event_header_fc,
270 false);
5cd6d0e5 271 update_field_class_in_ir(sc->packet_context_fc,
44c440bc
PP
272 ft_dependents);
273 }
274 }
275
276 if (!ctf_tc->is_translated) {
83ebb7f1
PP
277 force_update_field_class_in_ir(ctf_tc->packet_header_fc,
278 false);
44c440bc
PP
279 }
280
281 g_hash_table_destroy(ft_dependents);
282 return ret;
283}
This page took 0.065217 seconds and 4 git commands to generate.