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