1
1

Lots of revisions to the MCA base; too numerous to mention here

(continued evolution / implementation of the MCA base).

This commit was SVN r524.
Этот коммит содержится в:
Jeff Squyres 2004-01-22 00:37:58 +00:00
родитель 9ec1f24872
Коммит 79c5f8826c
10 изменённых файлов: 475 добавлений и 83 удалений

Просмотреть файл

@ -14,13 +14,36 @@
#include "mca/lam/base/mca_base_module_exchange.h"
/*
* Structure for making plain lists of modules
*/
struct mca_base_module_list_item_t {
lam_list_item_t super;
const mca_base_module_t *mli_module;
};
typedef struct mca_base_module_list_item_t mca_base_module_list_item_t;
/*
* Structure for making priority lists of modules
*/
struct mca_base_module_priority_list_item_t {
lam_list_item_t super;
int mpli_priority;
int mpli_thread_min, mpli_thread_max;
mca_base_module_t *mpli_module;
};
typedef struct mca_base_module_priority_list_item_t
mca_base_module_priority_list_item_t;
/*
* Public variables
*/
extern int mca_base_param_module_path;
/*
* Public functions
*/
@ -44,27 +67,38 @@ extern "C" {
/* mca_base_module_compare.c */
int mca_base_module_compare(mca_base_module_priority_t *a,
mca_base_module_priority_t *b);
int mca_base_module_compare(mca_base_module_priority_list_item_t *a,
mca_base_module_priority_list_item_t *b);
/* mca_base_module_find.c */
int mca_base_module_find(const char *directory, const char *type,
mca_base_module_t *static_modules[],
const mca_base_module_t *static_modules[],
lam_list_t *found_modules);
/* mca_base_module_register.c */
int mca_base_module_registry_init(void);
int mca_base_module_registry_retain(char *type, lt_dlhandle module_handle,
mca_base_module_t *module_struct);
const mca_base_module_t *module_struct);
int mca_base_module_registry_link(const char *src_type,
const char *src_name,
const char *depend_type,
const char *depend_name);
void mca_base_module_registry_release(mca_base_module_t *module);
void mca_base_module_registry_release(const mca_base_module_t *module);
void mca_base_module_registry_finalize(void);
/* mca_base_modules_open.c */
int mca_base_modules_open(const char *type_name, int output_id,
const mca_base_module_t **static_modules,
lam_list_t *modules_available);
/* mca_base_modules_close.c */
int mca_base_modules_close(int output_id, lam_list_t *modules_available,
const mca_base_module_t *skip);
#if defined(c_plusplus) || defined(__cplusplus)
}
#endif

Просмотреть файл

@ -14,6 +14,8 @@
*/
int mca_base_close(void)
{
extern bool mca_base_opened;
if (mca_base_opened) {
/* Clear out all the registered MCA params */
mca_base_param_finalize();
@ -21,6 +23,8 @@ int mca_base_close(void)
/* Close down the module registry */
mca_base_module_registry_finalize();
}
mca_base_opened = false;
/* All done */

Просмотреть файл

@ -22,20 +22,20 @@
* may help the gentle reader to consider this an inverse comparison.
* :-)
*/
int mca_base_module_compare(mca_base_module_priority_t *a,
mca_base_module_priority_t *b)
int mca_base_module_compare(mca_base_module_priority_list_item_t *a,
mca_base_module_priority_list_item_t *b)
{
int val;
/* First, compare the priorties */
if (a->lsm_priority > b->lsm_priority)
if (a->mpli_priority > b->mpli_priority)
return -1;
else if (a->lsm_priority < b->lsm_priority)
else if (a->mpli_priority < b->mpli_priority)
return 1;
else {
mca_base_module_t *aa = a->lsm_module;
mca_base_module_t *bb = b->lsm_module;
mca_base_module_t *aa = a->mpli_module;
mca_base_module_t *bb = b->mpli_module;
/* The priorities were equal, so compare the names */

Просмотреть файл

@ -92,23 +92,23 @@ static lam_list_t found_files;
* available modules.
*/
int mca_base_module_find(const char *directory, const char *type,
mca_base_module_t *static_modules[],
const mca_base_module_t *static_modules[],
lam_list_t *found_modules)
{
int i;
mca_base_module_list_item_t *item;
mca_base_module_list_item_t *mli;
/* Find all the modules that were statically linked in */
lam_list_init(found_modules);
for (i = 0; NULL != static_modules[i]; ++i) {
item = LAM_MALLOC(sizeof(mca_base_module_list_item_t));
if (NULL == item) {
mli = LAM_MALLOC(sizeof(mca_base_module_list_item_t));
if (NULL == mli) {
return LAM_ERR_OUT_OF_RESOURCE;
}
lam_list_item_init((lam_list_item_t *) item);
item->mli_module = static_modules[i];
lam_list_append(found_modules, (lam_list_item_t *) item);
lam_list_item_init((lam_list_item_t *) mli);
mli->mli_module = static_modules[i];
lam_list_append(found_modules, (lam_list_item_t *) mli);
}
/* Find any available dynamic modules in the specified directory */
@ -132,36 +132,40 @@ int mca_base_module_find(const char *directory, const char *type,
* functionality, we would not get the directory name of the file
* finally opened in recursive dependency traversals.
*/
static void find_dyn_modules(const char *path, const char *type,
static void find_dyn_modules(const char *path, const char *type_name,
const char *name, lam_list_t *found_modules)
{
ltfn_data_holder_t params;
char *path_to_use, *dir, *end;
char *path_to_use, *dir, *end, *param;
module_file_item_t *file;
lam_list_item_t *cur;
strcpy(params.type, type);
strcpy(params.name, name);
strcpy(params.type, type_name);
if (NULL == name) {
params.name[0] = '\0';
lam_output_verbose(0, 40, " looking for all dynamic %s MCA modules",
type, NULL);
type_name, NULL);
} else {
strcpy(params.name, name);
lam_output_verbose(0, 40,
" looking for dynamic %s MCA module named \"%s\"",
type, name, NULL);
type_name, name, NULL);
}
/* If directory is NULL, iterate over the set of directories
specified by the MCA param mca_base_module_path. If path is not
NULL, then use that as the path. */
param = NULL;
if (NULL == path) {
mca_base_param_lookup_string(mca_base_param_module_path, &dir);
path_to_use = strdup(dir);
mca_base_param_lookup_string(mca_base_param_module_path, &param);
dir = param;
}
if (NULL == path) {
path_to_use = strdup(path);
if (NULL == dir) {
path_to_use = NULL;
} else {
path_to_use = strdup(dir);
}
/* Iterate over all the files in the directories in the path and
@ -208,7 +212,13 @@ static void find_dyn_modules(const char *path, const char *type,
/* All done */
if (NULL != param) {
LAM_FREE(param);
}
/* JMS This list memory management may change */
#if 0
lam_list_destroy(&found_files);
#endif
LAM_FREE(path_to_use);
}
@ -538,7 +548,7 @@ static int check_dependency(char *line, module_file_item_t *target_file,
target_file->status = CHECKING_CYCLE;
for (happiness = false, cur = lam_list_get_first(&found_files);
lam_list_get_last(&found_files) != cur;
lam_list_get_end(&found_files) != cur;
cur = lam_list_get_next(cur)) {
mitem = (module_file_item_t *) cur;

Просмотреть файл

@ -26,7 +26,7 @@ struct registry_item_t {
char ri_type[MCA_BASE_MAX_TYPE_NAME_LEN];
lt_dlhandle ri_dlhandle;
mca_base_module_t *ri_module_struct;
const mca_base_module_t *ri_module_struct;
int ri_refcount;
lam_list_t ri_dependencies;
};
@ -60,14 +60,15 @@ static void release_registry_item(registry_item_t *ri);
*/
int mca_base_module_registry_init(void)
{
/* Initialized libltdl */
/* Setup internal structures */
if (!initialized) {
/* Initialize libltdl */
if (lt_dlinit() != 0)
return LAM_ERR_OUT_OF_RESOURCE;
/* Setup internal structures */
if (!initialized) {
lam_list_init(&registry);
initialized = true;
}
@ -83,7 +84,7 @@ int mca_base_module_registry_init(void)
* The module's type, handle, and public struct are saved.
*/
int mca_base_module_registry_retain(char *type, lt_dlhandle module_handle,
mca_base_module_t *module_struct)
const mca_base_module_t *module_struct)
{
registry_item_t *ri;
@ -141,7 +142,7 @@ int mca_base_module_registry_link(const char *src_type,
* If it's in the registr, close a specified module and remove it from
* the registry.
*/
void mca_base_module_registry_release(mca_base_module_t *module)
void mca_base_module_registry_release(const mca_base_module_t *module)
{
registry_item_t *ri = find_module(module->mca_type_name,
module->mca_module_name);
@ -177,7 +178,7 @@ void mca_base_module_registry_finalize(void)
do {
changed = false;
for (item = lam_list_get_first(&registry);
lam_list_get_last(&registry) != item && changed;
lam_list_get_end(&registry) != item && changed;
item = lam_list_get_next(item)) {
ri = (registry_item_t *) ri;
@ -187,13 +188,12 @@ void mca_base_module_registry_finalize(void)
}
}
} while (lam_list_get_size(&registry) > 0 && changed);
lam_list_destroy(&registry);
initialized = false;
}
/* Close down libltdl */
lt_dlexit();
initialized = false;
}
}
@ -203,7 +203,7 @@ static registry_item_t *find_module(const char *type, const char *name)
registry_item_t *ri;
for (item = lam_list_get_first(&registry);
lam_list_get_last(&registry) != item;
lam_list_get_end(&registry) != item;
item = lam_list_get_next(item)) {
ri = (registry_item_t *) ri;
if (0 == strcmp(ri->ri_type, type) &&

66
src/mca/lam/base/mca_base_modules_close.c Обычный файл
Просмотреть файл

@ -0,0 +1,66 @@
/*
* $HEADER$
*/
#include "lam_config.h"
#include "lam/lfc/list.h"
#include "lam/util/output.h"
#include "mca/mca.h"
#include "mca/lam/base/base.h"
int mca_base_modules_close(int output_id, lam_list_t *modules_available,
const mca_base_module_t *skip)
{
lam_list_item_t *item;
mca_base_module_list_item_t *mli;
const mca_base_module_t *module;
/* Close and unload all modules in the available list, except the
"skip" item. This is handy to close out all non-selected
modules. It's easier to simply remove the entire list and then
simply re-add the skip entry when done. */
for (item = lam_list_remove_first(modules_available);
NULL != item;
item = lam_list_remove_first(modules_available)) {
mli = (mca_base_module_list_item_t *) item;
module = mli->mli_module;
if (module != skip) {
/* Close */
if (NULL != module->mca_close_module) {
module->mca_close_module();
lam_output_verbose(10, output_id, "close: module %s closed",
module->mca_module_name);
}
/* Unload */
mca_base_module_registry_release((mca_base_module_t *) module);
lam_output_verbose(10, output_id, "close: module %s unloaded",
module->mca_module_name);
}
LAM_FREE(mli);
}
/* Re-add the skipped module to the available list (see above
comment) */
if (NULL != skip) {
mli = LAM_MALLOC(sizeof(mca_base_module_list_item_t));
if (NULL == mli) {
return LAM_ERR_OUT_OF_RESOURCE;
}
mli->mli_module = skip;
lam_list_append(modules_available, (lam_list_item_t *) mli);
}
/* All done */
return LAM_SUCCESS;
}

266
src/mca/lam/base/mca_base_modules_open.c Обычный файл
Просмотреть файл

@ -0,0 +1,266 @@
/*
* $HEADER$
*/
#include "lam_config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "lam/lfc/list.h"
#include "lam/util/strncpy.h"
#include "lam/util/argv.h"
#include "mca/mca.h"
#include "mca/lam/base/base.h"
struct module_name_t {
lam_list_item_t super;
char mn_name[MCA_BASE_MAX_MODULE_NAME_LEN];
};
typedef struct module_name_t module_name_t;
/*
* Local functions
*/
static int open_modules(const char *type_name, int output_id,
lam_list_t *modules_found,
lam_list_t *modules_available,
char **requested_module_names);
static int parse_requested(int mca_param, char ***requested_module_names);
/**
* Function for finding and opening either all MCA modules, or the one
* that was specifically requested via a MCA parameter.
*/
int mca_base_modules_open(const char *type_name, int output_id,
const mca_base_module_t **static_modules,
lam_list_t *modules_available)
{
int ret;
lam_list_item_t *item;
lam_list_t modules_found;
char **requested_module_names;
int param_verbose = -1;
int param_type;
/* Register MCA parameter */
param_verbose = mca_base_param_register_string(type_name, "base", "verbose",
NULL, NULL);
param_type = mca_base_param_register_string(type_name, "base", NULL,
NULL, NULL);
/* Setup verbosity for this MCA type */
#if 0
mca_base_set_verbose(param_verbose, &lds,
&mca_pcm_verbose, &mca_pcm_did);
#endif
lam_output_verbose(10, output_id, "open: Looking for modules");
/* Find and load all available modules */
if (LAM_SUCCESS !=
mca_base_module_find(NULL, type_name, static_modules, &modules_found)) {
return LAM_ERROR;
}
/* See if one or more specific modules were requested */
ret = parse_requested(param_type, &requested_module_names);
if (LAM_SUCCESS == ret) {
ret = open_modules(type_name, output_id, &modules_found, modules_available,
requested_module_names);
}
/* Free resources */
for (item = lam_list_remove_first(&modules_found); NULL != item;
item = lam_list_remove_first(&modules_found)) {
LAM_FREE(item);
}
if (NULL != requested_module_names) {
lam_argv_free(requested_module_names);
}
/* All done */
return ret;
}
static int parse_requested(int mca_param, char ***requested_module_names)
{
char *requested;
char *comma;
char *start;
int argc;
*requested_module_names = NULL;
/* See if the user requested anything */
if (LAM_ERROR == mca_base_param_lookup_string(mca_param, &requested)) {
return LAM_ERROR;
}
if (NULL == requested) {
return LAM_SUCCESS;
}
/* Loop over all names (yes, this could be more clever, but it's
nice and obvious this way!) */
start = requested;
comma = strchr(start, ',');
while (NULL != comma) {
*comma = '\0';
lam_argv_append(&argc, requested_module_names, start);
start = comma + 1;
comma = strchr(start, ',');
}
/* The last name */
lam_argv_append(&argc, requested_module_names, start);
/* All done */
return LAM_SUCCESS;
}
/*
* Traverse the entire list of found modules (a list of
* mca_base_module_t instances). If the requested_module_names array
* is empty, or the name of each module in the list of found modules
* is in the requested_modules_array, try to open it. If it opens,
* add it to the modules_available list.
*/
static int open_modules(const char *type_name, int output_id,
lam_list_t *modules_found,
lam_list_t *modules_available,
char **requested_module_names)
{
int i;
lam_list_item_t *item;
const mca_base_module_t *module;
mca_base_module_list_item_t *mli;
bool acceptable;
bool called_open;
bool opened;
/* Announce */
if (NULL == requested_module_names) {
lam_output_verbose(10, output_id,
"open: looking for any %s modules", type_name);
} else {
lam_output_verbose(10, output_id,
"open: looking for specific %s modules:", type_name);
for (i = 0; NULL != requested_module_names[i]; ++i) {
lam_output_verbose(10, output_id, "open: %s",
requested_module_names[i]);
}
}
/* Traverse the list of found modules */
lam_list_init(modules_available);
for (item = lam_list_get_first(modules_found);
lam_list_get_end(modules_found) != item;
item = lam_list_get_next(item)) {
mli = (mca_base_module_list_item_t *) item;
module = mli->mli_module;
/* Do we need to check for specific modules? */
if (NULL != requested_module_names) {
acceptable = false;
for (i = 0; NULL != requested_module_names[i]; ++i) {
if (0 == strcmp(requested_module_names[i], module->mca_module_name)) {
acceptable = true;
break;
}
}
} else {
acceptable = true;
}
/* If this is an acceptable module, try to open it */
if (acceptable) {
opened = called_open = false;
lam_output_verbose(10, output_id, "open: found loaded module %s",
module->mca_module_name);
if (NULL == module->mca_open_module) {
opened = true;
lam_output_verbose(10, output_id,
"open: module %s has no open function",
module->mca_module_name);
} else {
called_open = true;
if (MCA_SUCCESS == module->mca_open_module()) {
opened = true;
lam_output_verbose(10, output_id,
"open: module %s open function successful",
module->mca_module_name);
} else {
lam_output_verbose(10, output_id,
"open: module %s open function failed",
module->mca_module_name);
}
}
/* If it didn't open, close it out and get rid of it */
if (!opened) {
if (called_open) {
if (NULL != module->mca_close_module) {
module->mca_close_module();
}
lam_output_verbose(10, output_id,
"open: module %s closed",
module->mca_module_name);
called_open = false;
}
mca_base_module_registry_release(module);
lam_output_verbose(10, output_id,
"open: module %s unloaded",
module->mca_module_name);
}
/* If it did open, register its "priority" MCA parameter (if it
doesn't already have one) and save it in the opened_modules
list */
else {
if (LAM_ERROR == mca_base_param_find(type_name,
module->mca_module_name,
"priority")) {
mca_base_param_register_int(type_name,
module->mca_module_name,
"priority", NULL, 0);
}
mli = LAM_MALLOC(sizeof(mca_base_module_list_item_t));
if (NULL == mli) {
return LAM_ERROR;
}
lam_list_item_init(&mli->super);
mli->mli_module = module;
lam_list_append(modules_available, (lam_list_item_t *) mli);
}
}
}
/* All done */
return LAM_SUCCESS;
}

Просмотреть файл

@ -18,7 +18,7 @@
* Public variables
*/
int mca_base_param_module_path = -1;
bool mca_base_opened = false;
/*
* Private functions
@ -36,10 +36,17 @@ int mca_base_open(void)
char *value;
lam_output_stream_t lds;
if (!mca_base_opened) {
mca_base_opened = true;
} else {
return LAM_SUCCESS;
}
/* Register some params */
mca_base_param_module_path =
mca_base_param_register_string("base", NULL, "module_path",
"module_path", NULL);
"module_path", LAM_PKGLIBDIR);
param_index = mca_base_param_register_string("base", NULL, "verbose",
"verbose", NULL);

Просмотреть файл

@ -128,7 +128,7 @@ int mca_base_param_register_string(const char *type_name,
{
mca_base_param_storage_t storage;
if (NULL != default_value)
storage.stringval = strdup(default_value);
storage.stringval = (char *) default_value;
else
storage.stringval = NULL;
return param_register(type_name, module_name, param_name, mca_param_name,
@ -262,13 +262,19 @@ int mca_base_param_finalize(void)
size_t i, size;
mca_base_param_t **array;
lam_malloc_debug(2);
if (initialized) {
array = (mca_base_param_t**) lam_arr_get_c_array(&mca_base_params, &size);
for (i = 0; i < size; ++i) {
param_free(array[i]);
/* JMS Memory management of the array may change when array.[ch]
changes */
LAM_FREE(array[i]);
lam_arr_remove_item(&mca_base_params, i);
}
lam_arr_destroy(&mca_base_params);
/* JMS Memory management of the array may change when array.[ch]
changes */
LAM_FREE(array);
initialized = false;
}
@ -347,10 +353,16 @@ static int param_register(const char *type_name, const char *module_name,
}
param->mbp_full_name = LAM_MALLOC(len);
if (NULL != param->mbp_full_name) {
if (NULL == param->mbp_full_name) {
if (NULL != param->mbp_type_name) {
LAM_FREE(param->mbp_type_name);
}
if (NULL != param->mbp_module_name) {
LAM_FREE(param->mbp_module_name);
}
if (NULL != param->mbp_param_name) {
LAM_FREE(param->mbp_param_name);
}
return LAM_ERROR;
}
strncpy(param->mbp_full_name, type_name, len);
@ -415,6 +427,7 @@ static int param_register(const char *type_name, const char *module_name,
}
param_free(param);
LAM_FREE(param);
return i;
}
}
@ -456,10 +469,6 @@ static bool param_lookup(int index, mca_base_param_storage_t *storage)
array = (mca_base_param_t **) lam_arr_get_c_array(&mca_base_params,
&size);
p = array[index];
#if 0
p = ((mca_base_param_t*) lam_arr_get_c_array(&mca_base_params,
&size)) + index;
#endif
/* We either don't have a keyval or didn't find it. So look in the
environment. */
@ -485,7 +494,11 @@ static bool param_lookup(int index, mca_base_param_storage_t *storage)
break;
case MCA_BASE_PARAM_TYPE_STRING:
storage->stringval = p->mbp_default_value.stringval;
if (NULL != p->mbp_default_value.stringval) {
storage->stringval = strdup(p->mbp_default_value.stringval);
} else {
storage->stringval = NULL;
}
break;
default:
@ -528,5 +541,4 @@ static void param_free(mca_base_param_t *p)
NULL != p->mbp_default_value.stringval) {
LAM_FREE(p->mbp_default_value.stringval);
}
LAM_FREE(p);
}

Просмотреть файл

@ -92,26 +92,19 @@ typedef struct mca_base_module_data_1_0_0_t mca_base_module_data_1_0_0_t;
/*
* Lists of modules
* Return codes
*/
struct mca_base_module_list_item_t {
lam_list_item_t super;
mca_base_module_t *mli_module;
enum {
MCA_SUCCESS = 0,
MCA_ERROR = -1,
MCA_ERR_OUT_OF_RESOURCE = -2, /* fatal error */
MCA_ERR_TEMP_OUT_OF_RESOURCE = -3, /* try again later */
MCA_ERR_BAD_PARAM = -5, /* equivalent to MPI_ERR_ARG error code */
MCA_ERR_NOT_IMPLEMENTED = -10,
MCA_ERR_NOT_SUPPORTED = -11,
MCA_MAX_ERROR = -20
};
typedef struct mca_base_module_list_item_t mca_base_module_list_item_t;
/*
* Structure for making priority lists of modules
*/
struct mca_base_module_priority_t {
lam_list_item_t super;
int lsm_priority;
int lsm_thread_min, lsm_thread_max;
mca_base_module_t *lsm_module;
};
typedef struct mca_base_module_priority_t mca_base_module_priority_t;
/*