/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
/*
*
* (C) 2009 by Argonne National Laboratory.
* See COPYRIGHT in top-level directory.
*/
/* This test repeatedly dups and frees communicators with multiple threads
* concurrently to stress the multithreaded aspects of the context ID allocation
* code.
*
* Thanks to IBM for providing the original version of this test */
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include "mpitest.h"
#include "mpithreadtest.h"
#ifndef NITER
#define NITER 12345
#endif /* ! NITER */
#ifndef NTHREADS
#define NTHREADS 4
#endif /* ! NTHREADS */
MTEST_THREAD_RETURN_TYPE do_thread(void *v);
MTEST_THREAD_RETURN_TYPE do_thread(void *v)
{
int x;
MPI_Comm comm = *(MPI_Comm *) v;
MPI_Comm newcomm;
for (x = 0; x < NITER; ++x) {
MPI_Comm_dup(comm, &newcomm);
MPI_Comm_free(&newcomm);
}
return (MTEST_THREAD_RETURN_TYPE) 0;
}
int main(int argc, char **argv)
{
int x;
int threaded;
int errs;
MPI_Comm comms[NTHREADS];
int num_threads_obtained = 1;
MTest_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &threaded);
if (threaded != MPI_THREAD_MULTIPLE) {
printf("unable to initialize with MPI_THREAD_MULTIPLE\n");
goto fn_fail;
}
for (x = 0; x < NTHREADS; ++x) {
MPI_Comm_dup(MPI_COMM_WORLD, &comms[x]);
if (x != 0) {
errs = MTest_Start_thread(do_thread, (void *) &comms[x]);
if (errs) {
/* attempt to continue with fewer threads, we may be on a
* thread-constrained platform like BG/P in DUAL mode */
MPI_Comm_free(&comms[x]);
break;
}
++num_threads_obtained;
}
}
if (num_threads_obtained <= 1) {
printf("unable to create any additional threads, exiting\n");
goto fn_fail;
}
do_thread((void *) &comms[0]); /* we are thread 0 */
errs = MTest_Join_threads();
if (errs) {
printf("error joining threads, errs=%d", errs);
goto fn_fail;
}
for (x = 0; x < num_threads_obtained; ++x) {
MPI_Comm_free(&comms[x]);
}
fn_exit:
MTest_Finalize(errs);
return MTestReturnValue(errs);
fn_fail:
errs = 1;
goto fn_exit;
}