1
1

Fixes trac:2767: Recursive locking when ROMIO used with THREAD_MULITPLE

This commit was SVN r24681.

The following Trac tickets were found above:
  Ticket 2767 --> https://svn.open-mpi.org/trac/ompi/ticket/2767
Этот коммит содержится в:
Christopher Yeoh 2011-05-04 06:31:42 +00:00
родитель 34abbce82c
Коммит bab59bda76
18 изменённых файлов: 124 добавлений и 177 удалений

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

@ -255,9 +255,7 @@
(&(((ompi_##type##_t *)object)->attr_##type##_f), \
&f_key, &attr_val, &keyval_obj->extra_state.f_integer, &f_err); \
if (MPI_SUCCESS != OMPI_FINT_2_INT(f_err)) { \
if (need_lock) { \
OPAL_THREAD_UNLOCK(&alock); \
} \
OPAL_THREAD_UNLOCK(&attr_hash_lock); \
return OMPI_FINT_2_INT(f_err); \
} \
} \
@ -268,9 +266,7 @@
(&(((ompi_##type##_t *)object)->attr_##type##_f), \
&f_key, (int*)&attr_val, &keyval_obj->extra_state.f_address, &f_err); \
if (MPI_SUCCESS != OMPI_FINT_2_INT(f_err)) { \
if (need_lock) { \
OPAL_THREAD_UNLOCK(&alock); \
} \
OPAL_THREAD_UNLOCK(&attr_hash_lock); \
return OMPI_FINT_2_INT(f_err); \
} \
} \
@ -282,9 +278,7 @@
((ompi_##type##_t *)object, \
key, attr_val, \
keyval_obj->extra_state.c_ptr)) != MPI_SUCCESS) {\
if (need_lock) { \
OPAL_THREAD_UNLOCK(&alock); \
} \
OPAL_THREAD_UNLOCK(&attr_hash_lock); \
return err;\
} \
}
@ -306,7 +300,7 @@
&f_key, &keyval_obj->extra_state.f_integer, \
&in, &out, &f_flag, &f_err); \
if (MPI_SUCCESS != OMPI_FINT_2_INT(f_err)) { \
OPAL_THREAD_UNLOCK(&alock); \
OPAL_THREAD_UNLOCK(&attr_hash_lock); \
return OMPI_FINT_2_INT(f_err); \
} \
out_attr->av_value = (void*) 0; \
@ -322,7 +316,7 @@
&f_key, &keyval_obj->extra_state.f_address, &in, &out, \
&f_flag, &f_err); \
if (MPI_SUCCESS != OMPI_FINT_2_INT(f_err)) { \
OPAL_THREAD_UNLOCK(&alock); \
OPAL_THREAD_UNLOCK(&attr_hash_lock); \
return OMPI_FINT_2_INT(f_err); \
} \
out_attr->av_value = (void *) out; \
@ -336,7 +330,7 @@
if ((err = (*((keyval_obj->copy_attr_fn).attr_##type##_copy_fn)) \
((ompi_##type##_t *)old_object, key, keyval_obj->extra_state.c_ptr, \
in, &out, &flag, (ompi_##type##_t *)(new_object))) != MPI_SUCCESS) { \
OPAL_THREAD_UNLOCK(&alock); \
OPAL_THREAD_UNLOCK(&attr_hash_lock); \
return err; \
} \
out_attr->av_value = out; \
@ -374,7 +368,7 @@ static void ompi_attribute_keyval_destruct(ompi_attribute_keyval_t *keyval);
static int set_value(ompi_attribute_type_t type, void *object,
opal_hash_table_t **attr_hash, int key,
attribute_value_t *new_attr,
bool predefined, bool need_lock);
bool predefined);
static int get_value(opal_hash_table_t *attr_hash, int key,
attribute_value_t **attribute, int *flag);
static void *translate_to_c(attribute_value_t *val);
@ -409,14 +403,22 @@ static opal_bitmap_t *key_bitmap;
static unsigned int int_pos = 12345;
/*
* Have one lock protect all access to any attribute stuff (keyval
* hash, key bitmap, attribute hashes on MPI objects, etc.).
* Arguably, we would have a finer-grained scheme (e.g., 2 locks) that
* would allow at least *some* concurrency, but these are attributes
* -- they're not in the performance-critical portions of the code.
* So why bother?
* Have one lock protect all access to any attribute hashes on MPI
* objects and one to protect access to any other attribute stuff
* (keyval hash, key bitmap,). We could eventually go for finer
* grained locking, but this will do for now. Originally had only
* one lock, but this can lead to a deadlock if the delete callback
* for an attribute attempts to free a keyval
*
* Notes:
* 1. If you need both locks simultaneously, ALWAYS take
* the keyval_hash_lock lock first.
* 2. You *must* always drop both locks before calling any user defined
* callbacks (ie copy/delete callbacks)
*
*/
static opal_mutex_t alock;
static opal_mutex_t keyval_hash_lock;
static opal_mutex_t attr_hash_lock;
/*
@ -456,7 +458,7 @@ static void
ompi_attribute_keyval_destruct(ompi_attribute_keyval_t *keyval)
{
/* THIS FUNCTION ASSUMES THAT THE CALLER ALREADY HAS OBTAINED THE
alock MUTEX! Remove the keyval entry from the hash and free
keyval_hash_lock MUTEX! Remove the keyval entry from the hash and free
the key. */
if (-1 != keyval->key) {
@ -502,7 +504,8 @@ int ompi_attr_init(void)
}
}
OBJ_CONSTRUCT(&alock, opal_mutex_t);
OBJ_CONSTRUCT(&keyval_hash_lock, opal_mutex_t);
OBJ_CONSTRUCT(&attr_hash_lock, opal_mutex_t);
if (OMPI_SUCCESS != (ret = opal_hash_table_init(keyval_hash,
ATTR_TABLE_SIZE))) {
@ -543,12 +546,6 @@ static int ompi_attr_create_keyval_impl(ompi_attribute_type_t type,
ompi_attribute_keyval_t *keyval;
int ret;
/* Protect against the user calling ompi_attr_destroy and then
calling any of the functions which use it */
if (NULL == keyval_hash) {
return MPI_ERR_INTERN;
}
/* Allocate space for the list item */
keyval = OBJ_NEW(ompi_attribute_keyval_t);
@ -570,7 +567,7 @@ static int ompi_attr_create_keyval_impl(ompi_attribute_type_t type,
/* Create a new unique key and fill the hash */
OPAL_THREAD_LOCK(&alock);
OPAL_THREAD_LOCK(&keyval_hash_lock);
ret = CREATE_KEY(key);
if (OMPI_SUCCESS == ret) {
keyval->key = *key;
@ -578,11 +575,11 @@ static int ompi_attr_create_keyval_impl(ompi_attribute_type_t type,
}
if (OMPI_SUCCESS != ret) {
OBJ_RELEASE(keyval);
OPAL_THREAD_UNLOCK(&alock);
return ret;
} else {
ret = MPI_SUCCESS;
}
OPAL_THREAD_UNLOCK(&alock);
OPAL_THREAD_UNLOCK(&keyval_hash_lock);
return MPI_SUCCESS;
}
@ -640,22 +637,16 @@ int ompi_attr_free_keyval(ompi_attribute_type_t type, int *key,
int ret;
ompi_attribute_keyval_t *keyval;
/* Protect against the user calling ompi_attr_destroy and then
calling any of the functions which use it */
if (NULL == keyval_hash) {
return MPI_ERR_INTERN;
}
/* Find the key-value pair */
OPAL_THREAD_LOCK(&alock);
OPAL_THREAD_LOCK(&keyval_hash_lock);
ret = opal_hash_table_get_value_uint32(keyval_hash, *key,
(void **) &keyval);
if ((OMPI_SUCCESS != ret) || (NULL == keyval) ||
(keyval->attr_type != type) ||
((!predefined) && (keyval->attr_flag & OMPI_KEYVAL_PREDEFINED))) {
OPAL_THREAD_UNLOCK(&alock);
OPAL_THREAD_UNLOCK(&keyval_hash_lock);
return OMPI_ERR_BAD_PARAM;
}
@ -668,7 +659,7 @@ int ompi_attr_free_keyval(ompi_attribute_type_t type, int *key,
the last attribute is deleted, this object gets deleted too */
OBJ_RELEASE(keyval);
OPAL_THREAD_UNLOCK(&alock);
OPAL_THREAD_UNLOCK(&keyval_hash_lock);
return MPI_SUCCESS;
}
@ -676,52 +667,44 @@ int ompi_attr_free_keyval(ompi_attribute_type_t type, int *key,
int ompi_attr_delete(ompi_attribute_type_t type, void *object,
opal_hash_table_t *attr_hash, int key,
bool predefined, bool need_lock)
bool predefined)
{
ompi_attribute_keyval_t *keyval;
int ret = OMPI_SUCCESS, err;
attribute_value_t *attr;
/* Protect against the user calling ompi_attr_destroy and then
calling any of the functions which use it */
if (NULL == keyval_hash) {
return MPI_ERR_INTERN;
}
/* Note that this function can be invoked by
ompi_attr_delete_all() to set attributes on the new object (in
addition to the top-level MPI_* functions that set attributes).
In these cases, ompi_attr_delete_all() has already locked the
keyval_lock, so we should not try to lock it again. */
if (need_lock) {
OPAL_THREAD_LOCK(&alock);
}
/* Check if the key is valid in the master keyval hash */
OPAL_THREAD_LOCK(&keyval_hash_lock);
ret = opal_hash_table_get_value_uint32(keyval_hash, key,
(void **) &keyval);
OPAL_THREAD_UNLOCK(&keyval_hash_lock);
if ((OMPI_SUCCESS != ret) || (NULL == keyval) ||
(keyval->attr_type!= type) ||
((!predefined) && (keyval->attr_flag & OMPI_KEYVAL_PREDEFINED))) {
ret = OMPI_ERR_BAD_PARAM;
goto exit;
return ret;
}
OPAL_THREAD_LOCK(&attr_hash_lock);
/* Ensure that we don't have an empty attr_hash */
if (NULL == attr_hash) {
ret = OMPI_ERR_BAD_PARAM;
goto exit;
OPAL_THREAD_UNLOCK(&attr_hash_lock);
return ret;
}
/* Check if the key is valid for the communicator/window/dtype. If
yes, then delete the attribute and key entry from the object's
hash */
/* Note that this function can be invoked by
ompi_attr_delete_all() to set attributes on the new object (in
addition to the top-level MPI_* functions that set attributes). */
ret = opal_hash_table_get_value_uint32(attr_hash, key, (void**) &attr);
OPAL_THREAD_UNLOCK(&attr_hash_lock);
if (OMPI_SUCCESS == ret) {
switch (type) {
case COMM_ATTR:
@ -742,7 +725,10 @@ int ompi_attr_delete(ompi_attribute_type_t type, void *object,
}
OBJ_RELEASE(attr);
OPAL_THREAD_LOCK(&attr_hash_lock);
ret = opal_hash_table_remove_value_uint32(attr_hash, key);
OPAL_THREAD_UNLOCK(&attr_hash_lock);
if (OMPI_SUCCESS != ret) {
goto exit;
}
@ -757,13 +743,11 @@ int ompi_attr_delete(ompi_attribute_type_t type, void *object,
freed the last attribute that was using the keyval. */
if (OMPI_SUCCESS == ret) {
OPAL_THREAD_LOCK(&keyval_hash_lock);
OBJ_RELEASE(keyval);
OPAL_THREAD_UNLOCK(&keyval_hash_lock);
}
if (need_lock) {
OPAL_THREAD_UNLOCK(&alock);
}
return ret;
}
@ -774,7 +758,7 @@ int ompi_attr_delete(ompi_attribute_type_t type, void *object,
*/
int ompi_attr_set_c(ompi_attribute_type_t type, void *object,
opal_hash_table_t **attr_hash,
int key, void *attribute, bool predefined, bool need_lock)
int key, void *attribute, bool predefined)
{
attribute_value_t *new_attr = OBJ_NEW(attribute_value_t);
if (NULL == new_attr) {
@ -784,7 +768,7 @@ int ompi_attr_set_c(ompi_attribute_type_t type, void *object,
new_attr->av_value = attribute;
new_attr->av_set_from = OMPI_ATTRIBUTE_C;
return set_value(type, object, attr_hash, key, new_attr,
predefined, need_lock);
predefined);
}
@ -795,7 +779,7 @@ int ompi_attr_set_c(ompi_attribute_type_t type, void *object,
int ompi_attr_set_fortran_mpi1(ompi_attribute_type_t type, void *object,
opal_hash_table_t **attr_hash,
int key, MPI_Fint attribute,
bool predefined, bool need_lock)
bool predefined)
{
attribute_value_t *new_attr = OBJ_NEW(attribute_value_t);
if (NULL == new_attr) {
@ -806,7 +790,7 @@ int ompi_attr_set_fortran_mpi1(ompi_attribute_type_t type, void *object,
*new_attr->av_integer_pointer = attribute;
new_attr->av_set_from = OMPI_ATTRIBUTE_FORTRAN_MPI1;
return set_value(type, object, attr_hash, key, new_attr,
predefined, need_lock);
predefined);
}
@ -817,7 +801,7 @@ int ompi_attr_set_fortran_mpi1(ompi_attribute_type_t type, void *object,
int ompi_attr_set_fortran_mpi2(ompi_attribute_type_t type, void *object,
opal_hash_table_t **attr_hash,
int key, MPI_Aint attribute,
bool predefined, bool need_lock)
bool predefined)
{
attribute_value_t *new_attr = OBJ_NEW(attribute_value_t);
if (NULL == new_attr) {
@ -827,7 +811,7 @@ int ompi_attr_set_fortran_mpi2(ompi_attribute_type_t type, void *object,
new_attr->av_value = (void *) attribute;
new_attr->av_set_from = OMPI_ATTRIBUTE_FORTRAN_MPI2;
return set_value(type, object, attr_hash, key, new_attr,
predefined, need_lock);
predefined);
}
@ -903,12 +887,6 @@ int ompi_attr_copy_all(ompi_attribute_type_t type, void *old_object,
attribute_value_t *old_attr, *new_attr;
ompi_attribute_keyval_t *hash_value;
/* Protect against the user calling ompi_attr_destroy and then
calling any of the functions which use it */
if (NULL == keyval_hash) {
return MPI_ERR_INTERN;
}
/* If there's nothing to do, just return */
if (NULL == oldattr_hash) {
@ -916,15 +894,15 @@ int ompi_attr_copy_all(ompi_attribute_type_t type, void *old_object,
}
/* Lock this whole sequence of events -- don't let any other
thread modify the structure of the keyval hash or bitmap while
we're traversing it */
OPAL_THREAD_LOCK(&alock);
thread modify the structure of the attrbitue hash or bitmap
while we're traversing it */
OPAL_THREAD_LOCK(&attr_hash_lock);
/* Get the first attribute in the object's hash */
ret = opal_hash_table_get_first_key_uint32(oldattr_hash, &key,
(void **) &old_attr,
&node);
OPAL_THREAD_UNLOCK(&attr_hash_lock);
/* While we still have some attribute in the object's key hash */
while (OMPI_SUCCESS == ret) {
@ -933,8 +911,10 @@ int ompi_attr_copy_all(ompi_attribute_type_t type, void *old_object,
/* Get the keyval in the main keyval hash - so that we know
what the copy_attr_fn is */
OPAL_THREAD_LOCK(&keyval_hash_lock);
err = opal_hash_table_get_value_uint32(keyval_hash, key,
(void **) &hash_value);
OPAL_THREAD_UNLOCK(&keyval_hash_lock);
new_attr = OBJ_NEW(attribute_value_t);
switch (type) {
@ -977,19 +957,21 @@ int ompi_attr_copy_all(ompi_attribute_type_t type, void *old_object,
new_attr->av_set_from = OMPI_ATTRIBUTE_C;
}
set_value(type, new_object, &newattr_hash, key,
new_attr, true, false);
new_attr, true);
} else {
OBJ_RELEASE(new_attr);
}
OPAL_THREAD_LOCK(&attr_hash_lock);
ret = opal_hash_table_get_next_key_uint32(oldattr_hash, &key,
(void **) &old_attr,
in_node, &node);
OPAL_THREAD_UNLOCK(&attr_hash_lock);
}
/* All done */
OPAL_THREAD_UNLOCK(&alock);
return MPI_SUCCESS;
}
@ -1004,12 +986,6 @@ int ompi_attr_delete_all(ompi_attribute_type_t type, void *object,
uint32_t key, oldkey;
void *node, *in_node, *old_attr;
/* Protect against the user calling ompi_attr_destroy and then
calling any of the functions which use it */
if (NULL == keyval_hash) {
return MPI_ERR_INTERN;
}
/* Ensure that the table is not empty */
if (NULL == attr_hash) {
@ -1017,15 +993,16 @@ int ompi_attr_delete_all(ompi_attribute_type_t type, void *object,
}
/* Lock this whole sequence of events -- don't let any other
thread modify the structure of the keyval hash or bitmap while
we're traversing it */
OPAL_THREAD_LOCK(&alock);
thread modify the structure of the attribute hash or bitmap
while we're traversing it */
OPAL_THREAD_LOCK(&attr_hash_lock);
/* Get the first key in local object's hash */
key_ret = opal_hash_table_get_first_key_uint32(attr_hash,
&key, &old_attr,
&node);
OPAL_THREAD_UNLOCK(&attr_hash_lock);
del_ret = OMPI_SUCCESS;
while (OMPI_SUCCESS == key_ret && OMPI_SUCCESS == del_ret) {
@ -1037,17 +1014,19 @@ int ompi_attr_delete_all(ompi_attribute_type_t type, void *object,
/* Move to the next node */
OPAL_THREAD_LOCK(&attr_hash_lock);
key_ret = opal_hash_table_get_next_key_uint32(attr_hash,
&key, &old_attr,
in_node, &node);
OPAL_THREAD_UNLOCK(&attr_hash_lock);
/* Now delete this attribute */
del_ret = ompi_attr_delete(type, object, attr_hash, oldkey, true, false);
del_ret = ompi_attr_delete(type, object, attr_hash, oldkey, true);
}
/* All done */
OPAL_THREAD_UNLOCK(&alock);
return del_ret;
}
@ -1059,47 +1038,32 @@ int ompi_attr_delete_all(ompi_attribute_type_t type, void *object,
static int set_value(ompi_attribute_type_t type, void *object,
opal_hash_table_t **attr_hash, int key,
attribute_value_t *new_attr,
bool predefined, bool need_lock)
bool predefined)
{
ompi_attribute_keyval_t *keyval;
int ret, err;
attribute_value_t *old_attr;
bool had_old = false;
/* Protect against the user calling ompi_attr_destroy and then
calling any of the functions which use it */
if (NULL == keyval_hash) {
return MPI_ERR_INTERN;
}
if (NULL == attr_hash) {
return MPI_ERR_INTERN;
}
/* Note that this function can be invoked by ompi_attr_copy_all()
to set attributes on the new object (in addition to the
top-level MPI_* functions that set attributes). In these
cases, ompi_attr_copy_all() has already locked the keyval_lock,
so we should not try to lock it again. */
top-level MPI_* functions that set attributes). */
if (need_lock) {
OPAL_THREAD_LOCK(&alock);
}
OPAL_THREAD_LOCK(&keyval_hash_lock);
ret = opal_hash_table_get_value_uint32(keyval_hash, key,
(void **) &keyval);
OPAL_THREAD_UNLOCK(&keyval_hash_lock);
/* If key not found */
if ((OMPI_SUCCESS != ret ) || (NULL == keyval) ||
(keyval->attr_type != type) ||
((!predefined) && (keyval->attr_flag & OMPI_KEYVAL_PREDEFINED))) {
if (need_lock) {
OPAL_THREAD_UNLOCK(&alock);
}
return OMPI_ERR_BAD_PARAM;
}
/* Do we need to make a new attr_hash? */
OPAL_THREAD_LOCK(&attr_hash_lock);
if (NULL == *attr_hash) {
ompi_attr_hash_init(attr_hash);
}
@ -1108,6 +1072,8 @@ static int set_value(ompi_attribute_type_t type, void *object,
on the old keyval. If so, delete the old attribute value. */
ret = opal_hash_table_get_value_uint32(*attr_hash, key, (void**) &old_attr);
OPAL_THREAD_UNLOCK(&attr_hash_lock);
if (OMPI_SUCCESS == ret) {
switch (type) {
case COMM_ATTR:
@ -1123,16 +1089,28 @@ static int set_value(ompi_attribute_type_t type, void *object,
break;
default:
if (need_lock) {
OPAL_THREAD_UNLOCK(&alock);
}
return MPI_ERR_INTERN;
}
had_old = true;
OBJ_RELEASE(old_attr);
}
OPAL_THREAD_LOCK(&keyval_hash_lock);
ret = opal_hash_table_get_value_uint32(keyval_hash, key,
(void **) &keyval);
if ((OMPI_SUCCESS != ret ) || (NULL == keyval)) {
/* Keyval has disappeared underneath us. Someone must have
called ompi_attr_free_keyval since we last looked it up
in the hash. We'll behave as if we never found it in the
first place */
OPAL_THREAD_UNLOCK(&keyval_hash_lock);
return OMPI_ERR_BAD_PARAM;
}
OPAL_THREAD_LOCK(&attr_hash_lock);
ret = opal_hash_table_set_value_uint32(*attr_hash, key, new_attr);
OPAL_THREAD_UNLOCK(&attr_hash_lock);
OPAL_THREAD_UNLOCK(&keyval_hash_lock);
/* Increase the reference count of the object, only if there was no
old atribute/no old entry in the object's key hash */
@ -1141,11 +1119,6 @@ static int set_value(ompi_attribute_type_t type, void *object,
OBJ_RETAIN(keyval);
}
/* Release the lock if we grabbed it */
if (need_lock) {
OPAL_THREAD_UNLOCK(&alock);
}
if (OMPI_SUCCESS != ret) {
return ret;
}
@ -1174,25 +1147,26 @@ static int get_value(opal_hash_table_t *attr_hash, int key,
flag argument */
*flag = 0;
OPAL_THREAD_LOCK(&alock);
OPAL_THREAD_LOCK(&keyval_hash_lock);
ret = opal_hash_table_get_value_uint32(keyval_hash, key,
(void**) &keyval);
OPAL_THREAD_UNLOCK(&keyval_hash_lock);
if (OMPI_ERR_NOT_FOUND == OPAL_SOS_GET_ERROR_CODE(ret)) {
OPAL_THREAD_UNLOCK(&alock);
return MPI_KEYVAL_INVALID;
}
/* If we have a null attr_hash table, that means that nothing has
been cached on this object yet. So just return *flag = 0. */
OPAL_THREAD_LOCK(&attr_hash_lock);
if (NULL == attr_hash) {
OPAL_THREAD_UNLOCK(&alock);
OPAL_THREAD_UNLOCK(&attr_hash_lock);
return OMPI_SUCCESS;
}
ret = opal_hash_table_get_value_uint32(attr_hash, key, &attr);
OPAL_THREAD_UNLOCK(&alock);
OPAL_THREAD_UNLOCK(&attr_hash_lock);
if (OMPI_SUCCESS == ret) {
*attribute = (attribute_value_t*)attr;
*flag = 1;

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

@ -292,18 +292,11 @@ int ompi_attr_free_keyval(ompi_attribute_type_t type, int *key,
* @param key Key val for the attribute (IN)
* @param attribute The actual attribute pointer (IN)
* @param predefined Whether the key is predefined or not 0/1 (IN)
* @param need_lock Whether we need to need to lock the keyval_lock or not
* @return OMPI error code
*
* If (*attr_hash) == NULL, a new hash will be created and
* initialized.
*
* Note that need_lock should *always* be true when this function is
* invoked from an top-level MPI function. It is only false when this
* function is invoked internally (i.e., when we already hold the
* relevant locks, and we don't want to try to lock them again,
* recursively).
*
* All three of these functions (ompi_attr_set_c(),
* ompi_attr_set_fortran_mpi1(), and ompi_attr_set_fortran_mpi2())
* could have been combined into one function that took some kind of
@ -317,7 +310,7 @@ int ompi_attr_free_keyval(ompi_attribute_type_t type, int *key,
*/
int ompi_attr_set_c(ompi_attribute_type_t type, void *object,
opal_hash_table_t **attr_hash,
int key, void *attribute, bool predefined, bool need_lock);
int key, void *attribute, bool predefined);
/**
* Set an attribute on the comm/win/datatype in a form valid for
@ -329,18 +322,11 @@ int ompi_attr_set_c(ompi_attribute_type_t type, void *object,
* @param key Key val for the attribute (IN)
* @param attribute The actual attribute pointer (IN)
* @param predefined Whether the key is predefined or not 0/1 (IN)
* @param need_lock Whether we need to need to lock the keyval_lock or not
* @return OMPI error code
*
* If (*attr_hash) == NULL, a new hash will be created and
* initialized.
*
* Note that need_lock should *always* be true when this function is
* invoked from an top-level MPI function. It is only false when this
* function is invoked internally (i.e., when we already hold the
* relevant locks, and we don't want to try to lock them again,
* recursively).
*
* All three of these functions (ompi_attr_set_c(),
* ompi_attr_set_fortran_mpi1(), and ompi_attr_set_fortran_mpi2())
* could have been combined into one function that took some kind of
@ -355,7 +341,7 @@ int ompi_attr_set_c(ompi_attribute_type_t type, void *object,
OMPI_DECLSPEC int ompi_attr_set_fortran_mpi1(ompi_attribute_type_t type, void *object,
opal_hash_table_t **attr_hash,
int key, MPI_Fint attribute,
bool predefined, bool need_lock);
bool predefined);
/**
* Set an attribute on the comm/win/datatype in a form valid for
@ -367,18 +353,11 @@ OMPI_DECLSPEC int ompi_attr_set_fortran_mpi1(ompi_attribute_type_t type, void *o
* @param key Key val for the attribute (IN)
* @param attribute The actual attribute pointer (IN)
* @param predefined Whether the key is predefined or not 0/1 (IN)
* @param need_lock Whether we need to need to lock the keyval_lock or not
* @return OMPI error code
*
* If (*attr_hash) == NULL, a new hash will be created and
* initialized.
*
* Note that need_lock should *always* be true when this function is
* invoked from an top-level MPI function. It is only false when this
* function is invoked internally (i.e., when we already hold the
* relevant locks, and we don't want to try to lock them again,
* recursively).
*
* All three of these functions (ompi_attr_set_c(),
* ompi_attr_set_fortran_mpi1(), and ompi_attr_set_fortran_mpi2())
* could have been combined into one function that took some kind of
@ -393,7 +372,7 @@ OMPI_DECLSPEC int ompi_attr_set_fortran_mpi1(ompi_attribute_type_t type, void *o
OMPI_DECLSPEC int ompi_attr_set_fortran_mpi2(ompi_attribute_type_t type, void *object,
opal_hash_table_t **attr_hash,
int key, MPI_Aint attribute,
bool predefined, bool need_lock);
bool predefined);
/**
* Get an attribute on the comm/win/datatype in a form valid for C.
@ -482,19 +461,13 @@ OMPI_DECLSPEC int ompi_attr_get_fortran_mpi2(opal_hash_table_t *attr_hash, int k
* @param attr_hash The attribute hash table hanging on the object(IN)
* @param key Key val for the attribute (IN)
* @param predefined Whether the key is predefined or not 0/1 (IN)
* @param need_lock Whether we need to need to lock the keyval_lock or not
* @return OMPI error code
*
* Note that need_lock should *always* be true when this function is
* invoked from an top-level MPI function. It is only false when this
* function is invoked internally (i.e., when we already hold the
* relevant locks, and we don't want to try to lock them again,
* recursively).
*/
int ompi_attr_delete(ompi_attribute_type_t type, void *object,
opal_hash_table_t *attr_hash , int key,
bool predefined, bool need_lock);
bool predefined);
/**

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

@ -272,5 +272,5 @@ static int set_f(int keyval, MPI_Fint value)
return ompi_attr_set_fortran_mpi1(COMM_ATTR, MPI_COMM_WORLD,
&MPI_COMM_WORLD->c_keyhash,
keyval, value,
true, true);
true);
}

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

@ -70,7 +70,7 @@ int MPI_Add_error_class(int *errorclass)
&MPI_COMM_WORLD->c_keyhash,
MPI_LASTUSEDCODE,
ompi_mpi_errcode_lastused,
true, true);
true);
if ( MPI_SUCCESS != rc ) {
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, rc, FUNC_NAME);
}

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

@ -77,7 +77,7 @@ int MPI_Add_error_code(int errorclass, int *errorcode)
&MPI_COMM_WORLD->c_keyhash,
MPI_LASTUSEDCODE,
ompi_mpi_errcode_lastused,
true, true);
true);
if ( MPI_SUCCESS != rc ) {
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, rc, FUNC_NAME);
}

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

@ -57,7 +57,7 @@ int MPI_Attr_delete(MPI_Comm comm, int keyval)
OPAL_CR_ENTER_LIBRARY();
ret = ompi_attr_delete(COMM_ATTR, comm, comm->c_keyhash, keyval,
false, true);
false);
OMPI_ERRHANDLER_RETURN(ret, comm, MPI_ERR_OTHER, FUNC_NAME);
}

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

@ -56,7 +56,7 @@ int MPI_Attr_put(MPI_Comm comm, int keyval, void *attribute_val)
OPAL_CR_ENTER_LIBRARY();
ret = ompi_attr_set_c(COMM_ATTR, comm, &comm->c_keyhash,
keyval, attribute_val, false, true);
keyval, attribute_val, false);
OMPI_ERRHANDLER_RETURN(ret, comm, MPI_ERR_OTHER, FUNC_NAME);
}

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

@ -56,7 +56,7 @@ int MPI_Comm_delete_attr(MPI_Comm comm, int comm_keyval)
OPAL_CR_ENTER_LIBRARY();
ret = ompi_attr_delete(COMM_ATTR, comm, comm->c_keyhash, comm_keyval,
false, true);
false);
OMPI_ERRHANDLER_RETURN(ret, comm, MPI_ERR_OTHER, FUNC_NAME);
}

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

@ -56,6 +56,6 @@ int MPI_Comm_set_attr(MPI_Comm comm, int comm_keyval, void *attribute_val)
OPAL_CR_ENTER_LIBRARY();
ret = ompi_attr_set_c(COMM_ATTR, comm, &comm->c_keyhash,
comm_keyval, attribute_val, false, true);
comm_keyval, attribute_val, false);
OMPI_ERRHANDLER_RETURN(ret, comm, MPI_ERR_OTHER, FUNC_NAME);
}

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

@ -57,7 +57,7 @@ int MPI_Type_delete_attr (MPI_Datatype type, int type_keyval)
OPAL_CR_ENTER_LIBRARY();
ret = ompi_attr_delete(TYPE_ATTR, type, type->d_keyhash, type_keyval,
false, true);
false);
OMPI_ERRHANDLER_RETURN(ret, MPI_COMM_WORLD,
MPI_ERR_OTHER, FUNC_NAME);
}

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

@ -59,7 +59,7 @@ int MPI_Type_set_attr (MPI_Datatype type,
OPAL_CR_ENTER_LIBRARY();
ret = ompi_attr_set_c(TYPE_ATTR, type, &type->d_keyhash,
type_keyval, attribute_val, false, true);
type_keyval, attribute_val, false);
OMPI_ERRHANDLER_RETURN(ret, MPI_COMM_WORLD,
MPI_ERR_OTHER, FUNC_NAME);

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

@ -51,6 +51,6 @@ int MPI_Win_delete_attr(MPI_Win win, int win_keyval)
OPAL_CR_ENTER_LIBRARY();
ret = ompi_attr_delete(WIN_ATTR, win, win->w_keyhash, win_keyval,
false, true);
false);
OMPI_ERRHANDLER_RETURN(ret, win, MPI_ERR_OTHER, FUNC_NAME);
}

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

@ -51,6 +51,6 @@ int MPI_Win_set_attr(MPI_Win win, int win_keyval, void *attribute_val)
OPAL_CR_ENTER_LIBRARY();
ret = ompi_attr_set_c(WIN_ATTR, win, &win->w_keyhash,
win_keyval, attribute_val, false, true);
win_keyval, attribute_val, false);
OMPI_ERRHANDLER_RETURN(ret, win, MPI_ERR_OTHER, FUNC_NAME);
}

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

@ -73,6 +73,6 @@ void mpi_attr_put_f(MPI_Fint *comm, MPI_Fint *keyval, MPI_Fint *attribute_val,
&c_comm->c_keyhash,
OMPI_FINT_2_INT(*keyval),
*attribute_val,
false, true);
false);
*ierr = OMPI_INT_2_FINT(c_err);
}

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

@ -73,6 +73,6 @@ void mpi_comm_set_attr_f(MPI_Fint *comm, MPI_Fint *comm_keyval,
&c_comm->c_keyhash,
OMPI_FINT_2_INT(*comm_keyval),
*attribute_val,
false, true);
false);
*ierr = OMPI_INT_2_FINT(c_err);
}

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

@ -72,6 +72,6 @@ void mpi_type_set_attr_f(MPI_Fint *type, MPI_Fint *type_keyval, MPI_Aint *attrib
&c_type->d_keyhash,
OMPI_FINT_2_INT(*type_keyval),
*attribute_val,
false, true);
false);
*ierr = OMPI_INT_2_FINT(c_err);
}

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

@ -74,6 +74,6 @@ void mpi_win_set_attr_f(MPI_Fint *win, MPI_Fint *win_keyval,
&c_win->w_keyhash,
OMPI_FINT_2_INT(*win_keyval),
*attribute_val,
false, true);
false);
*ierr = OMPI_INT_2_FINT(c_err);
}

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

@ -103,14 +103,14 @@ ompi_win_create(void *base, size_t size,
/* Fill in required attributes */
ret = ompi_attr_set_c(WIN_ATTR, win, &win->w_keyhash,
MPI_WIN_BASE, win->w_baseptr, true, true);
MPI_WIN_BASE, win->w_baseptr, true);
if (OMPI_SUCCESS != ret) {
OBJ_RELEASE(win);
return ret;
}
ret = ompi_attr_set_fortran_mpi2(WIN_ATTR, win,
&win->w_keyhash,
MPI_WIN_SIZE, win->w_size, true, true);
MPI_WIN_SIZE, win->w_size, true);
if (OMPI_SUCCESS != ret) {
OBJ_RELEASE(win);
return ret;
@ -118,7 +118,7 @@ ompi_win_create(void *base, size_t size,
ret = ompi_attr_set_fortran_mpi2(WIN_ATTR, win,
&win->w_keyhash,
MPI_WIN_DISP_UNIT, win->w_disp_unit,
true, true);
true);
if (OMPI_SUCCESS != ret) {
OBJ_RELEASE(win);
return ret;