Prevent deadlocks on recursive calls (deleting communicators with
attributes from an attribute callback).
Этот коммит содержится в:
родитель
2581b41d08
Коммит
4d55ae838d
@ -2,7 +2,7 @@
|
|||||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||||
* University Research and Technology
|
* University Research and Technology
|
||||||
* Corporation. All rights reserved.
|
* Corporation. All rights reserved.
|
||||||
* Copyright (c) 2004-2013 The University of Tennessee and The University
|
* Copyright (c) 2004-2014 The University of Tennessee and The University
|
||||||
* of Tennessee Research Foundation. All rights
|
* of Tennessee Research Foundation. All rights
|
||||||
* reserved.
|
* reserved.
|
||||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||||
@ -247,6 +247,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define DELETE_ATTR_CALLBACKS(type, attribute, keyval_obj, object, err) \
|
#define DELETE_ATTR_CALLBACKS(type, attribute, keyval_obj, object, err) \
|
||||||
|
do { \
|
||||||
|
OPAL_THREAD_UNLOCK(&attribute_lock); \
|
||||||
if (0 != (keyval_obj->attr_flag & OMPI_KEYVAL_F77)) { \
|
if (0 != (keyval_obj->attr_flag & OMPI_KEYVAL_F77)) { \
|
||||||
MPI_Fint f_key = OMPI_INT_2_FINT(key); \
|
MPI_Fint f_key = OMPI_INT_2_FINT(key); \
|
||||||
MPI_Fint f_err; \
|
MPI_Fint f_err; \
|
||||||
@ -278,12 +280,16 @@
|
|||||||
((ompi_##type##_t *)object, \
|
((ompi_##type##_t *)object, \
|
||||||
key, attr_val, \
|
key, attr_val, \
|
||||||
keyval_obj->extra_state.c_ptr); \
|
keyval_obj->extra_state.c_ptr); \
|
||||||
}
|
} \
|
||||||
|
OPAL_THREAD_LOCK(&attribute_lock); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/* See the big, long comment above from DELETE_ATTR_CALLBACKS -- most of
|
/* See the big, long comment above from DELETE_ATTR_CALLBACKS -- most of
|
||||||
that text applies here, too. */
|
that text applies here, too. */
|
||||||
|
|
||||||
#define COPY_ATTR_CALLBACKS(type, old_object, keyval_obj, in_attr, new_object, out_attr, err) \
|
#define COPY_ATTR_CALLBACKS(type, old_object, keyval_obj, in_attr, new_object, out_attr, err) \
|
||||||
|
do { \
|
||||||
|
OPAL_THREAD_UNLOCK(&attribute_lock); \
|
||||||
if (0 != (keyval_obj->attr_flag & OMPI_KEYVAL_F77)) { \
|
if (0 != (keyval_obj->attr_flag & OMPI_KEYVAL_F77)) { \
|
||||||
MPI_Fint f_key = OMPI_INT_2_FINT(key); \
|
MPI_Fint f_key = OMPI_INT_2_FINT(key); \
|
||||||
MPI_Fint f_err; \
|
MPI_Fint f_err; \
|
||||||
@ -329,7 +335,9 @@
|
|||||||
in, &out, &flag, (ompi_##type##_t *)(new_object))) == MPI_SUCCESS) { \
|
in, &out, &flag, (ompi_##type##_t *)(new_object))) == MPI_SUCCESS) { \
|
||||||
out_attr->av_value = out; \
|
out_attr->av_value = out; \
|
||||||
} \
|
} \
|
||||||
}
|
} \
|
||||||
|
OPAL_THREAD_LOCK(&attribute_lock); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -402,12 +410,9 @@ static int attr_sequence;
|
|||||||
static unsigned int int_pos = 12345;
|
static unsigned int int_pos = 12345;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We used to have multiple locks for semi-fine-grained locking. But
|
* MPI attributes are *not* high performance, so just use a One Big Lock
|
||||||
* the code got complex, and we had to spend time looking for subtle
|
* approach. However, this lock is released before a user provided callback is
|
||||||
* bugs. Craziness -- MPI attributes are *not* high performance, so
|
* triggered and acquired right after, allowing for recursive behaviors.
|
||||||
* just use a One Big Lock approach: there is *no* concurrent access.
|
|
||||||
* If you have the lock, you can do whatever you want and no data will
|
|
||||||
* change/disapear from underneath you.
|
|
||||||
*/
|
*/
|
||||||
static opal_mutex_t attribute_lock;
|
static opal_mutex_t attribute_lock;
|
||||||
|
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user