1
1
openmpi/src/mca/base/mca_base_param.c

563 строки
14 KiB
C
Исходник Обычный вид История

/*
* $HEADER$
*/
#include "ompi_config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "include/constants.h"
#include "class/ompi_value_array.h"
#include "class/ompi_hash_table.h"
#include "attribute/attribute.h"
#include "mca/mca.h"
#include "mca/base/mca_base_param.h"
#include "mca/base/mca_base_param_internal.h"
/*
* Public variables
*
* This variable is public, but not advertised in mca_base_param.h.
* It's only public so that ompi_info can see it. The relevant component
* in ompi_info will provide an extern to see this variable.
*/
ompi_value_array_t mca_base_params;
/*
* local variables
*/
static char *mca_prefix = "OMPI_MCA_";
static bool initialized = false;
/*
* local functions
*/
static int param_register(const char *type_name, const char *component_name,
const char *param_name,
const char *mca_param_name,
mca_base_param_type_t type,
mca_base_param_storage_t *default_value);
static bool param_lookup(int index, mca_base_param_storage_t *storage,
ompi_hash_table_t *attrs);
static void param_constructor(mca_base_param_t *p);
static void param_destructor(mca_base_param_t *p);
/*
* Make the class instance for mca_base_param_t
*/
OBJ_CLASS_INSTANCE(mca_base_param_t, ompi_object_t,
param_constructor, param_destructor);
/*
* Register an integer MCA parameter
*/
int mca_base_param_register_int(const char *type_name,
const char *component_name,
const char *param_name,
const char *mca_param_name,
int default_value)
{
mca_base_param_storage_t storage;
storage.intval = default_value;
return param_register(type_name, component_name, param_name, mca_param_name,
MCA_BASE_PARAM_TYPE_INT, &storage);
}
/*
* Register a string MCA parameter.
*/
int mca_base_param_register_string(const char *type_name,
const char *component_name,
const char *param_name,
const char *mca_param_name,
const char *default_value)
{
mca_base_param_storage_t storage;
if (NULL != default_value) {
storage.stringval = (char *) default_value;
} else {
storage.stringval = NULL;
}
return param_register(type_name, component_name, param_name, mca_param_name,
MCA_BASE_PARAM_TYPE_STRING, &storage);
}
/*
* Associate a keyval with a parameter index
*/
int mca_base_param_kv_associate(int index, int keyval)
{
size_t len;
mca_base_param_t *array;
if (!initialized) {
return OMPI_ERROR;
}
len = ompi_value_array_get_size(&mca_base_params);
if (0 > index || index > len) {
return OMPI_ERROR;
}
/* We have a valid entry (remember that we never delete MCA
parameters, so if the index is >0 and <len, it must be good), so
save the keyval */
array = OMPI_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t);
array[index].mbp_keyval = keyval;
/* All done */
return OMPI_SUCCESS;
}
/*
* Look up an integer MCA parameter.
*/
int mca_base_param_lookup_int(int index, int *value)
{
mca_base_param_storage_t storage;
if (param_lookup(index, &storage, NULL)) {
*value = storage.intval;
return OMPI_SUCCESS;
}
return OMPI_ERROR;
}
/*
* Look up an integer MCA parameter, including in attributes
*/
int mca_base_param_kv_lookup_int(int index, ompi_hash_table_t *attrs,
int *value)
{
mca_base_param_storage_t storage;
if (param_lookup(index, &storage, attrs)) {
*value = storage.intval;
return OMPI_SUCCESS;
}
return OMPI_ERROR;
}
/*
* Look up a string MCA parameter.
*/
int mca_base_param_lookup_string(int index, char **value)
{
mca_base_param_storage_t storage;
if (param_lookup(index, &storage, NULL)) {
*value = storage.stringval;
return OMPI_SUCCESS;
}
return OMPI_ERROR;
}
/*
* Look up a string MCA parameter, including in attributes.
*/
int mca_base_param_kv_lookup_string(int index, ompi_hash_table_t *attrs,
char **value)
{
mca_base_param_storage_t storage;
if (param_lookup(index, &storage, attrs)) {
*value = storage.stringval;
return OMPI_SUCCESS;
}
return OMPI_ERROR;
}
/*
* Find the index for an MCA parameter based on its names.
*/
int mca_base_param_find(const char *type_name, const char *component_name,
const char *param_name)
{
size_t i, size;
mca_base_param_t *array;
/* Check for bozo cases */
if (!initialized) {
return OMPI_ERROR;
}
if (NULL == type_name) {
return OMPI_ERROR;
}
/* Loop through looking for a parameter of a given
type/component/param */
size = ompi_value_array_get_size(&mca_base_params);
array = OMPI_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t);
for (i = 0; i < size; ++i) {
if (0 == strcmp(type_name, array[i].mbp_type_name) &&
((NULL == component_name && NULL == array[i].mbp_component_name) ||
(NULL != component_name && NULL != array[i].mbp_component_name &&
0 == strcmp(component_name, array[i].mbp_component_name))) &&
((NULL == param_name && NULL == array[i].mbp_param_name) ||
(NULL != param_name && NULL != array[i].mbp_param_name &&
0 == strcmp(param_name, array[i].mbp_param_name)))) {
return i;
}
}
/* Didn't find it */
return OMPI_ERROR;
}
/*
* Shut down the MCA parameter system (normally only invoked by the
* MCA framework itself).
*/
int mca_base_param_finalize(void)
{
mca_base_param_t *array;
if (initialized) {
/* This is slow, but effective :-) */
array = OMPI_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t);
while (0 < ompi_value_array_get_size(&mca_base_params)) {
OBJ_DESTRUCT(&array[0]);
ompi_value_array_remove_item(&mca_base_params, 0);
}
OBJ_DESTRUCT(&mca_base_params);
initialized = false;
}
return OMPI_SUCCESS;
}
/*************************************************************************/
static int param_register(const char *type_name, const char *component_name,
const char *param_name, const char *mca_param_name,
mca_base_param_type_t type,
mca_base_param_storage_t *default_value)
{
int ret;
size_t i, len;
mca_base_param_t param, *array;
/* Initialize the array if it has never been initialized */
if (!initialized) {
OBJ_CONSTRUCT(&mca_base_params, ompi_value_array_t);
ompi_value_array_init(&mca_base_params, sizeof(mca_base_param_t));
initialized = true;
}
/* Error check */
if (NULL == type_name) {
return OMPI_ERR_BAD_PARAM;
}
/* Create a parameter entry. If a keyval is to be used, it will be
registered elsewhere. We simply assign -1 here. */
OBJ_CONSTRUCT(&param, mca_base_param_t);
param.mbp_type = type;
param.mbp_keyval = MPI_KEYVAL_INVALID;
param.mbp_type_name = strdup(type_name);
if (NULL == param.mbp_type_name) {
OBJ_DESTRUCT(&param);
return OMPI_ERR_OUT_OF_RESOURCE;
}
if (NULL != component_name) {
param.mbp_component_name = strdup(component_name);
if (NULL == param.mbp_component_name) {
OBJ_DESTRUCT(&param);
return OMPI_ERR_OUT_OF_RESOURCE;
}
} else {
param.mbp_param_name = NULL;
}
if (NULL != param_name) {
param.mbp_param_name = strdup(param_name);
if (NULL == param.mbp_param_name) {
OBJ_DESTRUCT(&param);
return OMPI_ERR_OUT_OF_RESOURCE;
}
} else {
param.mbp_param_name = NULL;
}
/* The full parameter name may have been specified by the caller.
If it was, use that (only for backwards compatability).
Otherwise, derive it from the type, component, and parameter
name. */
param.mbp_env_var_name = NULL;
if (NULL != mca_param_name) {
param.mbp_full_name = strdup(mca_param_name);
if (NULL == param.mbp_full_name) {
OBJ_DESTRUCT(&param);
return OMPI_ERROR;
}
} else {
len = 16 + strlen(type_name);
if (NULL != component_name) {
len += strlen(component_name);
}
if (NULL != param_name) {
len += strlen(param_name);
}
param.mbp_full_name = malloc(len);
if (NULL == param.mbp_full_name) {
OBJ_DESTRUCT(&param);
return OMPI_ERROR;
}
/* Copy the name over in parts */
strncpy(param.mbp_full_name, type_name, len);
if (NULL != component_name) {
strcat(param.mbp_full_name, "_");
strcat(param.mbp_full_name, component_name);
}
if (NULL != param_name) {
strcat(param.mbp_full_name, "_");
strcat(param.mbp_full_name, param_name);
}
}
/* Create the environment name */
len = strlen(param.mbp_full_name) + strlen(mca_prefix) + 16;
param.mbp_env_var_name = malloc(len);
if (NULL == param.mbp_env_var_name) {
OBJ_DESTRUCT(&param);
return OMPI_ERROR;
}
snprintf(param.mbp_env_var_name, len, "%s%s", mca_prefix,
param.mbp_full_name);
/* Figure out the default value; zero it out if a default is not
provided */
if (NULL != default_value) {
if (MCA_BASE_PARAM_TYPE_STRING == param.mbp_type &&
NULL != default_value->stringval) {
param.mbp_default_value.stringval = strdup(default_value->stringval);
} else {
param.mbp_default_value = *default_value;
}
} else {
memset(&param.mbp_default_value, 0, sizeof(param.mbp_default_value));
}
/* See if this entry is already in the array */
len = ompi_value_array_get_size(&mca_base_params);
array = OMPI_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t);
for (i = 0; i < len; ++i) {
if (0 == strcmp(param.mbp_full_name, array[i].mbp_full_name)) {
/* We found an entry with the same param name. Free the old
value (if it was a string */
if (MCA_BASE_PARAM_TYPE_STRING == array[i].mbp_type &&
NULL != array[i].mbp_default_value.stringval) {
free(array[i].mbp_default_value.stringval);
}
/* Now put in the new value */
if (MCA_BASE_PARAM_TYPE_STRING == param.mbp_type) {
if (NULL != param.mbp_default_value.stringval) {
array[i].mbp_default_value.stringval =
strdup(param.mbp_default_value.stringval);
} else {
array[i].mbp_default_value.stringval = NULL;
}
} else {
array[i].mbp_default_value.intval =
param.mbp_default_value.intval;
}
/* Just in case we changed type */
array[i].mbp_type = param.mbp_type;
/* Now delete the newly-created entry (since we just saved the
value in the old entry) */
OBJ_DESTRUCT(&param);
return i;
}
}
/* Add it to the array */
if (OMPI_SUCCESS !=
(ret = ompi_value_array_append_item(&mca_base_params, &param))) {
return ret;
}
return ompi_value_array_get_size(&mca_base_params) - 1;
}
/*
* Lookup a parameter
*/
static bool param_lookup(int index, mca_base_param_storage_t *storage,
ompi_hash_table_t *attrs)
{
size_t size;
char *env;
int err, flag;
mca_base_param_t *array;
/* Lookup the index and see if it's valid */
if (!initialized) {
return false;
}
if (ompi_value_array_get_size(&mca_base_params) < index) {
return false;
}
size = ompi_value_array_get_size(&mca_base_params);
array = OMPI_VALUE_ARRAY_GET_BASE(&mca_base_params, mca_base_param_t);
/* Ensure that MCA param has a good type */
if (MCA_BASE_PARAM_TYPE_INT != array[index].mbp_type &&
MCA_BASE_PARAM_TYPE_STRING != array[index].mbp_type) {
return false;
}
/* If this param has a keyval and we were provided with a hash
table, look it up and see if we can find a value */
if (-1 != array[index].mbp_keyval) {
/* Use the stringval member of the union because it's definitely
big enough to handle both (int) and (char*) */
err = ompi_attr_get(attrs, array[index].mbp_keyval,
&storage->stringval, &flag);
if (OMPI_SUCCESS == err && 1 == flag) {
/* Because of alignment weirdness between (void*) and int, we
must grab the lower sizeof(int) bytes from the (char*) in
stringval, in case sizeof(int) != sizeof(char*). */
if (MCA_BASE_PARAM_TYPE_INT == array[index].mbp_type) {
storage->intval = *((int *) (storage->stringval +
sizeof(void *) - sizeof(int)));
}
/* Nothing to do for string -- we already have the value loaded
in the right place */
return true;
}
}
/* We either don't have a keyval or didn't find it. So look in the
environment. */
if (NULL != array[index].mbp_env_var_name &&
NULL != (env = getenv(array[index].mbp_env_var_name))) {
if (MCA_BASE_PARAM_TYPE_INT == array[index].mbp_type) {
storage->intval = atoi(env);
} else if (MCA_BASE_PARAM_TYPE_STRING == array[index].mbp_type) {
storage->stringval = strdup(env);
}
return true;
}
/* Didn't find it; use the default value. */
switch (array[index].mbp_type) {
case MCA_BASE_PARAM_TYPE_INT:
storage->intval = array[index].mbp_default_value.intval;
break;
case MCA_BASE_PARAM_TYPE_STRING:
if (NULL != array[index].mbp_default_value.stringval) {
storage->stringval = strdup(array[index].mbp_default_value.stringval);
} else {
storage->stringval = NULL;
}
break;
default:
return false;
}
/* All done */
return true;
}
/*
* Create an empty param container
*/
static void param_constructor(mca_base_param_t *p)
{
p->mbp_type = MCA_BASE_PARAM_TYPE_MAX;
p->mbp_type_name = NULL;
p->mbp_component_name = NULL;
p->mbp_param_name = NULL;
p->mbp_full_name = NULL;
p->mbp_keyval = -1;
p->mbp_env_var_name = NULL;
p->mbp_default_value.stringval = NULL;
}
/*
* Free all the contents of a param container
*/
static void param_destructor(mca_base_param_t *p)
{
if (NULL != p->mbp_type_name) {
free(p->mbp_type_name);
}
if (NULL != p->mbp_component_name) {
free(p->mbp_component_name);
}
if (NULL != p->mbp_param_name) {
free(p->mbp_param_name);
}
if (NULL != p->mbp_env_var_name) {
free(p->mbp_env_var_name);
}
if (NULL != p->mbp_full_name) {
free(p->mbp_full_name);
}
if (MCA_BASE_PARAM_TYPE_STRING == p->mbp_type &&
NULL != p->mbp_default_value.stringval) {
free(p->mbp_default_value.stringval);
}
}