Commit 1a0c3dbc authored by Pavan Balaji's avatar Pavan Balaji
Browse files

We always need the runtime thread-safety check.



Disabling runtime check for thread-safety is not a correct option.
This would cause memory allocation and string manipulation routines to
be unusable before the thread-safety level is set.  Fixes #1900.
Signed-off-by: default avatarMichael Blocksome <blocksom@us.ibm.com>
Signed-off-by: Rob Latham's avatarRob Latham <robl@mcs.anl.gov>
parent 99485af8
......@@ -486,9 +486,6 @@ AC_ARG_WITH(logging,
AC_HELP_STRING([--with-logging=name], [Specify the logging library for MPICH]),
[if test -z "$withval" ; then with_logging=rlog ; fi],with_logging=none)
dnl The default option needs to be defined in terms of a specific choice
dnl (runtime in this case). Note that the default choice is the same as
dnl runtime only for certain devices - not for every device.
AC_ARG_ENABLE(threads,
[ --enable-threads=level - Control the level of thread support in the
MPICH implementation. The following levels
......@@ -496,14 +493,8 @@ AC_ARG_ENABLE(threads,
single - No threads (MPI_THREAD_SINGLE)
funneled - Only the main thread calls MPI (MPI_THREAD_FUNNELED)
serialized - User serializes calls to MPI (MPI_THREAD_SERIALIZED)
runtime - The level of thread support is determined by
the arguments to MPI_Init_thread, with
MPI_THREAD_MULTIPLE available. The default option
for many communication devices.
multiple - Fully multi-threaded (MPI_THREAD_MULTIPLE) always.
DO NOT select this option. The option runtime is more
efficient and also supports thread_multiple.
(multiple aliased to runtime now)
multiple - Fully multi-threaded (MPI_THREAD_MULTIPLE)
runtime - Alias to "multiple"
See also the --enable-thread-cs option for controlling the granularity of
the concurrency inside of the library
......@@ -1278,7 +1269,10 @@ fi
#
# Threads must be supported by the device. First, set the default to
# be the highest supported by the device
# "runtime" was an old (now deprecated) option; just map it to multiple
if test "$enable_threads" = "runtime" ; then enable_threads=multiple ; fi
if test "$enable_threads" = "yes" ; then enable_threads=default ; fi
if test "$enable_threads" = "no" ; then enable_threads=single ; fi
if test "$enable_threads" = default ; then
# XXX DJG bug is here, PREREQ is not being used right now
if test -n "$MPID_MAX_THREAD_LEVEL" ; then
......@@ -1286,7 +1280,7 @@ if test "$enable_threads" = default ; then
MPI_THREAD_SINGLE) enable_threads=single ;;
MPI_THREAD_FUNNELED) enable_threads=funneled ;;
MPI_THREAD_SERIALIZED) enable_threads=serialized ;;
MPI_THREAD_MULTIPLE) enable_threads=runtime ;;
MPI_THREAD_MULTIPLE) enable_threads=multiple ;;
*) AC_MSG_ERROR([Unrecognized thread level from device $MPID_MAX_THREAD_LEVEL])
;;
esac
......@@ -1295,18 +1289,6 @@ if test "$enable_threads" = default ; then
fi
fi
if test "$enable_threads" = "default" ; then
enable_threads=runtime
elif test "$enable_threads" = "no" ; then
enable_threads=single
fi
# Runtime is an alias for multiple with an additional value
if test "$enable_threads" = "runtime" ; then
AC_DEFINE(HAVE_RUNTIME_THREADCHECK,1,[Define if MPI supports MPI_THREAD_MULTIPLE with a runtime check for thread level])
enable_threads=multiple
fi
MPICH_THREAD_LEVEL=MPI_THREAD_FUNNELED
case "$enable_threads" in
single)
......
......@@ -72,10 +72,11 @@ typedef struct MPICH_ThreadInfo_t {
# endif /* !TLS */
MPID_Thread_id_t master_thread; /* Thread that started MPI */
#endif
#ifdef HAVE_RUNTIME_THREADCHECK
#if defined MPICH_IS_THREADED
int isThreaded; /* Set to true if user requested
THREAD_MULTIPLE */
#endif
#endif /* MPICH_IS_THREADED */
/* Define the mutex values used for each kind of implementation */
#if MPIU_THREAD_GRANULARITY == MPIU_THREAD_GRANULARITY_GLOBAL || \
......@@ -107,11 +108,6 @@ extern MPICH_ThreadInfo_t MPIR_ThreadInfo;
#else /* defined(MPICH_IS_THREADED) */
/* We want to avoid the overhead of the thread call if we're in the
runtime state and threads are not in use. In that case, MPIR_Thread
is still a pointer but it was already allocated in InitThread */
#ifdef HAVE_RUNTIME_THREADCHECK
#define MPIU_THREAD_CHECK_BEGIN if (MPIR_ThreadInfo.isThreaded) {
#define MPIU_THREAD_CHECK_END }
/* This macro used to take an argument of one or more statements that
......@@ -124,14 +120,6 @@ extern MPICH_ThreadInfo_t MPIR_ThreadInfo;
* completely eliminate unnecessary if's. */
#define MPIU_ISTHREADED (MPIR_ThreadInfo.isThreaded)
#else /* !defined(HAVE_RUNTIME_THREADCHECK) */
#define MPIU_THREAD_CHECK_BEGIN
#define MPIU_THREAD_CHECK_END
#define MPIU_ISTHREADED (1)
#endif /* HAVE_RUNTIME_THREADCHECK */
#endif /* MPICH_IS_THREADED */
/* ------------------------------------------------------------------------- */
......@@ -218,7 +206,6 @@ extern MPICH_PerThread_t MPIR_Thread;
void MPIR_CleanupThreadStorage(void *a);
#if !defined(MPIU_TLS_SPECIFIER)
# if defined(HAVE_RUNTIME_THREADCHECK)
/* In the case where the thread level is set in MPI_Init_thread, we
need a blended version of the non-threaded and the thread-multiple
definitions.
......@@ -268,36 +255,6 @@ extern MPICH_PerThread_t MPIR_ThreadSingle;
} \
} while (0)
# else /* unconditional thread multiple */
/* We initialize the MPIR_Thread pointer to null so that we need call the
* routine to get the thread-private storage only once in an invocation of a
* routine. */
#define MPIU_THREADPRIV_INITKEY \
do { \
int err_; \
MPID_Thread_tls_create(MPIR_CleanupThreadStorage,&MPIR_ThreadInfo.thread_storage,&err_); \
MPIU_Assert(err_ == 0); \
} while (0)
#define MPIU_THREADPRIV_INIT \
do { \
MPIR_Thread = (MPICH_PerThread_t *) MPIU_Calloc(1, sizeof(MPICH_PerThread_t)); \
MPIU_Assert(MPIR_Thread); \
MPID_Thread_tls_set(&MPIR_ThreadInfo.thread_storage, (void *)MPIR_Thread); \
} while (0)
#define MPIU_THREADPRIV_GET \
do { \
if (!MPIR_Thread) { \
MPID_Thread_tls_get(&MPIR_ThreadInfo.thread_storage, &MPIR_Thread); \
if (!MPIR_Thread) { \
MPIU_THREADPRIV_INIT; /* subtle, sets MPIR_Thread */ \
} \
MPIU_Assert(MPIR_Thread); \
} \
} while (0)
# endif /* runtime vs. unconditional */
/* common definitions when using MPID_Thread-based TLS */
#define MPIU_THREADPRIV_DECL MPICH_PerThread_t *MPIR_Thread=NULL
#define MPIU_THREADPRIV_FIELD(a_) (MPIR_Thread->a_)
......
......@@ -1363,14 +1363,9 @@ static inline int MPIR_T_is_initialized() {
extern void MPIR_T_strncpy(char *dst, const char *src, int *len);
/* Stuffs to support multithreaded MPI_T */
#ifdef HAVE_RUNTIME_THREADCHECK
extern int MPIR_T_is_threaded;
#define MPIR_T_THREAD_CHECK_BEGIN if (MPIR_T_is_threaded) {
#define MPIR_T_THREAD_CHECK_END }
#else /* !HAVE_RUNTIME_THREADCHECK */
#define MPIR_T_THREAD_CHECK_BEGIN
#define MPIR_T_THREAD_CHECK_END
#endif
#ifdef MPICH_IS_THREADED
extern MPIU_Thread_mutex_t mpi_t_mutex;
......
......@@ -146,12 +146,9 @@ int MPI_Init( int *argc, char ***argv )
* mutexes are not initialized yet, and we don't want to
* accidentally use them before they are initialized. We will
* reset this value once it is properly initialized. */
/* FIXME: This only works when runtime thread-safety is enabled.
* When we use configure-time thread-levels, we might still have a
* problem. */
#ifdef HAVE_RUNTIME_THREADCHECK
#if defined MPICH_IS_THREADED
MPIR_ThreadInfo.isThreaded = 0;
#endif
#endif /* MPICH_IS_THREADED */
MPIR_T_env_init();
......
......@@ -160,7 +160,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
MPICH_PerThread_t MPIR_Thread = { 0 };
#elif defined(MPIU_TLS_SPECIFIER)
MPIU_TLS_SPECIFIER MPICH_PerThread_t MPIR_Thread = { 0 };
#elif defined(HAVE_RUNTIME_THREADCHECK)
#else
/* If we may be single threaded, we need a preallocated version to use
if we are single threaded case */
MPICH_PerThread_t MPIR_ThreadSingle = { 0 };
......@@ -302,9 +302,9 @@ int MPIR_Init_thread(int * argc, char ***argv, int required, int * provided)
/* For any code in the device that wants to check for runtime
decisions on the value of isThreaded, set a provisional
value here. We could let the MPID_Init routine override this */
#ifdef HAVE_RUNTIME_THREADCHECK
#if defined MPICH_IS_THREADED
MPIR_ThreadInfo.isThreaded = required == MPI_THREAD_MULTIPLE;
#endif
#endif /* MPICH_IS_THREADED */
MPIU_THREAD_CS_INIT;
......@@ -479,9 +479,9 @@ int MPIR_Init_thread(int * argc, char ***argv, int required, int * provided)
/* Capture the level of thread support provided */
MPIR_ThreadInfo.thread_provided = thread_provided;
if (provided) *provided = thread_provided;
#ifdef HAVE_RUNTIME_THREADCHECK
#if defined MPICH_IS_THREADED
MPIR_ThreadInfo.isThreaded = (thread_provided == MPI_THREAD_MULTIPLE);
#endif
#endif /* MPICH_IS_THREADED */
/* FIXME: Define these in the interface. Does Timer init belong here? */
MPIU_dbg_init(MPIR_Process.comm_world->rank);
......@@ -618,12 +618,9 @@ int MPI_Init_thread( int *argc, char ***argv, int required, int *provided )
* mutexes are not initialized yet, and we don't want to
* accidentally use them before they are initialized. We will
* reset this value once it is properly initialized. */
/* FIXME: This only works when runtime thread-safety is enabled.
* When we use configure-time thread-levels, we might still have a
* problem. */
#ifdef HAVE_RUNTIME_THREADCHECK
#if defined MPICH_IS_THREADED
MPIR_ThreadInfo.isThreaded = 0;
#endif
#endif /* MPICH_IS_THREADED */
MPIR_T_env_init();
......
......@@ -10,9 +10,6 @@ int MPIR_T_init_balance = 0;
#ifdef MPICH_IS_THREADED
MPIU_Thread_mutex_t mpi_t_mutex;
#endif
#ifdef HAVE_RUNTIME_THREADCHECK
int MPIR_T_is_threaded;
#endif
......
......@@ -118,9 +118,9 @@ int MPI_T_init_thread(int required, int *provided)
/* ... body of routine ... */
#ifdef HAVE_RUNTIME_THREADCHECK
#if defined MPICH_IS_THREADED
MPIR_T_is_threaded = (required == MPI_THREAD_MULTIPLE);
#endif
#endif /* MPICH_IS_THREADED */
if (provided != NULL) {
/* This must be min(required,MPICH_THREAD_LEVEL) if runtime
......
......@@ -878,11 +878,7 @@ MPID_nem_mpich_blocking_recv(MPID_nem_cell_ptr_t *cell, int *in_fbox, int comple
#ifdef MPICH_IS_THREADED
/* We should never enter this function in a multithreaded app */
#ifdef HAVE_RUNTIME_THREADCHECK
MPIU_Assert(!MPIR_ThreadInfo.isThreaded);
#else
MPIU_Assert(0);
#endif
#endif
#ifdef USE_FASTBOX
......
......@@ -350,11 +350,7 @@ int MPIDI_CH3I_Progress (MPID_Progress_state *progress_state, int is_blocking)
/* check queue */
if (MPID_nem_safe_to_block_recv() && is_blocking
#ifdef MPICH_IS_THREADED
#ifdef HAVE_RUNTIME_THREADCHECK
&& !MPIR_ThreadInfo.isThreaded
#else
&& 0
#endif
#endif
)
{
......
......@@ -188,7 +188,6 @@ static int MPIDI_CH3i_Progress_wait(MPID_Progress_state * progress_state)
/* The logic for this case is just complicated enough that
we write separate code for each possibility */
# ifdef HAVE_RUNTIME_THREADCHECK
if (MPIR_ThreadInfo.isThreaded) {
MPIDI_CH3I_progress_blocked = TRUE;
mpi_errno = MPIDU_Sock_wait(MPIDI_CH3I_sock_set,
......@@ -200,13 +199,6 @@ static int MPIDI_CH3i_Progress_wait(MPID_Progress_state * progress_state)
mpi_errno = MPIDU_Sock_wait(MPIDI_CH3I_sock_set,
MPIDU_SOCK_INFINITE_TIME, &event);
}
# else
MPIDI_CH3I_progress_blocked = TRUE;
mpi_errno = MPIDU_Sock_wait(MPIDI_CH3I_sock_set,
MPIDU_SOCK_INFINITE_TIME, &event);
MPIDI_CH3I_progress_blocked = FALSE;
MPIDI_CH3I_progress_wakeup_signalled = FALSE;
# endif /* HAVE_RUNTIME_THREADCHECK */
# else
mpi_errno = MPIDU_Sock_wait(MPIDI_CH3I_sock_set,
......
......@@ -118,7 +118,6 @@ int MPIDU_Sock_wait(struct MPIDU_Sock_set * sock_set, int millisecond_timeout,
just use the same code as above. Otherwise, use
multithreaded code (and we don't then need the
MPIU_THREAD_CHECK_BEGIN/END macros) */
#ifdef HAVE_RUNTIME_THREADCHECK
if (!MPIR_ThreadInfo.isThreaded) {
MPIDI_FUNC_ENTER(MPID_STATE_POLL);
n_fds = poll(sock_set->pollfds, sock_set->poll_array_elems,
......@@ -126,7 +125,6 @@ int MPIDU_Sock_wait(struct MPIDU_Sock_set * sock_set, int millisecond_timeout,
MPIDI_FUNC_EXIT(MPID_STATE_POLL);
}
else
#endif
{
/*
* First try a non-blocking poll to see if any immediate
......
......@@ -46,9 +46,6 @@
#if (MPICH_THREAD_LEVEL != MPI_THREAD_MULTIPLE)
#error MPICH_THREAD_LEVEL should be MPI_THREAD_MULTIPLE
#endif
#ifndef HAVE_RUNTIME_THREADCHECK
#error Need HAVE_RUNTIME_THREADCHECK
#endif
#define MPIU_THREAD_CS_INIT ({ MPIDI_Mutex_initialize(); })
#define MPIU_THREAD_CS_FINALIZE
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment