This source file includes following definitions.
- pmix_mca_base_var_group_init
- pmix_mca_base_var_group_finalize
- pmix_mca_base_var_group_get_internal
- group_find_by_name
- compare_strings
- group_find_linear
- group_find
- group_register
- pmix_mca_base_var_group_register
- pmix_mca_base_var_group_component_register
- pmix_mca_base_var_group_deregister
- pmix_mca_base_var_group_find
- pmix_mca_base_var_group_find_by_name
- pmix_mca_base_var_group_add_var
- pmix_mca_base_var_group_get
- pmix_mca_base_var_group_set_var_flag
- pmix_mca_base_var_group_constructor
- pmix_mca_base_var_group_destructor
- pmix_mca_base_var_group_get_count
- pmix_mca_base_var_group_get_stamp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include <src/include/pmix_config.h>
25
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #ifdef HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32 #ifdef HAVE_SYS_PARAM_H
33 #include <sys/param.h>
34 #endif
35 #include <errno.h>
36
37 #include "src/include/pmix_stdint.h"
38 #include "src/util/show_help.h"
39 #include "src/mca/mca.h"
40 #include "src/mca/base/pmix_mca_base_vari.h"
41 #include "pmix_common.h"
42 #include "src/util/output.h"
43 #include "src/util/pmix_environ.h"
44
45 static pmix_pointer_array_t pmix_mca_base_var_groups;
46 static pmix_hash_table_t pmix_mca_base_var_group_index_hash;
47 static int pmix_mca_base_var_group_count = 0;
48 static int pmix_mca_base_var_groups_timestamp = 0;
49 static bool pmix_mca_base_var_group_initialized = false;
50
51 static void pmix_mca_base_var_group_constructor (pmix_mca_base_var_group_t *group);
52 static void pmix_mca_base_var_group_destructor (pmix_mca_base_var_group_t *group);
53 PMIX_CLASS_INSTANCE(pmix_mca_base_var_group_t, pmix_object_t,
54 pmix_mca_base_var_group_constructor,
55 pmix_mca_base_var_group_destructor);
56
57 int pmix_mca_base_var_group_init (void)
58 {
59 int ret;
60
61 if (!pmix_mca_base_var_group_initialized) {
62 PMIX_CONSTRUCT(&pmix_mca_base_var_groups, pmix_pointer_array_t);
63
64
65 ret = pmix_pointer_array_init (&pmix_mca_base_var_groups, 128, 16384, 128);
66 if (PMIX_SUCCESS != ret) {
67 return ret;
68 }
69
70 PMIX_CONSTRUCT(&pmix_mca_base_var_group_index_hash, pmix_hash_table_t);
71 ret = pmix_hash_table_init (&pmix_mca_base_var_group_index_hash, 256);
72 if (PMIX_SUCCESS != ret) {
73 return ret;
74 }
75
76 pmix_mca_base_var_group_initialized = true;
77 pmix_mca_base_var_group_count = 0;
78 }
79
80 return PMIX_SUCCESS;
81 }
82
83 int pmix_mca_base_var_group_finalize (void)
84 {
85 pmix_object_t *object;
86 int size, i;
87
88 if (pmix_mca_base_var_group_initialized) {
89 size = pmix_pointer_array_get_size(&pmix_mca_base_var_groups);
90 for (i = 0 ; i < size ; ++i) {
91 object = pmix_pointer_array_get_item (&pmix_mca_base_var_groups, i);
92 if (NULL != object) {
93 PMIX_RELEASE(object);
94 }
95 }
96 PMIX_DESTRUCT(&pmix_mca_base_var_groups);
97 PMIX_DESTRUCT(&pmix_mca_base_var_group_index_hash);
98 pmix_mca_base_var_group_count = 0;
99 pmix_mca_base_var_group_initialized = false;
100 }
101
102 return PMIX_SUCCESS;
103 }
104
105 int pmix_mca_base_var_group_get_internal (const int group_index, pmix_mca_base_var_group_t **group, bool invalidok)
106 {
107 if (group_index < 0) {
108 return PMIX_ERR_NOT_FOUND;
109 }
110
111 *group = (pmix_mca_base_var_group_t *) pmix_pointer_array_get_item (&pmix_mca_base_var_groups,
112 group_index);
113 if (NULL == *group || (!invalidok && !(*group)->group_isvalid)) {
114 *group = NULL;
115 return PMIX_ERR_NOT_FOUND;
116 }
117
118 return PMIX_SUCCESS;
119 }
120
121 static int group_find_by_name (const char *full_name, int *index, bool invalidok)
122 {
123 pmix_mca_base_var_group_t *group;
124 void *tmp;
125 int rc;
126
127 rc = pmix_hash_table_get_value_ptr (&pmix_mca_base_var_group_index_hash, full_name,
128 strlen (full_name), &tmp);
129 if (PMIX_SUCCESS != rc) {
130 return rc;
131 }
132
133 rc = pmix_mca_base_var_group_get_internal ((int)(uintptr_t) tmp, &group, invalidok);
134 if (PMIX_SUCCESS != rc) {
135 return rc;
136 }
137
138 if (invalidok || group->group_isvalid) {
139 *index = (int)(uintptr_t) tmp;
140 return PMIX_SUCCESS;
141 }
142
143 return PMIX_ERR_NOT_FOUND;
144 }
145
146 static bool compare_strings (const char *str1, const char *str2) {
147 if ((NULL != str1 && 0 == strcmp (str1, "*")) ||
148 (NULL == str1 && NULL == str2)) {
149 return true;
150 }
151
152 if (NULL != str1 && NULL != str2) {
153 return 0 == strcmp (str1, str2);
154 }
155
156 return false;
157 }
158
159 static int group_find_linear (const char *project_name, const char *framework_name,
160 const char *component_name, bool invalidok)
161 {
162 for (int i = 0 ; i < pmix_mca_base_var_group_count ; ++i) {
163 pmix_mca_base_var_group_t *group;
164
165 int rc = pmix_mca_base_var_group_get_internal (i, &group, invalidok);
166 if (PMIX_SUCCESS != rc) {
167 continue;
168 }
169
170 if (compare_strings (project_name, group->group_project) &&
171 compare_strings (framework_name, group->group_framework) &&
172 compare_strings (component_name, group->group_component)) {
173 return i;
174 }
175 }
176
177 return PMIX_ERR_NOT_FOUND;
178 }
179
180 static int group_find (const char *project_name, const char *framework_name,
181 const char *component_name, bool invalidok)
182 {
183 char *full_name;
184 int ret, index=0;
185
186 if (!pmix_mca_base_var_initialized) {
187 return PMIX_ERR_NOT_FOUND;
188 }
189
190
191 if ((project_name && '*' == project_name[0]) || (framework_name && '*' == framework_name[0]) ||
192 (component_name && '*' == component_name[0])) {
193 return group_find_linear (project_name, framework_name, component_name, invalidok);
194 }
195
196 ret = pmix_mca_base_var_generate_full_name4(project_name, framework_name, component_name,
197 NULL, &full_name);
198 if (PMIX_SUCCESS != ret) {
199 return PMIX_ERROR;
200 }
201
202 ret = group_find_by_name(full_name, &index, invalidok);
203 free (full_name);
204
205 return (0 > ret) ? ret : index;
206 }
207
208 static int group_register (const char *project_name, const char *framework_name,
209 const char *component_name, const char *description)
210 {
211 pmix_mca_base_var_group_t *group;
212 int group_id, parent_id = -1;
213 int ret;
214
215 if (NULL == project_name && NULL == framework_name && NULL == component_name) {
216
217 return -1;
218 }
219
220
221 if (NULL != project_name && NULL != framework_name &&
222 (0 == strcmp (project_name, framework_name))) {
223 project_name = NULL;
224 }
225
226 group_id = group_find (project_name, framework_name, component_name, true);
227 if (0 <= group_id) {
228 ret = pmix_mca_base_var_group_get_internal (group_id, &group, true);
229 if (PMIX_SUCCESS != ret) {
230
231 assert (NULL != group);
232 return ret;
233 }
234 group->group_isvalid = true;
235 pmix_mca_base_var_groups_timestamp++;
236
237
238 return group_id;
239 }
240
241 group = PMIX_NEW(pmix_mca_base_var_group_t);
242
243 group->group_isvalid = true;
244
245 if (NULL != project_name) {
246 group->group_project = strdup (project_name);
247 if (NULL == group->group_project) {
248 PMIX_RELEASE(group);
249 return PMIX_ERR_OUT_OF_RESOURCE;
250 }
251 }
252 if (NULL != framework_name) {
253 group->group_framework = strdup (framework_name);
254 if (NULL == group->group_framework) {
255 PMIX_RELEASE(group);
256 return PMIX_ERR_OUT_OF_RESOURCE;
257 }
258 }
259 if (NULL != component_name) {
260 group->group_component = strdup (component_name);
261 if (NULL == group->group_component) {
262 PMIX_RELEASE(group);
263 return PMIX_ERR_OUT_OF_RESOURCE;
264 }
265 }
266 if (NULL != description) {
267 group->group_description = strdup (description);
268 if (NULL == group->group_description) {
269 PMIX_RELEASE(group);
270 return PMIX_ERR_OUT_OF_RESOURCE;
271 }
272 }
273
274 if (NULL != framework_name && NULL != component_name) {
275 parent_id = group_register (project_name, framework_name, NULL, NULL);
276 }
277
278
279 ret = pmix_mca_base_var_generate_full_name4 (NULL, project_name, framework_name, component_name,
280 &group->group_full_name);
281 if (PMIX_SUCCESS != ret) {
282 PMIX_RELEASE(group);
283 return ret;
284 }
285
286 group_id = pmix_pointer_array_add (&pmix_mca_base_var_groups, group);
287 if (0 > group_id) {
288 PMIX_RELEASE(group);
289 return PMIX_ERROR;
290 }
291
292 pmix_hash_table_set_value_ptr (&pmix_mca_base_var_group_index_hash, group->group_full_name,
293 strlen (group->group_full_name), (void *)(uintptr_t) group_id);
294
295 pmix_mca_base_var_group_count++;
296 pmix_mca_base_var_groups_timestamp++;
297
298 if (0 <= parent_id) {
299 pmix_mca_base_var_group_t *parent_group;
300
301 (void) pmix_mca_base_var_group_get_internal(parent_id, &parent_group, false);
302 pmix_value_array_append_item (&parent_group->group_subgroups, &group_id);
303 }
304
305 return group_id;
306 }
307
308 int pmix_mca_base_var_group_register (const char *project_name, const char *framework_name,
309 const char *component_name, const char *description)
310 {
311 return group_register (project_name, framework_name, component_name, description);
312 }
313
314 int pmix_mca_base_var_group_component_register (const pmix_mca_base_component_t *component,
315 const char *description)
316 {
317
318 return group_register (component->pmix_mca_project_name, component->pmix_mca_type_name,
319 component->pmix_mca_component_name, description);
320 }
321
322
323 int pmix_mca_base_var_group_deregister (int group_index)
324 {
325 pmix_mca_base_var_group_t *group;
326 int size, ret;
327 int *params, *subgroups;
328
329 ret = pmix_mca_base_var_group_get_internal (group_index, &group, false);
330 if (PMIX_SUCCESS != ret) {
331 return ret;
332 }
333
334 group->group_isvalid = false;
335
336
337 size = pmix_value_array_get_size(&group->group_vars);
338 params = PMIX_VALUE_ARRAY_GET_BASE(&group->group_vars, int);
339
340 for (int i = 0 ; i < size ; ++i) {
341 const pmix_mca_base_var_t *var;
342
343 ret = pmix_mca_base_var_get (params[i], &var);
344 if (PMIX_SUCCESS != ret || !(var->mbv_flags & PMIX_MCA_BASE_VAR_FLAG_DWG)) {
345 continue;
346 }
347
348 (void) pmix_mca_base_var_deregister (params[i]);
349 }
350
351 size = pmix_value_array_get_size(&group->group_subgroups);
352 subgroups = PMIX_VALUE_ARRAY_GET_BASE(&group->group_subgroups, int);
353 for (int i = 0 ; i < size ; ++i) {
354 (void) pmix_mca_base_var_group_deregister (subgroups[i]);
355 }
356
357
358
359 pmix_mca_base_var_groups_timestamp++;
360
361 return PMIX_SUCCESS;
362 }
363
364 int pmix_mca_base_var_group_find (const char *project_name,
365 const char *framework_name,
366 const char *component_name)
367 {
368 return group_find (project_name, framework_name, component_name, false);
369 }
370
371 int pmix_mca_base_var_group_find_by_name (const char *full_name, int *index)
372 {
373 return group_find_by_name (full_name, index, false);
374 }
375
376 int pmix_mca_base_var_group_add_var (const int group_index, const int param_index)
377 {
378 pmix_mca_base_var_group_t *group;
379 int size, i, ret;
380 int *params;
381
382 ret = pmix_mca_base_var_group_get_internal (group_index, &group, false);
383 if (PMIX_SUCCESS != ret) {
384 return ret;
385 }
386
387 size = pmix_value_array_get_size(&group->group_vars);
388 params = PMIX_VALUE_ARRAY_GET_BASE(&group->group_vars, int);
389 for (i = 0 ; i < size ; ++i) {
390 if (params[i] == param_index) {
391 return i;
392 }
393 }
394
395 if (PMIX_SUCCESS !=
396 (ret = pmix_value_array_append_item (&group->group_vars, ¶m_index))) {
397 return ret;
398 }
399
400 pmix_mca_base_var_groups_timestamp++;
401
402
403 return (int) pmix_value_array_get_size (&group->group_vars) - 1;
404 }
405
406 int pmix_mca_base_var_group_get (const int group_index, const pmix_mca_base_var_group_t **group)
407 {
408 return pmix_mca_base_var_group_get_internal (group_index, (pmix_mca_base_var_group_t **) group, false);
409 }
410
411 int pmix_mca_base_var_group_set_var_flag (const int group_index, int flags, bool set)
412 {
413 pmix_mca_base_var_group_t *group;
414 int size, i, ret;
415 int *vars;
416
417 ret = pmix_mca_base_var_group_get_internal (group_index, &group, false);
418 if (PMIX_SUCCESS != ret) {
419 return ret;
420 }
421
422
423 size = pmix_value_array_get_size(&group->group_vars);
424 vars = PMIX_VALUE_ARRAY_GET_BASE(&group->group_vars, int);
425
426 for (i = 0 ; i < size ; ++i) {
427 if (0 <= vars[i]) {
428 (void) pmix_mca_base_var_set_flag (vars[i], flags, set);
429 }
430 }
431
432 return PMIX_SUCCESS;
433 }
434
435
436 static void pmix_mca_base_var_group_constructor (pmix_mca_base_var_group_t *group)
437 {
438 memset ((char *) group + sizeof (group->super), 0, sizeof (*group) - sizeof (group->super));
439
440 PMIX_CONSTRUCT(&group->group_subgroups, pmix_value_array_t);
441 pmix_value_array_init (&group->group_subgroups, sizeof (int));
442
443 PMIX_CONSTRUCT(&group->group_vars, pmix_value_array_t);
444 pmix_value_array_init (&group->group_vars, sizeof (int));
445
446 }
447
448 static void pmix_mca_base_var_group_destructor (pmix_mca_base_var_group_t *group)
449 {
450 free (group->group_full_name);
451 group->group_full_name = NULL;
452
453 free (group->group_description);
454 group->group_description = NULL;
455
456 free (group->group_project);
457 group->group_project = NULL;
458
459 free (group->group_framework);
460 group->group_framework = NULL;
461
462 free (group->group_component);
463 group->group_component = NULL;
464
465 PMIX_DESTRUCT(&group->group_subgroups);
466 PMIX_DESTRUCT(&group->group_vars);
467 }
468
469 int pmix_mca_base_var_group_get_count (void)
470 {
471 return pmix_mca_base_var_group_count;
472 }
473
474 int pmix_mca_base_var_group_get_stamp (void)
475 {
476 return pmix_mca_base_var_groups_timestamp;
477 }