root/opal/mca/pmix/pmix4x/pmix/src/mca/base/pmix_mca_base_var_group.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pmix_mca_base_var_group_init
  2. pmix_mca_base_var_group_finalize
  3. pmix_mca_base_var_group_get_internal
  4. group_find_by_name
  5. compare_strings
  6. group_find_linear
  7. group_find
  8. group_register
  9. pmix_mca_base_var_group_register
  10. pmix_mca_base_var_group_component_register
  11. pmix_mca_base_var_group_deregister
  12. pmix_mca_base_var_group_find
  13. pmix_mca_base_var_group_find_by_name
  14. pmix_mca_base_var_group_add_var
  15. pmix_mca_base_var_group_get
  16. pmix_mca_base_var_group_set_var_flag
  17. pmix_mca_base_var_group_constructor
  18. pmix_mca_base_var_group_destructor
  19. pmix_mca_base_var_group_get_count
  20. pmix_mca_base_var_group_get_stamp

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2012 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2008-2013 Cisco Systems, Inc.  All rights reserved.
  14  * Copyright (c) 2012-2015 Los Alamos National Security, LLC. All rights
  15  *                         reserved.
  16  * Copyright (c) 2016-2018 Intel, Inc. All rights reserved.
  17  * $COPYRIGHT$
  18  *
  19  * Additional copyrights may follow
  20  *
  21  * $HEADER$
  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         /* These values are arbitrary */
  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     /* check for wildcards */
 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         /* don't create a group with no name (maybe we should create a generic group?) */
 217         return -1;
 218     }
 219 
 220     /* avoid groups of the form pmix_pmix, etc */
 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             /* something went horribly wrong */
 231             assert (NULL != group);
 232             return ret;
 233         }
 234         group->group_isvalid = true;
 235         pmix_mca_base_var_groups_timestamp++;
 236 
 237         /* group already exists. return it's index */
 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     /* build the group name */
 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     /* 1.7 components do not store the project */
 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     /* deregister all associated mca parameters */
 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     /* ordering of variables and subgroups must be the same if the
 357      * group is re-registered */
 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, &param_index))) {
 397         return ret;
 398     }
 399 
 400     pmix_mca_base_var_groups_timestamp++;
 401 
 402     /* return the group index */
 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     /* set the flag on each valid variable */
 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 }

/* [<][>][^][v][top][bottom][index][help] */