|
Packit Service |
c5cf8c |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* (C) 2013 by Argonne National Laboratory.
|
|
Packit Service |
c5cf8c |
* See COPYRIGHT in top-level directory.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include "mpiimpl.h"
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int MPIR_T_init_balance = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifdef MPICH_IS_THREADED
|
|
Packit Service |
c5cf8c |
MPID_Thread_mutex_t mpi_t_mutex;
|
|
Packit Service |
c5cf8c |
int MPIR_T_is_threaded;
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* These variables must be initialized in MPI_T_initthread. Especially,
|
|
Packit Service |
c5cf8c |
* hash table pointers must be initialized to NULL.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int cat_stamp;
|
|
Packit Service |
c5cf8c |
UT_array *enum_table;
|
|
Packit Service |
c5cf8c |
UT_array *cat_table;
|
|
Packit Service |
c5cf8c |
UT_array *cvar_table;
|
|
Packit Service |
c5cf8c |
UT_array *pvar_table;
|
|
Packit Service |
c5cf8c |
name2index_hash_t *cat_hash;
|
|
Packit Service |
c5cf8c |
name2index_hash_t *cvar_hash;
|
|
Packit Service |
c5cf8c |
name2index_hash_t *pvar_hashs[MPIR_T_PVAR_CLASS_NUMBER];
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Create an enum.
|
|
Packit Service |
c5cf8c |
* IN: enum_name, name of the enum
|
|
Packit Service |
c5cf8c |
* OUT: handle, handle of the enum
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
void MPIR_T_enum_create(const char *enum_name, MPI_T_enum * handle)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
MPIR_T_enum_t *e;
|
|
Packit Service |
c5cf8c |
static const UT_icd enum_item_icd = { sizeof(enum_item_t), NULL, NULL, NULL };
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPIR_Assert(enum_name);
|
|
Packit Service |
c5cf8c |
MPIR_Assert(handle);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
utarray_extend_back(enum_table, MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
e = (MPIR_T_enum_t *) utarray_back(enum_table);
|
|
Packit Service |
c5cf8c |
e->name = MPL_strdup(enum_name);
|
|
Packit Service |
c5cf8c |
MPIR_Assert(e->name);
|
|
Packit Service |
c5cf8c |
#ifdef HAVE_ERROR_CHECKING
|
|
Packit Service |
c5cf8c |
e->kind = MPIR_T_ENUM_HANDLE;
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
utarray_new(e->items, &enum_item_icd, MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
(*handle) = e;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Add an item to an exisiting enum.
|
|
Packit Service |
c5cf8c |
* IN: handle, handle to the enum
|
|
Packit Service |
c5cf8c |
* IN: item_name, name of the item
|
|
Packit Service |
c5cf8c |
* IN: item_value, value associated with item_name
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
void MPIR_T_enum_add_item(MPI_T_enum handle, const char *item_name, int item_value)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
enum_item_t *item;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPIR_Assert(handle);
|
|
Packit Service |
c5cf8c |
MPIR_Assert(item_name);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
utarray_extend_back(handle->items, MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
item = (enum_item_t *) utarray_back(handle->items);
|
|
Packit Service |
c5cf8c |
item->name = MPL_strdup(item_name);
|
|
Packit Service |
c5cf8c |
MPIR_Assert(item->name);
|
|
Packit Service |
c5cf8c |
item->value = item_value;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Create a new category with name <cat_name>.
|
|
Packit Service |
c5cf8c |
* The new category is pushed at the back of cat_table.
|
|
Packit Service |
c5cf8c |
* Aslo, a new hash entry is added for the category in cat_hash.
|
|
Packit Service |
c5cf8c |
* Return the newly created category.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
static cat_table_entry_t *MPIR_T_cat_create(const char *cat_name)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int cat_idx;
|
|
Packit Service |
c5cf8c |
cat_table_entry_t *cat;
|
|
Packit Service |
c5cf8c |
name2index_hash_t *hash_entry;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* New a category */
|
|
Packit Service |
c5cf8c |
utarray_extend_back(cat_table, MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
cat = (cat_table_entry_t *) utarray_back(cat_table);
|
|
Packit Service |
c5cf8c |
cat->name = MPL_strdup(cat_name);
|
|
Packit Service |
c5cf8c |
cat->desc = NULL;
|
|
Packit Service |
c5cf8c |
utarray_new(cat->cvar_indices, &ut_int_icd, MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
utarray_new(cat->pvar_indices, &ut_int_icd, MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
utarray_new(cat->subcat_indices, &ut_int_icd, MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Record <cat_name, cat_idx> in cat_hash */
|
|
Packit Service |
c5cf8c |
cat_idx = utarray_len(cat_table) - 1;
|
|
Packit Service |
c5cf8c |
hash_entry = MPL_malloc(sizeof(name2index_hash_t), MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
MPIR_Assert(hash_entry);
|
|
Packit Service |
c5cf8c |
/* Need not to Strdup cat_name, since cat_table and cat_hash co-exist */
|
|
Packit Service |
c5cf8c |
hash_entry->name = cat_name;
|
|
Packit Service |
c5cf8c |
hash_entry->idx = cat_idx;
|
|
Packit Service |
c5cf8c |
HASH_ADD_KEYPTR(hh, cat_hash, hash_entry->name,
|
|
Packit Service |
c5cf8c |
strlen(hash_entry->name), hash_entry, MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return cat;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Add a pvar to an existing or new category
|
|
Packit Service |
c5cf8c |
* IN: cat_name, name of the category
|
|
Packit Service |
c5cf8c |
* IN: pvar_index, index of the pvar as defined by MPI_T_pvar_handle_alloc()
|
|
Packit Service |
c5cf8c |
* If cat_name is NULL or a empty string, nothing happpens.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int MPIR_T_cat_add_pvar(const char *cat_name, int pvar_index)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int mpi_errno = MPI_SUCCESS;
|
|
Packit Service |
c5cf8c |
name2index_hash_t *hash_entry;
|
|
Packit Service |
c5cf8c |
cat_table_entry_t *cat;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* NULL or empty string are allowed */
|
|
Packit Service |
c5cf8c |
if (cat_name == NULL || *cat_name == '\0')
|
|
Packit Service |
c5cf8c |
goto fn_exit;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
HASH_FIND_STR(cat_hash, cat_name, hash_entry);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (hash_entry != NULL) {
|
|
Packit Service |
c5cf8c |
/* Found it, i.e., category already exists */
|
|
Packit Service |
c5cf8c |
int cat_idx = hash_entry->idx;
|
|
Packit Service |
c5cf8c |
cat = (cat_table_entry_t *) utarray_eltptr(cat_table, cat_idx);
|
|
Packit Service |
c5cf8c |
/* FIXME: Is it worth checking duplicated vars? Probably not */
|
|
Packit Service |
c5cf8c |
utarray_push_back(cat->pvar_indices, &pvar_index, MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* Not found, so create a new category */
|
|
Packit Service |
c5cf8c |
cat = MPIR_T_cat_create(cat_name);
|
|
Packit Service |
c5cf8c |
utarray_push_back(cat->pvar_indices, &pvar_index, MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
/* Notify categories have been changed */
|
|
Packit Service |
c5cf8c |
cat_stamp++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
fn_exit:
|
|
Packit Service |
c5cf8c |
return mpi_errno;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Add a cvar to an existing or new category
|
|
Packit Service |
c5cf8c |
* IN: cat_name, name of the category
|
|
Packit Service |
c5cf8c |
* IN: cvar_index, index of the cvar as defined by MPI_T_cvar_handle_alloc()
|
|
Packit Service |
c5cf8c |
* If cat_name is NULL or a empty string, nothing happpens.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int MPIR_T_cat_add_cvar(const char *cat_name, int cvar_index)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int mpi_errno = MPI_SUCCESS;
|
|
Packit Service |
c5cf8c |
name2index_hash_t *hash_entry;
|
|
Packit Service |
c5cf8c |
cat_table_entry_t *cat;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* NULL or empty string are allowed */
|
|
Packit Service |
c5cf8c |
if (cat_name == NULL || *cat_name == '\0')
|
|
Packit Service |
c5cf8c |
goto fn_exit;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
HASH_FIND_STR(cat_hash, cat_name, hash_entry);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (hash_entry != NULL) {
|
|
Packit Service |
c5cf8c |
/* Found it, i.e., category already exists */
|
|
Packit Service |
c5cf8c |
int cat_idx = hash_entry->idx;
|
|
Packit Service |
c5cf8c |
cat = (cat_table_entry_t *) utarray_eltptr(cat_table, cat_idx);
|
|
Packit Service |
c5cf8c |
/* FIXME: Is it worth checking duplicated vars? Probably not */
|
|
Packit Service |
c5cf8c |
utarray_push_back(cat->cvar_indices, &cvar_index, MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* Not found, so create a new category */
|
|
Packit Service |
c5cf8c |
cat = MPIR_T_cat_create(cat_name);
|
|
Packit Service |
c5cf8c |
utarray_push_back(cat->cvar_indices, &cvar_index, MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
/* Notify categories have been changed */
|
|
Packit Service |
c5cf8c |
cat_stamp++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
fn_exit:
|
|
Packit Service |
c5cf8c |
return mpi_errno;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Add a sub-category to an existing or new category
|
|
Packit Service |
c5cf8c |
* IN: parent_name, name of the parent category
|
|
Packit Service |
c5cf8c |
* IN: child_name, name of the child category
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int MPIR_T_cat_add_subcat(const char *parent_name, const char *child_name)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int mpi_errno = MPI_SUCCESS;
|
|
Packit Service |
c5cf8c |
int parent_index, child_index;
|
|
Packit Service |
c5cf8c |
name2index_hash_t *hash_entry;
|
|
Packit Service |
c5cf8c |
cat_table_entry_t *parent;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* NULL or empty string are allowed */
|
|
Packit Service |
c5cf8c |
if (parent_name == NULL || *parent_name == '\0' || child_name == NULL || *child_name == '\0') {
|
|
Packit Service |
c5cf8c |
goto fn_exit;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Find or create parent */
|
|
Packit Service |
c5cf8c |
HASH_FIND_STR(cat_hash, parent_name, hash_entry);
|
|
Packit Service |
c5cf8c |
if (hash_entry != NULL) {
|
|
Packit Service |
c5cf8c |
/* Found parent in cat_table */
|
|
Packit Service |
c5cf8c |
parent_index = hash_entry->idx;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* parent is a new category */
|
|
Packit Service |
c5cf8c |
MPIR_T_cat_create(parent_name);
|
|
Packit Service |
c5cf8c |
parent_index = utarray_len(cat_table) - 1;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Find or create child */
|
|
Packit Service |
c5cf8c |
HASH_FIND_STR(cat_hash, child_name, hash_entry);
|
|
Packit Service |
c5cf8c |
if (hash_entry != NULL) {
|
|
Packit Service |
c5cf8c |
/* Found child in cat_table */
|
|
Packit Service |
c5cf8c |
child_index = hash_entry->idx;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* child is a new category */
|
|
Packit Service |
c5cf8c |
MPIR_T_cat_create(child_name);
|
|
Packit Service |
c5cf8c |
child_index = utarray_len(cat_table) - 1;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Connect parent and child */
|
|
Packit Service |
c5cf8c |
parent = (cat_table_entry_t *) utarray_eltptr(cat_table, parent_index);
|
|
Packit Service |
c5cf8c |
utarray_push_back(parent->subcat_indices, &child_index, MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Notify categories have been changed */
|
|
Packit Service |
c5cf8c |
cat_stamp++;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
fn_exit:
|
|
Packit Service |
c5cf8c |
return mpi_errno;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Add description to an existing or new category
|
|
Packit Service |
c5cf8c |
* IN: cat_name, name of the category
|
|
Packit Service |
c5cf8c |
* IN: cat_desc, description of the category
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int MPIR_T_cat_add_desc(const char *cat_name, const char *cat_desc)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int cat_idx, mpi_errno = MPI_SUCCESS;
|
|
Packit Service |
c5cf8c |
name2index_hash_t *hash_entry;
|
|
Packit Service |
c5cf8c |
cat_table_entry_t *cat;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* NULL args are not allowed */
|
|
Packit Service |
c5cf8c |
MPIR_Assert(cat_name);
|
|
Packit Service |
c5cf8c |
MPIR_Assert(cat_desc);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
HASH_FIND_STR(cat_hash, cat_name, hash_entry);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (hash_entry != NULL) {
|
|
Packit Service |
c5cf8c |
/* Found it, i.e., category already exists */
|
|
Packit Service |
c5cf8c |
cat_idx = hash_entry->idx;
|
|
Packit Service |
c5cf8c |
cat = (cat_table_entry_t *) utarray_eltptr(cat_table, cat_idx);
|
|
Packit Service |
c5cf8c |
MPIR_Assert(cat->desc == NULL);
|
|
Packit Service |
c5cf8c |
cat->desc = MPL_strdup(cat_desc);
|
|
Packit Service |
c5cf8c |
MPIR_Assert(cat->desc);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* Not found, so create a new category */
|
|
Packit Service |
c5cf8c |
cat = MPIR_T_cat_create(cat_name);
|
|
Packit Service |
c5cf8c |
cat->desc = MPL_strdup(cat_desc);
|
|
Packit Service |
c5cf8c |
MPIR_Assert(cat->desc);
|
|
Packit Service |
c5cf8c |
/* Notify categories have been changed */
|
|
Packit Service |
c5cf8c |
cat_stamp++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return mpi_errno;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* A low level, generic and internally used interface to register
|
|
Packit Service |
c5cf8c |
* a cvar to the MPIR_T.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* IN: dtype, MPI datatype for this cvar
|
|
Packit Service |
c5cf8c |
* IN: name, Name of the cvar
|
|
Packit Service |
c5cf8c |
* IN: addr, Pointer to the cvar if known at registeration, otherwise NULL.
|
|
Packit Service |
c5cf8c |
* IN: count, # of elements of this cvar if known at registeration, otherwise 0.
|
|
Packit Service |
c5cf8c |
* IN: etype, MPI_T_enum or MPI_T_ENUM_NULL
|
|
Packit Service |
c5cf8c |
* IN: verb, MPI_T_PVAR_VERBOSITY_*
|
|
Packit Service |
c5cf8c |
* IN: binding, MPI_T_BIND_*
|
|
Packit Service |
c5cf8c |
* IN: Scope, MPI_T_SCOPE_*
|
|
Packit Service |
c5cf8c |
* IN: get_addr, If not NULL, it is a callback to get address of the cvar.
|
|
Packit Service |
c5cf8c |
* IN: get_count, If not NULL, it is a callback to read count of the cvar.
|
|
Packit Service |
c5cf8c |
* IN: cat, Catogery name of the cvar
|
|
Packit Service |
c5cf8c |
* IN: desc, Description of the cvar
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
void MPIR_T_CVAR_REGISTER_impl(MPI_Datatype dtype, const char *name, const void *addr, int count,
|
|
Packit Service |
c5cf8c |
MPIR_T_enum_t * etype, MPIR_T_verbosity_t verb,
|
|
Packit Service |
c5cf8c |
MPIR_T_bind_t binding, MPIR_T_scope_t scope,
|
|
Packit Service |
c5cf8c |
MPIR_T_cvar_get_addr_cb get_addr, MPIR_T_cvar_get_count_cb get_count,
|
|
Packit Service |
c5cf8c |
MPIR_T_cvar_value_t defaultval, const char *cat, const char *desc)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
name2index_hash_t *hash_entry;
|
|
Packit Service |
c5cf8c |
cvar_table_entry_t *cvar;
|
|
Packit Service |
c5cf8c |
int cvar_idx;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Check whether this is a replicated cvar, whose name is unique. */
|
|
Packit Service |
c5cf8c |
HASH_FIND_STR(cvar_hash, name, hash_entry);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (hash_entry != NULL) {
|
|
Packit Service |
c5cf8c |
/* Found it, the cvar already exists */
|
|
Packit Service |
c5cf8c |
cvar_idx = hash_entry->idx;
|
|
Packit Service |
c5cf8c |
cvar = (cvar_table_entry_t *) utarray_eltptr(cvar_table, cvar_idx);
|
|
Packit Service |
c5cf8c |
/* Should never override an existing & active var */
|
|
Packit Service |
c5cf8c |
MPIR_Assert(cvar->active != TRUE);
|
|
Packit Service |
c5cf8c |
cvar->active = TRUE;
|
|
Packit Service |
c5cf8c |
/* FIXME: Do we need to check consistency between the old and new? */
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* Not found, so push the cvar to back of cvar_table */
|
|
Packit Service |
c5cf8c |
utarray_extend_back(cvar_table, MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
cvar = (cvar_table_entry_t *) utarray_back(cvar_table);
|
|
Packit Service |
c5cf8c |
cvar->active = TRUE;
|
|
Packit Service |
c5cf8c |
cvar->datatype = dtype;
|
|
Packit Service |
c5cf8c |
cvar->name = MPL_strdup(name);
|
|
Packit Service |
c5cf8c |
MPIR_Assert(cvar->name);
|
|
Packit Service |
c5cf8c |
if (dtype != MPI_CHAR) {
|
|
Packit Service |
c5cf8c |
cvar->addr = (void *) addr;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
cvar->addr = MPL_malloc(count, MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
MPIR_Assert(cvar->addr);
|
|
Packit Service |
c5cf8c |
if (defaultval.str == NULL) {
|
|
Packit Service |
c5cf8c |
((char *) (cvar->addr))[0] = '\0';
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* Use greater (>), since count includes the terminating '\0', but strlen does not */
|
|
Packit Service |
c5cf8c |
MPIR_Assert((unsigned) count > strlen(defaultval.str));
|
|
Packit Service |
c5cf8c |
strcpy(cvar->addr, defaultval.str);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
cvar->count = count;
|
|
Packit Service |
c5cf8c |
cvar->verbosity = verb;
|
|
Packit Service |
c5cf8c |
cvar->bind = binding;
|
|
Packit Service |
c5cf8c |
cvar->scope = scope;
|
|
Packit Service |
c5cf8c |
cvar->get_addr = get_addr;
|
|
Packit Service |
c5cf8c |
cvar->get_count = get_count;
|
|
Packit Service |
c5cf8c |
cvar->defaultval = defaultval;
|
|
Packit Service |
c5cf8c |
cvar->desc = MPL_strdup(desc);
|
|
Packit Service |
c5cf8c |
MPIR_Assert(cvar->desc);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Record <name, index> in hash table */
|
|
Packit Service |
c5cf8c |
cvar_idx = utarray_len(cvar_table) - 1;
|
|
Packit Service |
c5cf8c |
hash_entry = MPL_malloc(sizeof(name2index_hash_t), MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
MPIR_Assert(hash_entry);
|
|
Packit Service |
c5cf8c |
/* Need not to Strdup name, since cvar_table and cvar_hash co-exist */
|
|
Packit Service |
c5cf8c |
hash_entry->name = name;
|
|
Packit Service |
c5cf8c |
hash_entry->idx = cvar_idx;
|
|
Packit Service |
c5cf8c |
HASH_ADD_KEYPTR(hh, cvar_hash, hash_entry->name,
|
|
Packit Service |
c5cf8c |
strlen(hash_entry->name), hash_entry, MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Add the cvar to a category */
|
|
Packit Service |
c5cf8c |
MPIR_T_cat_add_cvar(cat, cvar_idx);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* A low level, generic and internally used interface to register
|
|
Packit Service |
c5cf8c |
* a pvar to MPIR_T. Other modules should use interfaces defined
|
|
Packit Service |
c5cf8c |
* for concrete pvar classes.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* IN: varclass, MPI_T_PVAR_CLASS_*
|
|
Packit Service |
c5cf8c |
* IN: dtype, MPI datatype for this pvar
|
|
Packit Service |
c5cf8c |
* IN: name, Name of the pvar
|
|
Packit Service |
c5cf8c |
* IN: addr, Pointer to the pvar if known at registeration, otherwise NULL.
|
|
Packit Service |
c5cf8c |
* IN: count, # of elements of this pvar if known at registeration, otherwise 0.
|
|
Packit Service |
c5cf8c |
* IN: etype, MPI_T_enum or MPI_T_ENUM_NULL
|
|
Packit Service |
c5cf8c |
* IN: verb, MPI_T_PVAR_VERBOSITY_*
|
|
Packit Service |
c5cf8c |
* IN: binding, MPI_T_BIND_*
|
|
Packit Service |
c5cf8c |
* IN: flags, Bitwise OR of MPIR_T_R_PVAR_FLAGS_{}
|
|
Packit Service |
c5cf8c |
* IN: get_value, If not NULL, it is a callback to read the pvar.
|
|
Packit Service |
c5cf8c |
* IN: get_count, If not NULL, it is a callback to read count of the pvar.
|
|
Packit Service |
c5cf8c |
* IN: cat, Catogery name of the pvar
|
|
Packit Service |
c5cf8c |
* IN: desc, Description of the pvar
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
void MPIR_T_PVAR_REGISTER_impl(MPIR_T_pvar_class_t varclass, MPI_Datatype dtype, const char *name,
|
|
Packit Service |
c5cf8c |
void *addr, int count, MPIR_T_enum_t * etype,
|
|
Packit Service |
c5cf8c |
MPIR_T_verbosity_t verb, MPIR_T_bind_t binding, int flags,
|
|
Packit Service |
c5cf8c |
MPIR_T_pvar_get_value_cb get_value,
|
|
Packit Service |
c5cf8c |
MPIR_T_pvar_get_count_cb get_count, const char *cat,
|
|
Packit Service |
c5cf8c |
const char *desc)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
name2index_hash_t *hash_entry;
|
|
Packit Service |
c5cf8c |
pvar_table_entry_t *pvar;
|
|
Packit Service |
c5cf8c |
int pvar_idx;
|
|
Packit Service |
c5cf8c |
int seq = varclass - MPIR_T_PVAR_CLASS_FIRST;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Check whether this is a replicated pvar, whose name is unique per class */
|
|
Packit Service |
c5cf8c |
HASH_FIND_STR(pvar_hashs[seq], name, hash_entry);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (hash_entry != NULL) {
|
|
Packit Service |
c5cf8c |
/* Found it, the pvar already exists */
|
|
Packit Service |
c5cf8c |
pvar_idx = hash_entry->idx;
|
|
Packit Service |
c5cf8c |
pvar = (pvar_table_entry_t *) utarray_eltptr(pvar_table, pvar_idx);
|
|
Packit Service |
c5cf8c |
/* Should never override an existing & active var */
|
|
Packit Service |
c5cf8c |
MPIR_Assert(pvar->active != TRUE);
|
|
Packit Service |
c5cf8c |
pvar->active = TRUE;
|
|
Packit Service |
c5cf8c |
/* FIXME: Do we need to check consistency between the old and new? */
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* Not found, so push the pvar to back of pvar_table */
|
|
Packit Service |
c5cf8c |
utarray_extend_back(pvar_table, MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
pvar = (pvar_table_entry_t *) utarray_back(pvar_table);
|
|
Packit Service |
c5cf8c |
pvar->active = TRUE;
|
|
Packit Service |
c5cf8c |
pvar->varclass = varclass;
|
|
Packit Service |
c5cf8c |
pvar->datatype = dtype;
|
|
Packit Service |
c5cf8c |
pvar->name = MPL_strdup(name);
|
|
Packit Service |
c5cf8c |
MPIR_Assert(pvar->name);
|
|
Packit Service |
c5cf8c |
pvar->addr = addr;
|
|
Packit Service |
c5cf8c |
pvar->count = count;
|
|
Packit Service |
c5cf8c |
pvar->enumtype = etype;
|
|
Packit Service |
c5cf8c |
pvar->verbosity = verb;
|
|
Packit Service |
c5cf8c |
pvar->bind = binding;
|
|
Packit Service |
c5cf8c |
pvar->flags = flags;
|
|
Packit Service |
c5cf8c |
pvar->get_value = get_value;
|
|
Packit Service |
c5cf8c |
pvar->get_count = get_count;
|
|
Packit Service |
c5cf8c |
pvar->desc = MPL_strdup(desc);
|
|
Packit Service |
c5cf8c |
MPIR_Assert(pvar->desc);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Record <name, index> in hash table */
|
|
Packit Service |
c5cf8c |
pvar_idx = utarray_len(pvar_table) - 1;
|
|
Packit Service |
c5cf8c |
hash_entry = MPL_malloc(sizeof(name2index_hash_t), MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
MPIR_Assert(hash_entry);
|
|
Packit Service |
c5cf8c |
/* Need not to Strdup name, since pvar_table and pvar_hashs co-exist */
|
|
Packit Service |
c5cf8c |
hash_entry->name = name;
|
|
Packit Service |
c5cf8c |
hash_entry->idx = pvar_idx;
|
|
Packit Service |
c5cf8c |
HASH_ADD_KEYPTR(hh, pvar_hashs[seq], hash_entry->name,
|
|
Packit Service |
c5cf8c |
strlen(hash_entry->name), hash_entry, MPL_MEM_MPIT);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Add the pvar to a category */
|
|
Packit Service |
c5cf8c |
MPIR_T_cat_add_pvar(cat, utarray_len(pvar_table) - 1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Implements an MPI_T-style strncpy. Here is the description from the draft
|
|
Packit Service |
c5cf8c |
* standard:
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* Several MPI tool information interface functions return one or more
|
|
Packit Service |
c5cf8c |
* strings. These functions have two arguments for each string to be returned:
|
|
Packit Service |
c5cf8c |
* an OUT parameter that identifies a pointer to the buffer in which the
|
|
Packit Service |
c5cf8c |
* string will be returned, and an IN/OUT parameter to pass the length of the
|
|
Packit Service |
c5cf8c |
* buffer. The user is responsible for the memory allocation of the buffer and
|
|
Packit Service |
c5cf8c |
* must pass the size of the buffer (n) as the length argument. Let n be the
|
|
Packit Service |
c5cf8c |
* length value specified to the function. On return, the function writes at
|
|
Packit Service |
c5cf8c |
* most n - 1 of the string's characters into the buffer, followed by a null
|
|
Packit Service |
c5cf8c |
* terminator. If the returned string's length is greater than or equal to n,
|
|
Packit Service |
c5cf8c |
* the string will be truncated to n - 1 characters. In this case, the length
|
|
Packit Service |
c5cf8c |
* of the string plus one (for the terminating null character) is returned in
|
|
Packit Service |
c5cf8c |
* the length argument. If the user passes the null pointer as the buffer
|
|
Packit Service |
c5cf8c |
* argument or passes 0 as the length argument, the function does not return
|
|
Packit Service |
c5cf8c |
* the string and only returns the length of the string plus one in the length
|
|
Packit Service |
c5cf8c |
* argument. If the user passes the null pointer as the length argument, the
|
|
Packit Service |
c5cf8c |
* buffer argument is ignored and nothing is returned.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* So this routine copies up to (*len)-1 characters from src to dst and then
|
|
Packit Service |
c5cf8c |
* sets *len to (strlen(dst)+1). If dst==NULL, just return (strlen(src)+1) in
|
|
Packit Service |
c5cf8c |
* *len.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* This routine does not follow MPICH error handling conventions.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
void MPIR_T_strncpy(char *dst, const char *src, int *len)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
/* std. says if len arg is NULL, dst is ignored and nothing is returned (MPI-3, p.563) */
|
|
Packit Service |
c5cf8c |
if (len) {
|
|
Packit Service |
c5cf8c |
/* If dst is NULL or *len is 0, just return src length + 1 */
|
|
Packit Service |
c5cf8c |
if (!dst || !*len) {
|
|
Packit Service |
c5cf8c |
*len = (src == NULL) ? 1 : strlen(src) + 1;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* MPL_strncpy will always terminate the string */
|
|
Packit Service |
c5cf8c |
MPIR_Assert(*len > 0);
|
|
Packit Service |
c5cf8c |
if (src != NULL) {
|
|
Packit Service |
c5cf8c |
MPL_strncpy(dst, src, *len);
|
|
Packit Service |
c5cf8c |
*len = (int) strlen(dst) + 1;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* As if an empty string is copied */
|
|
Packit Service |
c5cf8c |
*dst = '\0';
|
|
Packit Service |
c5cf8c |
*len = 1;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|