1
1
openmpi/opal/mca/base/mca_base_alias.c
Nathan Hjelm 9fae5bfdf3 mca/base: add support for component aliasing
This commit adds support for aliasing component names. A component
name alias is created by calling: mca_base_alias_register. The name
of the project and framework are optional. The component name and
component alias are required. Once an alias is registered all
variables registered after the alias creation will have synonyms
also registered. For example:

```c
mca_base_alias_register("opal", "btl", "vader", "sm", false);
```

would cause all of the variables registered by btl/vader to have
aliases that start with btl_sm. Ex: btl_vader_single_copy_mechanism
would have the synonym: btl_sm_single_copy_mechanism.

If aliases are registered before component filtering the alias
can also be used for component selection. For example, if sm is
registered as an alias to vader in the btl framework register
function then ```--mca btl self,sm``` would be equivalent to
```--mca btl self,vader```.

Signed-off-by: Nathan Hjelm <hjelmn@google.com>
2020-05-05 06:43:19 -07:00

174 строки
4.5 KiB
C

/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2020 Google, LLC. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "mca_base_alias.h"
#include "opal/class/opal_hash_table.h"
#include "opal/runtime/opal.h"
static void mca_base_alias_init (mca_base_alias_t *alias)
{
OBJ_CONSTRUCT(&alias->component_aliases, opal_list_t);
}
static void mca_base_alias_fini (mca_base_alias_t *alias)
{
OPAL_LIST_DESTRUCT(&alias->component_aliases);
}
OBJ_CLASS_INSTANCE(mca_base_alias_t, opal_object_t, mca_base_alias_init,
mca_base_alias_fini);
static void mca_base_alias_item_init (mca_base_alias_item_t *alias_item) {
alias_item->component_alias = NULL;
}
static void mca_base_alias_item_fini (mca_base_alias_item_t *alias_item) {
free (alias_item->component_alias);
}
OBJ_CLASS_INSTANCE(mca_base_alias_item_t, opal_list_item_t, mca_base_alias_item_init,
mca_base_alias_item_fini);
/*
* local variables
*/
static opal_hash_table_t *alias_hash_table;
static void mca_base_alias_cleanup (void)
{
if (!alias_hash_table) {
return;
}
void *key;
opal_object_t *value;
OPAL_HASH_TABLE_FOREACH_PTR(key, value, alias_hash_table, {
OBJ_RELEASE(value);
});
OBJ_RELEASE(alias_hash_table);
alias_hash_table = NULL;
}
static int mca_base_alias_setup (void)
{
if (NULL != alias_hash_table) {
return OPAL_SUCCESS;
}
opal_finalize_register_cleanup (mca_base_alias_cleanup);
alias_hash_table = OBJ_NEW(opal_hash_table_t);
if (NULL == alias_hash_table) {
return OPAL_ERR_OUT_OF_RESOURCE;
}
int ret = opal_hash_table_init (alias_hash_table, 32);
if (OPAL_SUCCESS != ret) {
OBJ_RELEASE(alias_hash_table);
alias_hash_table = NULL;
return ret;
}
return OPAL_SUCCESS;
}
static char *mca_base_alias_generate_name (const char *project, const char *framework, const char *component_name)
{
size_t project_length = project ? strlen (project) : 0;
size_t framework_length = framework ? strlen (framework) : 0;
size_t component_name_length = strlen (component_name);
size_t length = project_length + framework_length + component_name_length + 2;
char *tmp = calloc (1, length + 1);
if (NULL == tmp) {
return tmp;
}
if (project_length) {
strncat (tmp, project, length);
strncat (tmp, "_", 1);
length -= project_length + 1;
}
if (framework_length) {
strncat (tmp, framework, length);
strncat (tmp, "_", 1);
length -= framework_length + 1;
}
strncat (tmp, component_name, length);
return tmp;
}
static mca_base_alias_t *mca_base_alias_lookup_internal (const char *name)
{
mca_base_alias_t *alias = NULL;
if (NULL == alias_hash_table) {
return NULL;
}
(void) opal_hash_table_get_value_ptr (alias_hash_table, name, strlen (name), (void **) &alias);
return alias;
}
int mca_base_alias_register (const char *project, const char *framework, const char *component_name,
const char *component_alias, uint32_t alias_flags)
{
if (NULL == component_name) {
return OPAL_ERR_BAD_PARAM;
}
int ret = mca_base_alias_setup ();
if (OPAL_SUCCESS != ret) {
return ret;
}
char *name = mca_base_alias_generate_name (project, framework, component_name);
assert (NULL != name);
mca_base_alias_t *alias = mca_base_alias_lookup_internal (name);
if (NULL == alias) {
alias = OBJ_NEW(mca_base_alias_t);
if (NULL == alias) {
return OPAL_ERR_OUT_OF_RESOURCE;
}
opal_hash_table_set_value_ptr (alias_hash_table, name, strlen(name), alias);
free (name);
}
mca_base_alias_item_t *alias_item = OBJ_NEW(mca_base_alias_item_t);
if (NULL == alias_item) {
return OPAL_ERR_OUT_OF_RESOURCE;
}
alias_item->component_alias = strdup (component_alias);
alias_item->alias_flags = alias_flags;
opal_list_append (&alias->component_aliases, &alias_item->super);
return OPAL_SUCCESS;
}
const mca_base_alias_t *mca_base_alias_lookup(const char *project, const char *framework, const char *component_name)
{
if (NULL == component_name) {
return NULL;
}
char *name = mca_base_alias_generate_name (project, framework, component_name);
assert (NULL != name);
const mca_base_alias_t *alias = mca_base_alias_lookup_internal (name);
free (name);
return alias;
}