* try to handle MPI_{LONG,DOUBLE,SHORT}_INT better (despite the best
efforts of the MPI spec to screw this up)
* Add locking to accesses to the "sReqs" shadow-requests table
used to keep track of uncompleted MPI_Irecv's. This might
even mean the wrappers are thread-safe now :-)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5738 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/auxprogs/mpiwrap.c b/auxprogs/mpiwrap.c
index 28cef6a..c329fc0 100644
--- a/auxprogs/mpiwrap.c
+++ b/auxprogs/mpiwrap.c
@@ -451,11 +451,24 @@
/* Hmm. Perhaps it's a named struct? Unfortunately we can't
take them to bits so we have to do a really ugly hack, which
makes assumptions about how the MPI implementation has laid
- out these types.
+ out these types. At least Open MPI 1.0.1 appears to put
+ the 'val' field first.
*/
if (ty == MPI_LONG_INT) {
- typedef struct { long dbl; int loc; } Ty;
- f(base + offsetof(Ty,dbl), sizeof(long));
+ typedef struct { long val; int loc; } Ty;
+ f(base + offsetof(Ty,val), sizeof(long));
+ f(base + offsetof(Ty,loc), sizeof(int));
+ return;
+ }
+ if (ty == MPI_DOUBLE_INT) {
+ typedef struct { double val; int loc; } Ty;
+ f(base + offsetof(Ty,val), sizeof(double));
+ f(base + offsetof(Ty,loc), sizeof(int));
+ return;
+ }
+ if (ty == MPI_SHORT_INT) {
+ typedef struct { short val; int loc; } Ty;
+ f(base + offsetof(Ty,val), sizeof(short));
f(base + offsetof(Ty,loc), sizeof(int));
return;
}
@@ -643,7 +656,9 @@
}
-void walk_type_EXTERNALLY_VISIBLE
+/* Hook so it's visible from outside (can be handy to dlopen/dlsym
+ it) */
+void mpiwrap_walk_type_EXTERNALLY_VISIBLE
( void(*f)(void*,long), char* base, MPI_Datatype ty )
{
return walk_type(f, base, ty);
@@ -848,7 +863,17 @@
static ShadowRequest* sReqs = NULL;
static int sReqs_size = 0;
static int sReqs_used = 0;
-//static pthread_mutex_t sReqs_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t sReqs_lock = PTHREAD_MUTEX_INITIALIZER;
+
+#define LOCK_SREQS \
+ do { int pr = pthread_mutex_lock(&sReqs_lock); \
+ assert(pr == 0); \
+ } while (0)
+
+#define UNLOCK_SREQS \
+ do { int pr = pthread_mutex_unlock(&sReqs_lock); \
+ assert(pr == 0); \
+ } while (0)
/* Ensure the sReqs expandable array has at least one free slot, by
@@ -862,7 +887,7 @@
sReqs_size = sReqs_size==0 ? 2 : 2*sReqs_size;
sReqs2 = malloc( sReqs_size * sizeof(ShadowRequest) );
if (sReqs2 == NULL) {
- /* UNLOCK */
+ UNLOCK_SREQS;
barf("add_shadow_Request: malloc failed.\n");
}
for (i = 0; i < sReqs_used; i++)
@@ -882,14 +907,14 @@
{
ShadowRequest* ret = NULL;
int i;
- /* LOCK */
+ LOCK_SREQS;
for (i = 0; i < sReqs_used; i++) {
if (sReqs[i].inUse && eq_MPI_Request(sReqs[i].key,request)) {
ret = &sReqs[i];
break;
}
}
- /* UNLOCK */
+ UNLOCK_SREQS;
return ret;
}
@@ -899,14 +924,14 @@
static void delete_shadow_Request ( MPI_Request request )
{
int i;
- /* LOCK */
+ LOCK_SREQS;
for (i = 0; i < sReqs_used; i++) {
if (sReqs[i].inUse && eq_MPI_Request(sReqs[i].key,request)) {
sReqs[i].inUse = False;
break;
}
}
- /* UNLOCK */
+ UNLOCK_SREQS;
}
@@ -918,7 +943,7 @@
MPI_Datatype datatype )
{
int i, ix = -1;
- /* LOCK */
+ LOCK_SREQS;
assert(sReqs_used >= 0);
assert(sReqs_size >= 0);
assert(sReqs_used <= sReqs_size);
@@ -961,13 +986,15 @@
sReqs[ix].count = count;
sReqs[ix].datatype = datatype;
- /* UNLOCK */
+ UNLOCK_SREQS;
if (opt_verbosity > 1)
fprintf(stderr, "%s %5d: sReq+ 0x%lx -> b/c/d %p/%d/0x%lx [slot %d]\n",
preamble, my_pid, (unsigned long)request,
buf, count, (long)datatype, ix);
}
+#undef LOCK_SREQS
+#undef UNLOCK_SREQS
static void maybe_complete ( Bool error_in_status,
MPI_Request request_before,