[mpich2-commits] r5499 - in mpich2/trunk/src: include mpi/comm mpi/errhan mpi/group mpi/pt2pt mpi/spawn mpid/ch3/channels/nemesis/nemesis/netmod/mx mpid/ch3/channels/nemesis/nemesis/src mpid/ch3/channels/sctp/src mpid/ch3/include mpid/ch3/src mpid/common/datatype util/mem
goodell at mcs.anl.gov
goodell at mcs.anl.gov
Tue Oct 20 15:35:30 CDT 2009
Author: goodell
Date: 2009-10-20 15:35:30 -0500 (Tue, 20 Oct 2009)
New Revision: 5499
Modified:
mpich2/trunk/src/include/mpiatomic.h
mpich2/trunk/src/include/mpihandlemem.h
mpich2/trunk/src/include/mpiimpl.h
mpich2/trunk/src/mpi/comm/commutil.c
mpich2/trunk/src/mpi/errhan/errutil.c
mpich2/trunk/src/mpi/group/grouputil.c
mpich2/trunk/src/mpi/pt2pt/bsendutil.c
mpich2/trunk/src/mpi/pt2pt/ibsend.c
mpich2/trunk/src/mpi/spawn/comm_disconnect.c
mpich2/trunk/src/mpid/ch3/channels/nemesis/nemesis/netmod/mx/mx_impl.h
mpich2/trunk/src/mpid/ch3/channels/nemesis/nemesis/src/mpid_nem_debug.c
mpich2/trunk/src/mpid/ch3/channels/sctp/src/ch3_progress.c
mpich2/trunk/src/mpid/ch3/include/mpidimpl.h
mpich2/trunk/src/mpid/ch3/src/ch3u_handle_connection.c
mpich2/trunk/src/mpid/ch3/src/ch3u_port.c
mpich2/trunk/src/mpid/ch3/src/ch3u_request.c
mpich2/trunk/src/mpid/ch3/src/mpid_vc.c
mpich2/trunk/src/mpid/ch3/src/mpidi_pg.c
mpich2/trunk/src/mpid/common/datatype/mpid_datatype.h
mpich2/trunk/src/util/mem/handlemem.c
Log:
Make lock-free reference counting work again.
There were several layers of brokenness that prevented lock-free
reference counting from occurring. Some of this code has been brought
over from the threads development branch, but most of it is new. This
code still contains many questionable uses of the reference count
variables that need to be investigated and fixed (search for FIXME-MT).
No reviewer.
Modified: mpich2/trunk/src/include/mpiatomic.h
===================================================================
--- mpich2/trunk/src/include/mpiatomic.h 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/include/mpiatomic.h 2009-10-20 20:35:30 UTC (rev 5499)
@@ -41,65 +41,6 @@
*/
/* ======================================================
- reference counting routines
- ====================================================== */
-
-/* Atomically increment a reference count */
-#undef FUNCNAME
-#define FUNCNAME MPIDU_Ref_add
-#undef FCNAME
-#define FCNAME MPIDI_QUOTE(FUNCNAME)
-static inline void MPIDU_Ref_add(OPA_int_t *ptr)
-{
- MPIDI_STATE_DECL(MPID_STATE_MPIDU_REF_ADD);
-
- MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_REF_ADD);
- OPA_incr_int(ptr);
- MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_REF_ADD);
-}
-
-/* Atomically decrement a reference count and test if the result is equal to
- zero. Returns true if this was the final reference released. */
-#undef FUNCNAME
-#define FUNCNAME MPIDU_Ref_release_and_test
-#undef FCNAME
-#define FCNAME MPIDI_QUOTE(FUNCNAME)
-static inline int MPIDU_Ref_release_and_test(OPA_int_t *ptr)
-{
- int retval;
- MPIDI_STATE_DECL(MPID_STATE_MPIDU_REF_RELEASE_AND_TEST);
-
- MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_REF_RELEASE_AND_TEST);
-
-#if defined(ATOMIC_DECR_AND_TEST_IS_EMULATED) && !defined(ATOMIC_FETCH_AND_DECR_IS_EMULATED)
- {
- int prev;
- prev = OPA_fetch_and_decr_int(ptr);
- retval = (1 == prev);
- goto fn_exit;
- }
-#elif defined(ATOMIC_DECR_AND_TEST_IS_EMULATED) && !defined(ATOMIC_CAS_INT_IS_EMULATED)
- {
- int oldv, newv;
- do {
- oldv = OPA_load_int(ptr);
- newv = oldv - 1;
- } while (oldv != OPA_cas_int(ptr, oldv, newv));
- retval = (0 == newv);
- goto fn_exit;
- }
-#else
- retval = OPA_decr_and_test_int(ptr);
- goto fn_exit;
-#endif
-
-fn_exit:
- MPIU_Assert(OPA_load_int(ptr) >= 0); /* help find add/release mismatches */
- MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_REF_RELEASE_AND_TEST);
- return retval;
-}
-
-/* ======================================================
Ownership Mechanisms
======================================================
@@ -167,7 +108,7 @@
MPIU_DBG_MSG_D(ALL, VERBOSE, "... my_id=%d", my_id);
MPIU_DBG_MSG_P(ALL, VERBOSE, "... &info->id=%p", &info->id);
- prev_id = OPA_cas_int_int(&info->id, MPIDU_OWNER_ID_NONE, my_id);
+ prev_id = OPA_cas_int(&info->id, MPIDU_OWNER_ID_NONE, my_id);
if (after_owner) *after_owner = my_id;
if (my_id == prev_id) {
Modified: mpich2/trunk/src/include/mpihandlemem.h
===================================================================
--- mpich2/trunk/src/include/mpihandlemem.h 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/include/mpihandlemem.h 2009-10-20 20:35:30 UTC (rev 5499)
@@ -75,6 +75,9 @@
#define HANDLE_MPI_KIND_SHIFT 26
#define HANDLE_GET_MPI_KIND(a) ( ((a)&0x3c000000) >> HANDLE_MPI_KIND_SHIFT )
+/* returns the name of the handle kind for debugging/logging purposes */
+const char *MPIU_Handle_get_kind_str(int kind);
+
/* Handle types. These are really 2 bits */
#define HANDLE_KIND_INVALID 0x0
#define HANDLE_KIND_BUILTIN 0x1
@@ -101,24 +104,207 @@
#define HANDLE_MASK 0x03FFFFFF
#define HANDLE_INDEX(a) ((a)& HANDLE_MASK)
+/* ------------------------------------------------------------------------- */
+/* reference counting macros */
+
+/* If we're debugging the handles (including reference counts),
+ add an additional test. The check on a max refcount helps to
+ detect objects whose refcounts are not decremented as many times
+ as they are incremented */
+#ifdef MPICH_DEBUG_HANDLES
+#define MPICH_DEBUG_MAX_REFCOUNT 64
+#define MPIU_HANDLE_CHECK_REFCOUNT(objptr_,op_) \
+ do { \
+ int local_ref_count_ = MPIU_Object_get_ref(objptr_); \
+ if (local_ref_count_ > MPICH_DEBUG_MAX_REFCOUNT || local_ref_count_ < 0) \
+ { \
+ MPIU_DBG_MSG_FMT(HANDLE,TYPICAL,(MPIU_DBG_FDEST, \
+ "Invalid refcount (%d) in %p (0x%08x) %s", \
+ local_ref_count_, (objptr_), (objptr_)->handle, op_)); \
+ } \
+ MPIU_Assert(local_ref_count_ < 0); \
+ } while (0)
+#else
+#define MPIU_HANDLE_CHECK_REFCOUNT(objptr_,op_) \
+ MPIU_Assert(MPIU_Object_get_ref(objptr_) >= 0)
+#endif
+
+#define MPIU_HANDLE_LOG_REFCOUNT_CHANGE(objptr_, action_str_) \
+ MPIU_DBG_MSG_FMT(HANDLE,TYPICAL,(MPIU_DBG_FDEST, \
+ "%s %p (0x%08x kind=%s) refcount to %d", \
+ (action_str_), \
+ (objptr_), \
+ (objptr_)->handle, \
+ MPIU_Handle_get_kind_str(HANDLE_GET_MPI_KIND((objptr_)->handle)), \
+ MPIU_Object_get_ref(objptr_)))
+
+
+/*M
+ MPIU_Object_add_ref - Increment the reference count for an MPI object
+
+ Synopsis:
+.vb
+ MPIU_Object_add_ref( MPIU_Object *ptr )
+.ve
+
+ Input Parameter:
+. ptr - Pointer to the object.
+
+ Notes:
+ In an unthreaded implementation, this function will usually be implemented
+ as a single-statement macro. In an 'MPI_THREAD_MULTIPLE' implementation,
+ this routine must implement an atomic increment operation, using, for
+ example, a lock on datatypes or special assembly code.
+M*/
+/*M
+ MPIU_Object_release_ref - Decrement the reference count for an MPI object
+
+ Synopsis:
+.vb
+ MPIU_Object_release_ref( MPIU_Object *ptr, int *inuse_ptr )
+.ve
+
+ Input Parameter:
+. objptr - Pointer to the object.
+
+ Output Parameter:
+. inuse_ptr - Pointer to the value of the reference count after decrementing.
+ This value is either zero or non-zero. See below for details.
+
+ Notes:
+ In an unthreaded implementation, this function will usually be implemented
+ as a single-statement macro. In an 'MPI_THREAD_MULTIPLE' implementation,
+ this routine must implement an atomic decrement operation, using, for
+ example, a lock on datatypes or special assembly code.
+
+ Once the reference count is decremented to zero, it is an error to
+ change it. A correct MPI program will never do that, but an incorrect one
+ (particularly a multithreaded program with a race condition) might.
+
+ The following code is `invalid`\:
+.vb
+ MPIU_Object_release_ref( datatype_ptr );
+ if (datatype_ptr->ref_count == 0) MPID_Datatype_free( datatype_ptr );
+.ve
+ In a multi-threaded implementation, the value of 'datatype_ptr->ref_count'
+ may have been changed by another thread, resulting in both threads calling
+ 'MPID_Datatype_free'. Instead, use
+.vb
+ MPIU_Object_release_ref( datatype_ptr, &inUse );
+ if (!inuse)
+ MPID_Datatype_free( datatype_ptr );
+.ve
+ M*/
+
+/* The MPIU_DBG... statements are macros that vanish unless
+ --enable-g=log is selected. MPIU_HANDLE_CHECK_REFCOUNT is
+ defined above, and adds an additional sanity check for the refcounts
+*/
+#if MPIU_THREAD_REFCOUNT == MPIU_REFCOUNT_NONE || \
+ MPIU_THREAD_REFCOUNT == MPIU_REFCOUNT_LOCK
+
+#if MPIU_THREAD_REFCOUNT == MPIU_REFCOUNT_NONE
+typedef int MPIU_Handle_ref_count;
+#elif MPIU_THREAD_REFCOUNT == MPIU_REFCOUNT_LOCK
+typedef volatile int MPIU_Handle_ref_count;
+#endif
+#define MPIU_HANDLE_REF_COUNT_INITIALIZER(val_) (val_)
+
+#define MPIU_Object_set_ref(objptr_,val) \
+ do { \
+ MPIU_THREAD_CS_ENTER(HANDLE,objptr_); \
+ (objptr_)->ref_count = val; \
+ MPIU_HANDLE_LOG_REFCOUNT_CHANGE(objptr_, "set"); \
+ MPIU_THREAD_CS_EXIT(HANDLE,objptr_); \
+ } while (0)
+
+/* must be used with care, since there is no synchronization for this read */
+#define MPIU_Object_get_ref(objptr_) \
+ ((objptr_)->ref_count)
+
+#define MPIU_Object_add_ref(objptr_) \
+ do { \
+ MPIU_THREAD_CS_ENTER(HANDLE,objptr_); \
+ (objptr_)->ref_count++; \
+ MPIU_HANDLE_LOG_REFCOUNT_CHANGE(objptr_, "incr"); \
+ MPIU_HANDLE_CHECK_REFCOUNT(objptr_,"incr"); \
+ MPIU_THREAD_CS_EXIT(HANDLE,objptr_); \
+ } while (0)
+#define MPIU_Object_release_ref(objptr_,inuse_ptr) \
+ do { \
+ MPIU_THREAD_CS_ENTER(HANDLE,objptr_); \
+ *(inuse_ptr) = --((objptr_)->ref_count); \
+ MPIU_HANDLE_LOG_REFCOUNT_CHANGE(objptr_, "decr"); \
+ MPIU_HANDLE_CHECK_REFCOUNT(objptr_,"decr"); \
+ MPIU_THREAD_CS_EXIT(HANDLE,objptr_); \
+ } while (0)
+
+#elif MPIU_THREAD_REFCOUNT == MPIU_REFCOUNT_LOCKFREE
+#include "opa_primitives.h"
+typedef OPA_int_t MPIU_Handle_ref_count;
+#define MPIU_HANDLE_REF_COUNT_INITIALIZER(val_) OPA_INT_T_INITIALIZER(val_)
+
+#define MPIU_Object_set_ref(objptr_,val) \
+ do { \
+ OPA_store_int(&(objptr_)->ref_count, val); \
+ MPIU_HANDLE_LOG_REFCOUNT_CHANGE(objptr_, "set"); \
+ } while (0)
+
+/* must be used with care, since there is no synchronization for this read */
+#define MPIU_Object_get_ref(objptr_) \
+ (OPA_load_int(&(objptr_)->ref_count))
+
+#define MPIU_Object_add_ref(objptr_) \
+ do { \
+ OPA_incr_int(&((objptr_)->ref_count)); \
+ MPIU_HANDLE_LOG_REFCOUNT_CHANGE(objptr_, "incr"); \
+ MPIU_HANDLE_CHECK_REFCOUNT(objptr_,"incr"); \
+ } while (0)
+#define MPIU_Object_release_ref(objptr_,inuse_ptr) \
+ do { \
+ int got_zero_ = OPA_decr_and_test_int(&((objptr_)->ref_count)); \
+ *(inuse_ptr) = got_zero_ ? 0 : 1; \
+ MPIU_HANDLE_LOG_REFCOUNT_CHANGE(objptr_, "decr"); \
+ MPIU_HANDLE_CHECK_REFCOUNT(objptr_,"decr"); \
+ } while (0)
+#endif
+/* end reference counting macros */
+/* ------------------------------------------------------------------------- */
+
+/* This macro defines structure fields that are needed in order to use the
+ * reference counting and object allocation macros/functions in MPICH2. This
+ * allows us to avoid casting and violating C's strict aliasing rules in most
+ * cases.
+ *
+ * All *active* (in use) objects have the handle as the first value; objects
+ * with referene counts have the reference count as the second value. See
+ * MPIU_Object_add_ref and MPIU_Object_release_ref.
+ *
+ * NOTE: This macro *must* be invoked as the very first element of the structure! */
+#define MPIU_OBJECT_HEADER \
+ int handle; \
+ MPIU_Handle_ref_count ref_count/*semicolon intentionally omitted*/
+/* For static initialization of structures starting with MPIU_OBJECT_HEADER.
+ * This should be put inside of curly braces {} at the position corresponding to
+ * the MPIU_OBJECT_HEADER (should always be first unless you *really* know what
+ * you are doing) */
+#define MPIU_OBJECT_HEADER_INITIALIZER(handle_val_, ref_cnt_val_) \
+ (handle_val_), MPIU_HANDLE_REF_COUNT_INITIALIZER(ref_cnt_val_)
+
/* ALL objects have the handle as the first value. */
/* Inactive (unused and stored on the appropriate avail list) objects
have MPIU_Handle_common as the head */
typedef struct MPIU_Handle_common {
- int handle;
- volatile int ref_count; /* This field is used to indicate that the
- object is not in use (see, e.g.,
- MPID_Comm_valid_ptr) */
+ MPIU_OBJECT_HEADER;
void *next; /* Free handles use this field to point to the next
free object */
} MPIU_Handle_common;
-/* All *active* (in use) objects have the handle as the first value; objects
- with referene counts have the reference count as the second value.
- See MPIU_Object_add_ref and MPIU_Object_release_ref. */
+/* Provides a type to which a specific object structure can be casted. In
+ * general this should not be used, since most uses are violations of C's strict
+ * aliasing rules. */
typedef struct MPIU_Handle_head {
- int handle;
- volatile int ref_count;
+ MPIU_OBJECT_HEADER;
} MPIU_Handle_head;
/* This type contains all of the data, except for the direct array,
Modified: mpich2/trunk/src/include/mpiimpl.h
===================================================================
--- mpich2/trunk/src/include/mpiimpl.h 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/include/mpiimpl.h 2009-10-20 20:35:30 UTC (rev 5499)
@@ -353,167 +353,6 @@
void MPIR_DatatypeAttrFinalize( void );
/* ------------------------------------------------------------------------- */
-/* mpiobjref.h */
-/* ------------------------------------------------------------------------- */
-/* This isn't quite right, since we need to distinguish between multiple
- user threads and multiple implementation threads.
- */
-
-
-/* If we're debugging the handles (including reference counts),
- add an additional test. The check on a max refcount helps to
- detect objects whose refcounts are not decremented as many times
- as they are incremented */
-#ifdef MPICH_DEBUG_HANDLES
-#define MPICH_DEBUG_MAX_REFCOUNT 64
-#define MPIU_HANDLE_CHECK_REFCOUNT(_objptr,_op) \
- if (((MPIU_Handle_head*)(_objptr))->ref_count > MPICH_DEBUG_MAX_REFCOUNT){\
- MPIU_DBG_MSG_FMT(HANDLE,TYPICAL,(MPIU_DBG_FDEST, \
- "Invalid refcount in %p (0x%08x) %s", \
- (_objptr), (_objptr)->handle, _op)); }
-#else
-#define MPIU_HANDLE_CHECK_REFCOUNT(_objptr,_op)
-#endif
-
-
-/*M
- MPIU_Object_add_ref - Increment the reference count for an MPI object
-
- Synopsis:
-.vb
- MPIU_Object_add_ref( MPIU_Object *ptr )
-.ve
-
- Input Parameter:
-. ptr - Pointer to the object.
-
- Notes:
- In an unthreaded implementation, this function will usually be implemented
- as a single-statement macro. In an 'MPI_THREAD_MULTIPLE' implementation,
- this routine must implement an atomic increment operation, using, for
- example, a lock on datatypes or special assembly code such as
-.vb
- try-again:
- load-link refcount-address to r2
- add 1 to r2
- store-conditional r2 to refcount-address
- if failed branch to try-again:
-.ve
- on RISC architectures or
-.vb
- lock
- inc refcount-address or
-.ve
- on IA32; "lock" is a special opcode prefix that forces atomicity. This
- is not a separate instruction; however, the GNU assembler expects opcode
- prefixes on a separate line.
-
- Module:
- MPID_CORE
-
- Question:
- This accesses the 'ref_count' member of all MPID objects. Currently,
- that member is typed as 'volatile int'. However, for a purely polling,
- thread-funnelled application, the 'volatile' is unnecessary. Should
- MPID objects use a 'typedef' for the 'ref_count' that can be defined
- as 'volatile' only when needed? For now, the answer is no; there isn''t
- enough to be gained in that case.
-M*/
-
-/*M
- MPIU_Object_release_ref - Decrement the reference count for an MPI object
-
- Synopsis:
-.vb
- MPIU_Object_release_ref( MPIU_Object *ptr, int *inuse_ptr )
-.ve
-
- Input Parameter:
-. objptr - Pointer to the object.
-
- Output Parameter:
-. inuse_ptr - Pointer to the value of the reference count after decrementing.
- This value is either zero or non-zero. See below for details.
-
- Notes:
- In an unthreaded implementation, this function will usually be implemented
- as a single-statement macro. In an 'MPI_THREAD_MULTIPLE' implementation,
- this routine must implement an atomic decrement operation, using, for
- example, a lock on datatypes or special assembly code such as
-.vb
- try-again:
- load-link refcount-address to r2
- sub 1 to r2
- store-conditional r2 to refcount-address
- if failed branch to try-again:
- store r2 to newval_ptr
-.ve
- on RISC architectures or
-.vb
- lock
- dec refcount-address
- if zf store 0 to newval_ptr else store 1 to newval_ptr
-.ve
- on IA32; "lock" is a special opcode prefix that forces atomicity. This
- is not a separate instruction; however, the GNU assembler expects opcode
- prefixes on a separate line. 'zf' is the zero flag; this is set if the
- result of the operation is zero. Implementing a full decrement-and-fetch
- would require more code and the compare and swap instruction.
-
- Once the reference count is decremented to zero, it is an error to
- change it. A correct MPI program will never do that, but an incorrect one
- (particularly a multithreaded program with a race condition) might.
-
- The following code is `invalid`\:
-.vb
- MPID_Object_release_ref( datatype_ptr );
- if (datatype_ptr->ref_count == 0) MPID_Datatype_free( datatype_ptr );
-.ve
- In a multi-threaded implementation, the value of 'datatype_ptr->ref_count'
- may have been changed by another thread, resulting in both threads calling
- 'MPID_Datatype_free'. Instead, use
-.vb
- MPID_Object_release_ref( datatype_ptr, &inUse );
- if (!inuse)
- MPID_Datatype_free( datatype_ptr );
-.ve
-
- Module:
- MPID_CORE
- M*/
-
-/* The MPIU_DBG... statements are macros that vanish unless
- --enable-g=log is selected. MPIU_HANDLE_CHECK_REFCOUNT is
- defined above, and adds an additional sanity check for the refcounts
-*/
-#define MPIU_Object_set_ref(objptr,val) \
- {((objptr))->ref_count = val; \
- MPIU_DBG_MSG_FMT(HANDLE,TYPICAL,(MPIU_DBG_FDEST, \
- "set %p (0x%08x) refcount to %d", \
- (objptr), (objptr)->handle, val)); \
- }
-#define MPIU_Object_add_ref(objptr) \
- {((objptr))->ref_count++; \
- MPIU_DBG_MSG_FMT(HANDLE,TYPICAL,(MPIU_DBG_FDEST, \
- "incr %p (0x%08x) refcount to %d", \
- (objptr), (objptr)->handle, (objptr)->ref_count));\
- MPIU_HANDLE_CHECK_REFCOUNT(objptr,"incr"); \
- }
-#define MPIU_Object_release_ref(objptr,inuse_ptr) \
- {*(inuse_ptr)=--((objptr))->ref_count; \
- MPIU_DBG_MSG_FMT(HANDLE,TYPICAL,(MPIU_DBG_FDEST, \
- "decr %p (0x%08x) refcount to %d", \
- (objptr), (objptr)->handle, (objptr)->ref_count)); \
- MPIU_HANDLE_CHECK_REFCOUNT(objptr,"decr"); \
- }
-
-
-
-/* ------------------------------------------------------------------------- */
-/* mpiobjref.h */
-/* ------------------------------------------------------------------------- */
-
-/* ------------------------------------------------------------------------- */
/* Should the following be moved into mpihandlemem.h ?*/
/* ------------------------------------------------------------------------- */
@@ -615,10 +454,13 @@
/* Check not only for a null pointer but for an invalid communicator,
such as one that has been freed. Let's try the ref_count as the test
for now */
-#define MPID_Comm_valid_ptr(ptr,err) { \
- MPID_Valid_ptr_class(Comm,ptr,MPI_ERR_COMM,err); \
- if ((ptr) && (ptr)->ref_count == 0) { \
- err = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_COMM,"**comm", 0);ptr=0;}}
+#define MPID_Comm_valid_ptr(ptr,err) { \
+ MPID_Valid_ptr_class(Comm,ptr,MPI_ERR_COMM,err); \
+ if ((ptr) && MPIU_Object_get_ref(ptr) == 0) { \
+ MPIU_ERR_SET(err,MPI_ERR_COMM,"**comm"); \
+ ptr = 0; \
+ } \
+}
#define MPID_Group_valid_ptr(ptr,err) MPID_Valid_ptr_class(Group,ptr,MPI_ERR_GROUP,err)
#define MPID_Win_valid_ptr(ptr,err) MPID_Valid_ptr_class(Win,ptr,MPI_ERR_WIN,err)
#define MPID_Op_valid_ptr(ptr,err) MPID_Valid_ptr_class(Op,ptr,MPI_ERR_OP,err)
@@ -728,12 +570,7 @@
Info-DS
S*/
typedef struct MPID_Info {
- int handle;
- volatile int ref_count; /* FIXME: ref_count isn't needed by Info
- objects, but MPIU_Info_free does not
- work correctly unless MPID_Info and
- MPIU_Handle_common have the next
- pointer in the same location */
+ MPIU_OBJECT_HEADER; /* adds handle and ref_count fields */
struct MPID_Info *next;
char *key;
char *value;
@@ -793,8 +630,7 @@
ErrHand-DS
S*/
typedef struct MPID_Errhandler {
- int handle;
- volatile int ref_count;
+ MPIU_OBJECT_HEADER; /* adds handle and ref_count fields */
MPID_Lang_t language;
MPID_Object_kind kind;
MPID_Errhandler_fn errfn;
@@ -809,13 +645,9 @@
extern MPID_Errhandler MPID_Errhandler_direct[];
#define MPIR_Errhandler_add_ref( _errhand ) \
- { MPIU_Object_add_ref( _errhand ); \
- MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST,\
- "Incr errhandler %p ref count to %d",_errhand,_errhand->ref_count));}
+ do { MPIU_Object_add_ref( _errhand ); } while (0)
#define MPIR_Errhandler_release_ref( _errhand, _inuse ) \
- { MPIU_Object_release_ref( _errhand, _inuse ); \
- MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST,\
- "Decr errhandler %p ref count to %d",_errhand,_errhand->ref_count));}
+ do { MPIU_Object_release_ref( _errhand, _inuse ); } while (0)
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
@@ -995,8 +827,7 @@
S*/
typedef struct MPID_Keyval {
- int handle;
- volatile int ref_count;
+ MPIU_OBJECT_HEADER; /* adds handle and ref_count fields */
MPID_Object_kind kind;
int was_freed;
void *extra_state;
@@ -1010,18 +841,12 @@
#define MPIR_Keyval_add_ref( _keyval ) \
do { \
- MPIU_Assert((_keyval)->ref_count >= 0); \
MPIU_Object_add_ref( _keyval ); \
- MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST, \
- "Incr keyval %p ref count to %d",_keyval,_keyval->ref_count)); \
} while(0)
#define MPIR_Keyval_release_ref( _keyval, _inuse ) \
do { \
MPIU_Object_release_ref( _keyval, _inuse ); \
- MPIU_Assert((_keyval)->ref_count >= 0); \
- MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST, \
- "Decr keyval %p ref count to %d",_keyval,_keyval->ref_count)); \
} while(0)
@@ -1078,10 +903,9 @@
S*/
typedef struct MPID_Attribute {
- int handle;
- volatile int ref_count;
+ MPIU_OBJECT_HEADER; /* adds handle and ref_count fields */
MPID_Keyval *keyval; /* Keyval structure for this attribute */
-
+
struct MPID_Attribute *next; /* Pointer to next in the list */
MPIR_AttrType attrType; /* Type of the attribute */
long pre_sentinal; /* Used to detect user errors in accessing
@@ -1145,8 +969,7 @@
S*/
typedef struct MPID_Group {
- int handle;
- volatile int ref_count;
+ MPIU_OBJECT_HEADER; /* adds handle and ref_count fields */
int size; /* Size of a group */
int rank; /* rank of this process relative to this
group */
@@ -1167,14 +990,10 @@
extern MPID_Group MPID_Group_direct[];
#define MPIR_Group_add_ref( _group ) \
- { MPIU_Object_add_ref( _group ); \
- MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST,\
- "Incr group %p ref count to %d",_group,_group->ref_count));}
+ do { MPIU_Object_add_ref( _group ); } while (0)
#define MPIR_Group_release_ref( _group, _inuse ) \
- { MPIU_Object_release_ref( _group, _inuse ); \
- MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST,\
- "Decr group %p ref count to %d",_group,_group->ref_count));}
+ do { MPIU_Object_release_ref( _group, _inuse ); } while (0)
void MPIR_Group_setup_lpid_list( MPID_Group * );
int MPIR_GroupCheckVCRSubset( MPID_Group *group_ptr, int vsize, MPID_VCR *vcr, int *idx );
@@ -1250,9 +1069,8 @@
health? For example, ok, failure detected, all (live) members of failed
communicator have acked.
S*/
-typedef struct MPID_Comm {
- int handle; /* value of MPI_Comm for this structure */
- volatile int ref_count;
+typedef struct MPID_Comm {
+ MPIU_OBJECT_HEADER; /* adds handle and ref_count fields */
MPIR_Context_id_t context_id; /* Send context id. See notes */
MPIR_Context_id_t recvcontext_id; /* Send context id. See notes */
int remote_size; /* Value of MPI_Comm_(remote)_size */
@@ -1320,14 +1138,10 @@
int MPIR_Comm_release(MPID_Comm *, int );
#define MPIR_Comm_add_ref(_comm) \
- { MPIU_Object_add_ref((_comm)); \
- MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST,\
- "Incr comm %p ref count to %d",_comm,_comm->ref_count));}
+ do { MPIU_Object_add_ref((_comm)); } while (0)
#define MPIR_Comm_release_ref( _comm, _inuse ) \
- { MPIU_Object_release_ref( _comm, _inuse ); \
- MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST,\
- "Decr comm %p ref count to %d",_comm,_comm->ref_count));}
+ do { MPIU_Object_release_ref( _comm, _inuse ); } while (0)
/* Preallocated comm objects. There are 3: comm_world, comm_self, and
a private (non-user accessible) dup of comm world that is provided
@@ -1470,8 +1284,7 @@
S*/
typedef struct MPID_Request {
- int handle;
- volatile int ref_count;
+ MPIU_OBJECT_HEADER; /* adds handle and ref_count fields */
MPID_Request_kind_t kind;
/* completion counter */
volatile int cc;
@@ -1508,14 +1321,10 @@
extern MPID_Request MPID_Request_direct[];
#define MPIR_Request_add_ref( _req ) \
- { MPIU_Object_add_ref( _req ); \
- MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST,\
- "Incr request %p ref count to %d",_req,_req->ref_count));}
+ do { MPIU_Object_add_ref( _req ); } while (0)
#define MPIR_Request_release_ref( _req, _inuse ) \
- { MPIU_Object_release_ref( _req, _inuse ); \
- MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST,\
- "Decr request %p ref count to %d",_req,_req->ref_count));}
+ do { MPIU_Object_release_ref( _req, _inuse ); } while (0)
/* These macros allow us to implement a sendq when debugger support is
selected. As there is extra overhead for this, we only do this
@@ -1637,8 +1446,7 @@
S*/
typedef struct MPID_Win {
- int handle; /* value of MPI_Win for this structure */
- volatile int ref_count;
+ MPIU_OBJECT_HEADER; /* adds handle and ref_count fields */
int fence_cnt; /* 0 = no fence has been called;
1 = fence has been called */
MPID_Errhandler *errhandler; /* Pointer to the error handler structure */
@@ -1852,8 +1660,7 @@
Collective-DS
S*/
typedef struct MPID_Op {
- int handle; /* value of MPI_Op for this structure */
- volatile int ref_count;
+ MPIU_OBJECT_HEADER; /* adds handle and ref_count fields */
MPID_Op_kind kind;
MPID_Lang_t language;
MPID_User_function function;
@@ -1864,9 +1671,7 @@
extern MPIU_Object_alloc_t MPID_Op_mem;
#define MPIR_Op_release_ref( _op, _inuse ) \
- { MPIU_Object_release_ref( _op, _inuse ); \
- MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST,\
- "Decr MPI_Op %p ref count to %d",_op,_op->ref_count));}
+ do { MPIU_Object_release_ref( _op, _inuse ); } while (0)
/* ------------------------------------------------------------------------- */
@@ -2233,6 +2038,7 @@
/* ------------------------------------------------------------------------- */
+/* XXX DJG FIXME delete this? */
/* FIXME: Merge these with the object refcount update routines (perhaps as
part of a general "atomic update" file */
/*
@@ -3325,9 +3131,7 @@
void MPID_Request_release(MPID_Request *);
typedef struct MPID_Grequest_class {
- int handle; /* value of MPIX_Grequest_class for
- this structure */
- volatile int ref_count;
+ MPIU_OBJECT_HEADER; /* adds handle and ref_count fields */
MPI_Grequest_query_function *query_fn;
MPI_Grequest_free_function *free_fn;
MPI_Grequest_cancel_function *cancel_fn;
Modified: mpich2/trunk/src/mpi/comm/commutil.c
===================================================================
--- mpich2/trunk/src/mpi/comm/commutil.c 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/mpi/comm/commutil.c 2009-10-20 20:35:30 UTC (rev 5499)
@@ -14,8 +14,8 @@
#endif
/* Preallocated comm objects */
-MPID_Comm MPID_Comm_builtin[MPID_COMM_N_BUILTIN] = { {0,0} };
-MPID_Comm MPID_Comm_direct[MPID_COMM_PREALLOC] = { {0,0} };
+MPID_Comm MPID_Comm_builtin[MPID_COMM_N_BUILTIN] = { { MPIU_OBJECT_HEADER_INITIALIZER(0,0) } };
+MPID_Comm MPID_Comm_direct[MPID_COMM_PREALLOC] = { { MPIU_OBJECT_HEADER_INITIALIZER(0,0) } };
MPIU_Object_alloc_t MPID_Comm_mem = { 0, 0, 0, 0, MPID_COMM,
sizeof(MPID_Comm), MPID_Comm_direct,
MPID_COMM_PREALLOC};
Modified: mpich2/trunk/src/mpi/errhan/errutil.c
===================================================================
--- mpich2/trunk/src/mpi/errhan/errutil.c 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/mpi/errhan/errutil.c 2009-10-20 20:35:30 UTC (rev 5499)
@@ -112,11 +112,12 @@
#endif
/* Preallocated errorhandler objects */
-MPID_Errhandler MPID_Errhandler_builtin[3] =
- { { MPI_ERRORS_ARE_FATAL, 0},
- { MPI_ERRORS_RETURN, 0},
- { MPIR_ERRORS_THROW_EXCEPTIONS, 0 } };
-MPID_Errhandler MPID_Errhandler_direct[MPID_ERRHANDLER_PREALLOC] = { {0} };
+MPID_Errhandler MPID_Errhandler_builtin[3] = {
+ { MPIU_OBJECT_HEADER_INITIALIZER(MPI_ERRORS_ARE_FATAL, 0), },
+ { MPIU_OBJECT_HEADER_INITIALIZER(MPI_ERRORS_RETURN, 0), },
+ { MPIU_OBJECT_HEADER_INITIALIZER(MPIR_ERRORS_THROW_EXCEPTIONS, 0) },
+ };
+MPID_Errhandler MPID_Errhandler_direct[MPID_ERRHANDLER_PREALLOC] = { { MPIU_OBJECT_HEADER_INITIALIZER(0,0) } };
MPIU_Object_alloc_t MPID_Errhandler_mem = { 0, 0, 0, 0, MPID_ERRHANDLER,
sizeof(MPID_Errhandler),
MPID_Errhandler_direct,
Modified: mpich2/trunk/src/mpi/group/grouputil.c
===================================================================
--- mpich2/trunk/src/mpi/group/grouputil.c 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/mpi/group/grouputil.c 2009-10-20 20:35:30 UTC (rev 5499)
@@ -13,8 +13,8 @@
/* Preallocated group objects */
MPID_Group MPID_Group_builtin[MPID_GROUP_N_BUILTIN] = {
- { MPI_GROUP_EMPTY, 1, 0, MPI_UNDEFINED, -1, 0, } };
-MPID_Group MPID_Group_direct[MPID_GROUP_PREALLOC] = { {0} };
+ { MPIU_OBJECT_HEADER_INITIALIZER(MPI_GROUP_EMPTY, 1), 0, MPI_UNDEFINED, -1, 0, } };
+MPID_Group MPID_Group_direct[MPID_GROUP_PREALLOC] = { { MPIU_OBJECT_HEADER_INITIALIZER(0,0) } };
MPIU_Object_alloc_t MPID_Group_mem = { 0, 0, 0, 0, MPID_GROUP,
sizeof(MPID_Group), MPID_Group_direct,
MPID_GROUP_PREALLOC};
Modified: mpich2/trunk/src/mpi/pt2pt/bsendutil.c
===================================================================
--- mpich2/trunk/src/mpi/pt2pt/bsendutil.c 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/mpi/pt2pt/bsendutil.c 2009-10-20 20:35:30 UTC (rev 5499)
@@ -450,7 +450,8 @@
testing when the user has successfully released
the request (it is a grequest, the free call will do it) */
flag = 0;
- if (active->request->ref_count == 1) {
+ /* XXX DJG FIXME-MT should we be checking this? */
+ if (MPIU_Object_get_ref(active->request) == 1) {
NMPI_Test(&r, &flag, MPI_STATUS_IGNORE );
}
else {
Modified: mpich2/trunk/src/mpi/pt2pt/ibsend.c
===================================================================
--- mpich2/trunk/src/mpi/pt2pt/ibsend.c 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/mpi/pt2pt/ibsend.c 2009-10-20 20:35:30 UTC (rev 5499)
@@ -45,7 +45,8 @@
/* Release the MPID_Request (there is still another ref pending
within the bsendutil functions) */
- if (ibsend_info->req->ref_count > 1) {
+ /* XXX DJG FIXME-MT should we be checking this? */
+ if (MPIU_Object_get_ref(ibsend_info->req) > 1) {
int inuse;
/* Note that this should mean that the request was
cancelled (that would have decremented the ref count)
Modified: mpich2/trunk/src/mpi/spawn/comm_disconnect.c
===================================================================
--- mpich2/trunk/src/mpi/spawn/comm_disconnect.c 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/mpi/spawn/comm_disconnect.c 2009-10-20 20:35:30 UTC (rev 5499)
@@ -103,12 +103,13 @@
* only for pending communication operations (and decremented when
* those complete).
*/
- if (comm_ptr->ref_count > 1)
+ /* FIXME-MT should we be checking this? */
+ if (MPIU_Object_get_ref(comm_ptr) > 1)
{
MPID_Progress_state progress_state;
MPID_Progress_start(&progress_state);
- while (comm_ptr->ref_count > 1)
+ while (MPIU_Object_get_ref(comm_ptr) > 1)
{
mpi_errno = MPID_Progress_wait(&progress_state);
/* --BEGIN ERROR HANDLING-- */
Modified: mpich2/trunk/src/mpid/ch3/channels/nemesis/nemesis/netmod/mx/mx_impl.h
===================================================================
--- mpich2/trunk/src/mpid/ch3/channels/nemesis/nemesis/netmod/mx/mx_impl.h 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/mpid/ch3/channels/nemesis/nemesis/netmod/mx/mx_impl.h 2009-10-20 20:35:30 UTC (rev 5499)
@@ -103,8 +103,7 @@
/* The begining of this structure is the same as MPID_Request */
struct MPID_nem_mx_internal_req
{
- int handle; /* unused */
- volatile int ref_count; /* unused */
+ MPIU_OBJECT_HEADER; /* adds (unused) handle and ref_count fields */
MPID_Request_kind_t kind; /* used */
MPIDI_CH3_PktGeneric_t pending_pkt;
MPIDI_VC_t *vc;
Modified: mpich2/trunk/src/mpid/ch3/channels/nemesis/nemesis/src/mpid_nem_debug.c
===================================================================
--- mpich2/trunk/src/mpid/ch3/channels/nemesis/nemesis/src/mpid_nem_debug.c 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/mpid/ch3/channels/nemesis/nemesis/src/mpid_nem_debug.c 2009-10-20 20:35:30 UTC (rev 5499)
@@ -124,7 +124,7 @@
MPIDI_PG_Get_iterator(&iter);
while (MPIDI_PG_Has_next(&iter)) {
MPIDI_PG_Get_next(&iter, &pg);
- fprintf(stream, "PG ptr=%p size=%d id=%s refcount=%d\n", pg, pg->size, (const char*)pg->id, pg->ref_count);
+ fprintf(stream, "PG ptr=%p size=%d id=%s refcount=%d\n", pg, pg->size, (const char*)pg->id, MPIU_Object_get_ref(pg));
for (i = 0; i < MPIDI_PG_Get_size(pg); ++i) {
/* We would prefer to use "MPIDI_PG_Get_vc_set_active(pg, rank, &vc);"
but that macro has the side effect of changing the VC's state, which
Modified: mpich2/trunk/src/mpid/ch3/channels/sctp/src/ch3_progress.c
===================================================================
--- mpich2/trunk/src/mpid/ch3/channels/sctp/src/ch3_progress.c 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/mpid/ch3/channels/sctp/src/ch3_progress.c 2009-10-20 20:35:30 UTC (rev 5499)
@@ -622,6 +622,9 @@
} else {
/* not a temporary VC */
+ /* FIXME why would the vc ref_count be zero w/o being destroyed yet?
+ * A check against zero like this is usually not
+ * thread-safe...*/
if(vc->ref_count == 0 && vc->pg != NULL && vc->pg->ref_count == 1 ) {
/* MPIDI_PG_Destroy will be called in the upcall below, so do the
* necessary steps since this VC will be destroyed.
Modified: mpich2/trunk/src/mpid/ch3/include/mpidimpl.h
===================================================================
--- mpich2/trunk/src/mpid/ch3/include/mpidimpl.h 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/mpid/ch3/include/mpidimpl.h 2009-10-20 20:35:30 UTC (rev 5499)
@@ -67,8 +67,7 @@
MPIU_Object system, but we do use the associated reference counting
routines. Therefore, handle must be present, but is not used
except by debugging routines */
- int handle;
- volatile int ref_count;
+ MPIU_OBJECT_HEADER; /* adds handle and ref_count fields */
/* Next pointer used to maintain a list of all process groups known to
this process */
@@ -583,17 +582,13 @@
int MPIDI_CH3_PG_Init( MPIDI_PG_t * );
#define MPIDI_PG_add_ref(pg_) \
-{ \
+do { \
MPIU_Object_add_ref(pg_); \
- MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST,\
- "Incr process group %p ref count to %d",pg_,pg_->ref_count));\
-}
+} while (0)
#define MPIDI_PG_release_ref(pg_, inuse_) \
-{ \
+do { \
MPIU_Object_release_ref(pg_, inuse_); \
- MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST,\
- "Decr process group %p ref count to %d",pg_,pg_->ref_count));\
-}
+} while (0)
#define MPIDI_PG_Get_vc_set_active(pg_, rank_, vcp_) do { \
*(vcp_) = &(pg_)->vct[rank_]; \
@@ -695,8 +690,7 @@
when debugging objects (the handle kind is used in reporting
on changes to the object).
*/
- int handle;
- volatile int ref_count;
+ MPIU_OBJECT_HEADER; /* adds handle and ref_count fields */
/* state of the VC */
MPIDI_VC_State_t state;
@@ -805,14 +799,10 @@
#define MPIDI_VC_add_ref( _vc ) \
- { MPIU_Object_add_ref( _vc ); \
- MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST, \
- "Incr VC %p ref count to %d",_vc,_vc->ref_count));}
+ do { MPIU_Object_add_ref( _vc ); } while (0)
#define MPIDI_VC_release_ref( _vc, _inuse ) \
- { MPIU_Object_release_ref( _vc, _inuse ); \
- MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST,\
- "Decr VC %p ref count to %d",_vc,_vc->ref_count));}
+ do { MPIU_Object_release_ref( _vc, _inuse ); } while (0)
/*------------------------------
END VIRTUAL CONNECTION SECTION
Modified: mpich2/trunk/src/mpid/ch3/src/ch3u_handle_connection.c
===================================================================
--- mpich2/trunk/src/mpid/ch3/src/ch3u_handle_connection.c 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/mpid/ch3/src/ch3u_handle_connection.c 2009-10-20 20:35:30 UTC (rev 5499)
@@ -59,8 +59,9 @@
* FIXME: The VC used in connect accept has a NULL
* process group
*/
- if (vc->pg != NULL && vc->ref_count == 0)
- {
+ /* XXX DJG FIXME-MT should we be checking this ref_count? */
+ if (vc->pg != NULL && (MPIU_Object_get_ref(vc) == 0))
+ {
/* FIXME: Who increments the reference count that
this is decrementing? */
/* When the reference count for a vc becomes zero,
Modified: mpich2/trunk/src/mpid/ch3/src/ch3u_port.c
===================================================================
--- mpich2/trunk/src/mpid/ch3/src/ch3u_port.c 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/mpid/ch3/src/ch3u_port.c 2009-10-20 20:35:30 UTC (rev 5499)
@@ -575,7 +575,8 @@
pg_list->pg_id = MPIU_Strdup(comm_p->vcr[0]->pg->id);
pg_list->index = cur_index++;
pg_list->next = NULL;
- MPIU_Assert( comm_p->vcr[0]->pg->ref_count);
+ /* XXX DJG FIXME-MT should we be checking this? the add/release macros already check this */
+ MPIU_Assert( MPIU_Object_get_ref(comm_p->vcr[0]->pg));
mpi_errno = MPIDI_PG_To_string(comm_p->vcr[0]->pg, &pg_list->str,
&pg_list->lenStr );
if (mpi_errno != MPI_SUCCESS) {
@@ -590,7 +591,8 @@
pg_trailer = pg_list;
while (pg_iter != NULL) {
/* Check to ensure pg is (probably) valid */
- MPIU_Assert(comm_p->vcr[i]->pg->ref_count != 0);
+ /* XXX DJG FIXME-MT should we be checking this? the add/release macros already check this */
+ MPIU_Assert(MPIU_Object_get_ref(comm_p->vcr[i]->pg) != 0);
if (MPIDI_PG_Id_compare(comm_p->vcr[i]->pg->id, pg_iter->pg_id)) {
local_translation[i].pg_index = pg_iter->index;
local_translation[i].pg_rank = comm_p->vcr[i]->pg_rank;
Modified: mpich2/trunk/src/mpid/ch3/src/ch3u_request.c
===================================================================
--- mpich2/trunk/src/mpid/ch3/src/ch3u_request.c 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/mpid/ch3/src/ch3u_request.c 2009-10-20 20:35:30 UTC (rev 5499)
@@ -129,6 +129,7 @@
"**invalid_handle", "**invalid_handle %d", req->handle);
MPID_Abort(MPIR_Process.comm_world, mpi_errno, -1, NULL);
}
+ /* XXX DJG FIXME should we be checking this? */
/*MPIU_Assert(req->ref_count == 0);*/
if (req->ref_count != 0)
{
Modified: mpich2/trunk/src/mpid/ch3/src/mpid_vc.c
===================================================================
--- mpich2/trunk/src/mpid/ch3/src/mpid_vc.c 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/mpid/ch3/src/mpid_vc.c 2009-10-20 20:35:30 UTC (rev 5499)
@@ -35,8 +35,7 @@
S*/
typedef struct MPIDI_VCRT
{
- int handle;
- volatile int ref_count;
+ MPIU_OBJECT_HEADER; /* adds handle and ref_count fields */
int size;
MPIDI_VC_t * vcr_table[1];
}
@@ -110,8 +109,7 @@
MPIDI_FUNC_ENTER(MPID_STATE_MPID_VCRT_ADD_REF);
MPIU_Object_add_ref(vcrt);
- MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST,
- "Incr VCRT %p ref count to %d",vcrt,vcrt->ref_count));
+ MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST, "Incr VCRT %p ref count",vcrt));
MPIDI_FUNC_EXIT(MPID_STATE_MPID_VCRT_ADD_REF);
return MPI_SUCCESS;
}
@@ -137,8 +135,7 @@
MPIDI_FUNC_ENTER(MPID_STATE_MPID_VCRT_RELEASE);
MPIU_Object_release_ref(vcrt, &in_use);
- MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST,
- "Decr VCRT %p ref count to %d",vcrt,vcrt->ref_count));
+ MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST, "Decr VCRT %p ref count",vcrt));
/* If this VC reference table is no longer in use, we can
decrement the reference count of each of the VCs. If the
@@ -163,7 +160,21 @@
/* Dynamic connections start with a refcount of 2 instead of 1.
* That way we can distinguish between an MPI_Free and an
* MPI_Comm_disconnect. */
- if (isDisconnect && vc->ref_count == 1) {
+ /* XXX DJG FIXME-MT should we be checking this? */
+ /* probably not, need to do something like the following instead: */
+#if 0
+ if (isDisconnect) {
+ MPIU_Assert(in_use);
+ /* FIXME this is still bogus, the VCRT may contain a mix of
+ * dynamic and non-dynamic VCs, so the ref_count isn't
+ * guaranteed to have started at 2. The best thing to do might
+ * be to avoid overloading the reference counting this way and
+ * use a separate check for dynamic VCs (another flag? compare
+ * PGs?) */
+ MPIU_Object_release_ref(vc, &in_use);
+ }
+#endif
+ if (isDisconnect && MPIU_Object_get_ref(vc) == 1) {
MPIDI_VC_release_ref(vc, &in_use);
}
@@ -269,7 +280,9 @@
/* We are allowed to create a vc that belongs to no process group
as part of the initial connect/accept action, so in that case,
ignore the pg ref count update */
- if (orig_vcr->ref_count == 0 && orig_vcr->pg) {
+ /* XXX DJG FIXME-MT should we be checking this? */
+ /* we probably need a test-and-incr operation or equivalent to avoid races */
+ if (MPIU_Object_get_ref(orig_vcr) == 0 && orig_vcr->pg) {
MPIDI_VC_add_ref( orig_vcr );
MPIDI_VC_add_ref( orig_vcr );
MPIDI_PG_add_ref( orig_vcr->pg );
@@ -277,8 +290,7 @@
else {
MPIDI_VC_add_ref(orig_vcr);
}
- MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST,\
- "Incr VCR %p ref count to %d",orig_vcr,orig_vcr->ref_count));
+ MPIU_DBG_MSG_FMT(REFCOUNT,TYPICAL,(MPIU_DBG_FDEST,"Incr VCR %p ref count",orig_vcr));
*new_vcr = orig_vcr;
MPIDI_FUNC_EXIT(MPID_STATE_MPID_VCR_DUP);
return MPI_SUCCESS;
Modified: mpich2/trunk/src/mpid/ch3/src/mpidi_pg.c
===================================================================
--- mpich2/trunk/src/mpid/ch3/src/mpidi_pg.c 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/mpid/ch3/src/mpidi_pg.c 2009-10-20 20:35:30 UTC (rev 5499)
@@ -117,11 +117,12 @@
the ref count is not zero. This can happen if the user
fails to use MPI_Comm_disconnect on communicators that
were created with the dynamic process routines.*/
- if (pg->ref_count == 0 || 1) {
+ /* XXX DJG FIXME-MT should we be checking this? */
+ if (MPIU_Object_get_ref(pg) == 0 || 1) {
if (pg == MPIDI_Process.my_pg)
MPIDI_Process.my_pg = NULL;
- pg->ref_count = 0; /* satisfy assertions in PG_Destroy */
+ MPIU_Object_set_ref(pg, 0); /* satisfy assertions in PG_Destroy */
MPIDI_PG_Destroy( pg );
}
pg = pgNext;
@@ -273,7 +274,7 @@
MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_PG_DESTROY);
- MPIU_Assert(pg->ref_count == 0);
+ MPIU_Assert(MPIU_Object_get_ref(pg) == 0);
pg_prev = NULL;
pg_cur = MPIDI_PG_list;
@@ -304,7 +305,7 @@
counts IS required and missing one is a bug.)
2) There is a real bug lurking out there somewhere and we
just haven't hit it in the tests yet. */
- /*MPIU_Assert(pg->vct[i].ref_count == 0);*/
+ /*MPIU_Assert(MPIU_Object_get_ref(pg->vct[i]) == 0);*/
MPIU_DBG_MSG_FMT(CH3_DISCONNECT, VERBOSE, (MPIU_DBG_FDEST, "about to free pg->vct=%p which contains vc=%p", pg->vct, &pg->vct[i]));
@@ -1120,8 +1121,8 @@
increases from 0 to 1, increase the reference count of the
process group *and* the reference count of the vc (this
allows us to distinquish between Comm_free and Comm_disconnect) */
- /* FIXME: This should be a fetch and increment for thread-safety */
- if (vc->ref_count == 0) {
+ /* FIXME-MT: This should be a fetch and increment for thread-safety */
+ if (MPIU_Object_get_ref(vc) == 0) {
MPIDI_PG_add_ref(pg);
MPIDI_VC_add_ref(vc);
}
@@ -1165,7 +1166,8 @@
MPIDI_VC_t * vc = &pg->vct[i];
/* If the VC is myself then skip the close message */
if (pg == MPIDI_Process.my_pg && i == MPIDI_Process.my_pg_rank) {
- if (vc->ref_count != 0) {
+ /* XXX DJG FIXME-MT should we be checking this? */
+ if (MPIU_Object_get_ref(vc) != 0) {
MPIDI_PG_release_ref(pg, &inuse);
}
continue;
@@ -1191,7 +1193,8 @@
}
else
{
- if (vc->state == MPIDI_VC_STATE_INACTIVE && vc->ref_count != 0) {
+ /* XXX DJG FIXME-MT should we be checking this? */
+ if (vc->state == MPIDI_VC_STATE_INACTIVE && MPIU_Object_get_ref(vc) != 0) {
/* FIXME: If the reference count for the vc is not 0,
something is wrong */
MPIDI_PG_release_ref(pg, &inuse);
@@ -1226,11 +1229,12 @@
fprintf( fp, "Process groups:\n" );
while (pg) {
+ /* XXX DJG FIXME-MT should we be checking this? */
fprintf( fp, "size = %d, refcount = %d, id = %s\n",
- pg->size, pg->ref_count, (char *)pg->id );
+ pg->size, MPIU_Object_get_ref(pg), (char *)pg->id );
for (i=0; i<pg->size; i++) {
fprintf( fp, "\tVCT rank = %d, refcount = %d, lpid = %d, state = %d \n",
- pg->vct[i].pg_rank, pg->vct[i].ref_count,
+ pg->vct[i].pg_rank, MPIU_Object_get_ref(&pg->vct[i]),
pg->vct[i].lpid, (int)pg->vct[i].state );
}
fflush(fp);
Modified: mpich2/trunk/src/mpid/common/datatype/mpid_datatype.h
===================================================================
--- mpich2/trunk/src/mpid/common/datatype/mpid_datatype.h 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/mpid/common/datatype/mpid_datatype.h 2009-10-20 20:35:30 UTC (rev 5499)
@@ -355,8 +355,7 @@
S*/
typedef struct MPID_Datatype {
/* handle and ref_count are filled in by MPIU_Handle_obj_alloc() */
- int handle; /* value of MPI_Datatype for structure */
- volatile int ref_count;
+ MPIU_OBJECT_HEADER; /* adds handle and ref_count fields */
/* basic parameters for datatype, accessible via MPI calls */
int size;
Modified: mpich2/trunk/src/util/mem/handlemem.c
===================================================================
--- mpich2/trunk/src/util/mem/handlemem.c 2009-10-20 20:35:28 UTC (rev 5498)
+++ mpich2/trunk/src/util/mem/handlemem.c 2009-10-20 20:35:30 UTC (rev 5499)
@@ -534,29 +534,35 @@
return 0;
}
-static const char *MPIR_ObjectName( MPIU_Object_alloc_t *objmem )
+/* returns the name of the handle kind for debugging/logging purposes */
+const char *MPIU_Handle_get_kind_str(int kind)
{
- const char *name=0;
- switch (objmem->kind) {
- case MPID_COMM: name = "COMM"; break;
- case MPID_GROUP: name = "GROUP"; break;
- case MPID_DATATYPE: name = "DATATYPE"; break;
- case MPID_FILE: name = "FILE"; break;
- case MPID_ERRHANDLER: name = "ERRHANDLER"; break;
- case MPID_OP: name = "OP"; break;
- case MPID_INFO: name = "INFO"; break;
- case MPID_WIN: name = "WIN"; break;
- case MPID_KEYVAL: name = "ATTRIBUTE KEY"; break;
- case MPID_ATTR: name = "ATTRIBUTE"; break;
- case MPID_REQUEST: name = "REQUEST"; break;
- case MPID_PROCGROUP: name = "PROCGROUP"; break;
- case MPID_VCONN: name = "VIRTUAL CONNECTION"; break;
- case MPID_GREQ_CLASS: name = "GENERALIZED REQUEST CLASS"; break;
- default:
- name = "UNKNOWN OBJECT TYPE";
+#define mpiu_name_case_(name_) case MPID_##name_: return (#name_)
+ switch (kind) {
+ mpiu_name_case_(COMM);
+ mpiu_name_case_(GROUP);
+ mpiu_name_case_(DATATYPE);
+ mpiu_name_case_(FILE);
+ mpiu_name_case_(ERRHANDLER);
+ mpiu_name_case_(OP);
+ mpiu_name_case_(INFO);
+ mpiu_name_case_(WIN);
+ mpiu_name_case_(KEYVAL);
+ mpiu_name_case_(ATTR);
+ mpiu_name_case_(REQUEST);
+ mpiu_name_case_(PROCGROUP);
+ mpiu_name_case_(VCONN);
+ mpiu_name_case_(GREQ_CLASS);
+ default:
+ return "unknown";
}
- return name;
+#undef mpiu_name_case_
}
+
+static const char *MPIR_ObjectName( MPIU_Object_alloc_t *objmem )
+{
+ return MPIU_Handle_get_kind_str(objmem->kind);
+}
#endif
#ifdef NEEDS_PRINT_HANDLE
More information about the mpich2-commits
mailing list