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