cpp-common/bt2c/fmt.hpp: use `wise_enum::string_type` in `EnableIfIsWiseEnum` definition
[babeltrace.git] / src / lib / graph / mip.c
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright 2019 Philippe Proulx <pproulx@efficios.com>
5 */
6
7 #define BT_LOG_TAG "LIB/MIP"
8 #include "lib/logging.h"
9
10 #include "lib/assert-cond.h"
11 #include <stdbool.h>
12 #include <unistd.h>
13 #include <glib.h>
14 #include <babeltrace2/graph/graph.h>
15
16 #include "common/assert.h"
17 #include "compat/compiler.h"
18 #include "common/common.h"
19 #include "lib/func-status.h"
20 #include "lib/graph/component-class.h"
21 #include "lib/value.h"
22 #include "component-descriptor-set.h"
23 #include "lib/integer-range-set.h"
24
25 static
26 bool unsigned_integer_range_set_contains(
27 const struct bt_integer_range_set *range_set, uint64_t value)
28 {
29 bool contains = false;
30 uint64_t i;
31
32 BT_ASSERT(range_set);
33
34 for (i = 0; i < range_set->ranges->len; i++) {
35 const struct bt_integer_range *range =
36 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(range_set, i);
37
38 if (value >= range->lower.u && value <= range->upper.u) {
39 contains = true;
40 goto end;
41 }
42 }
43
44 end:
45 return contains;
46 }
47
48 /*
49 * As of this version, this function only validates that all the
50 * component descriptors in `descriptors` support MIP version 0, which
51 * is the only version supported by this library.
52 *
53 * If any component descriptor does not support MIP version 0, then this
54 * function returns `BT_FUNC_STATUS_NO_MATCH`.
55 */
56 static
57 int validate_operative_mip_version_in_array(GPtrArray *descriptors,
58 enum bt_logging_level log_level)
59 {
60 typedef bt_component_class_get_supported_mip_versions_method_status
61 (*method_t)(
62 void * /* component class */,
63 const struct bt_value *,
64 void * /* init method data */,
65 enum bt_logging_level,
66 struct bt_integer_range_set *);
67
68 int status = BT_FUNC_STATUS_OK;
69 uint64_t i;
70 struct bt_integer_range_set *range_set = NULL;
71
72 for (i = 0; i < descriptors->len; i++) {
73 struct bt_component_descriptor_set_entry *descr =
74 descriptors->pdata[i];
75 method_t method = NULL;
76 const char *method_name = NULL;
77 bt_component_class_get_supported_mip_versions_method_status method_status;
78
79 switch (descr->comp_cls->type) {
80 case BT_COMPONENT_CLASS_TYPE_SOURCE:
81 {
82 struct bt_component_class_source *src_cc = (void *)
83 descr->comp_cls;
84
85 method = (method_t) src_cc->methods.get_supported_mip_versions;
86 method_name = "bt_component_class_source_get_supported_mip_versions_method";
87 break;
88 }
89 case BT_COMPONENT_CLASS_TYPE_FILTER:
90 {
91 struct bt_component_class_filter *flt_cc = (void *)
92 descr->comp_cls;
93
94 method = (method_t) flt_cc->methods.get_supported_mip_versions;
95 method_name = "bt_component_class_filter_get_supported_mip_versions_method";
96 break;
97 }
98 case BT_COMPONENT_CLASS_TYPE_SINK:
99 {
100 struct bt_component_class_sink *sink_cc = (void *)
101 descr->comp_cls;
102
103 method = (method_t) sink_cc->methods.get_supported_mip_versions;
104 method_name = "bt_component_class_sink_get_supported_mip_versions_method";
105 break;
106 }
107 default:
108 bt_common_abort();
109 }
110
111 if (!method) {
112 /* Assume 0 */
113 continue;
114 }
115
116 range_set = (void *) bt_integer_range_set_unsigned_create();
117 if (!range_set) {
118 status = BT_FUNC_STATUS_MEMORY_ERROR;
119 goto end;
120 }
121
122 BT_ASSERT(descr->params);
123 BT_LIB_LOGD("Calling user's \"get supported MIP versions\" method: "
124 "%![cc-]+C, %![params-]+v, init-method-data=%p, "
125 "log-level=%s",
126 descr->comp_cls, descr->params,
127 descr->init_method_data,
128 bt_common_logging_level_string(log_level));
129 method_status = method(descr->comp_cls, descr->params,
130 descr->init_method_data, log_level,
131 range_set);
132 BT_LIB_LOGD("User method returned: status=%s",
133 bt_common_func_status_string(method_status));
134 BT_ASSERT_POST(method_name, "status-ok-with-at-least-one-range",
135 method_status != BT_FUNC_STATUS_OK ||
136 range_set->ranges->len > 0,
137 "User method returned `BT_FUNC_STATUS_OK` without "
138 "adding a range to the supported MIP version range set.");
139 BT_ASSERT_POST_NO_ERROR_IF_NO_ERROR_STATUS(method_name,
140 method_status);
141 if (method_status < 0) {
142 BT_LIB_LOGW_APPEND_CAUSE(
143 "Component class's \"get supported MIP versions\" method failed: "
144 "%![cc-]+C, %![params-]+v, init-method-data=%p, "
145 "log-level=%s",
146 descr->comp_cls, descr->params,
147 descr->init_method_data,
148 bt_common_logging_level_string(log_level));
149 status = (int) method_status;
150 goto end;
151 }
152
153 if (!unsigned_integer_range_set_contains(range_set, 0)) {
154 /*
155 * Supported MIP versions do not include 0,
156 * which is the only MIP versions currently
157 * supported by the library itself.
158 */
159 status = BT_FUNC_STATUS_NO_MATCH;
160 goto end;
161 }
162
163 BT_OBJECT_PUT_REF_AND_RESET(range_set);
164 }
165
166 end:
167 bt_object_put_ref(range_set);
168 return status;
169 }
170
171 /*
172 * The purpose of this function is eventually to find the greatest
173 * common supported MIP version amongst all the component descriptors.
174 * But as of this version of the library, only MIP version 0 is
175 * supported, so it only checks that they all support MIP version 0 and
176 * always sets `*operative_mip_version` to 0.
177 *
178 * When any component descriptor does not support MIP version 0, this
179 * function returns `BT_FUNC_STATUS_NO_MATCH`.
180 */
181 BT_EXPORT
182 enum bt_get_greatest_operative_mip_version_status
183 bt_get_greatest_operative_mip_version(
184 const struct bt_component_descriptor_set *comp_descr_set,
185 enum bt_logging_level log_level,
186 uint64_t *operative_mip_version)
187 {
188 int status = BT_FUNC_STATUS_OK;
189
190 BT_ASSERT_PRE_NO_ERROR();
191 BT_ASSERT_PRE_COMP_DESCR_SET_NON_NULL(comp_descr_set);
192 BT_ASSERT_PRE_NON_NULL("operative-mip-version-output",
193 operative_mip_version,
194 "Operative MIP version (output)");
195 BT_ASSERT_PRE("component-descriptor-set-is-not-empty",
196 comp_descr_set->sources->len +
197 comp_descr_set->filters->len +
198 comp_descr_set->sinks->len > 0,
199 "Component descriptor set is empty: addr=%p", comp_descr_set);
200 status = validate_operative_mip_version_in_array(
201 comp_descr_set->sources, log_level);
202 if (status) {
203 goto end;
204 }
205
206 status = validate_operative_mip_version_in_array(
207 comp_descr_set->filters, log_level);
208 if (status) {
209 goto end;
210 }
211
212 status = validate_operative_mip_version_in_array(
213 comp_descr_set->sinks, log_level);
214 if (status) {
215 goto end;
216 }
217
218 *operative_mip_version = 0;
219
220 end:
221 return status;
222 }
223
224 BT_EXPORT
225 uint64_t bt_get_maximal_mip_version(void)
226 {
227 return 0;
228 }
This page took 0.034456 seconds and 4 git commands to generate.