int MPIR_Thread_CS_Finalize( void ) { MPIU_DBG_MSG(THREAD,TYPICAL,"Freeing global mutex and private storage"); #if MPIU_THREAD_GRANULARITY == MPIU_THREAD_GRANULARITY_GLOBAL /* There is a single, global lock, held for the duration of an MPI call */ MPID_Thread_mutex_destroy(&MPIR_ThreadInfo.global_mutex, NULL); #elif MPIU_THREAD_GRANULARITY == MPIU_THREAD_GRANULARITY_PER_OBJECT /* MPIU_THREAD_GRANULARITY_PER_OBJECT: There are multiple locks, * one for each logical class (e.g., each type of object) */ MPID_Thread_mutex_destroy(&MPIR_ThreadInfo.global_mutex, NULL); MPID_Thread_mutex_destroy(&MPIR_ThreadInfo.handle_mutex, NULL); MPID_Thread_mutex_destroy(&MPIR_ThreadInfo.msgq_mutex, NULL); MPID_Thread_mutex_destroy(&MPIR_ThreadInfo.completion_mutex, NULL); MPID_Thread_mutex_destroy(&MPIR_ThreadInfo.ctx_mutex, NULL); MPID_Thread_mutex_destroy(&MPIR_ThreadInfo.pmi_mutex, NULL); #elif MPIU_THREAD_GRANULARITY == MPIU_THREAD_GRANULARITY_LOCK_FREE /* Updates to shared data and access to shared services is handled without locks where ever possible. */ #error lock-free not yet implemented #elif MPIU_THREAD_GRANULARITY == MPIU_THREAD_GRANULARITY_SINGLE /* No thread support, make all operations a no-op */ #else #error Unrecognized thread granularity #endif MPIU_THREADPRIV_FINALIZE; return MPI_SUCCESS; }
int MPIR_Thread_CS_Finalize(void) { int err; MPL_DBG_MSG(MPIR_DBG_INIT, TYPICAL, "Freeing global mutex and private storage"); #if MPICH_THREAD_GRANULARITY == MPICH_THREAD_GRANULARITY__GLOBAL /* There is a single, global lock, held for the duration of an MPI call */ MPID_Thread_mutex_destroy(&MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX, &err); MPIR_Assert(err == 0); #elif MPICH_THREAD_GRANULARITY == MPICH_THREAD_GRANULARITY__POBJ /* MPICH_THREAD_GRANULARITY__POBJ: There are multiple locks, * one for each logical class (e.g., each type of object) */ MPID_Thread_mutex_destroy(&MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX, &err); MPIR_Assert(err == 0); MPID_Thread_mutex_destroy(&MPIR_THREAD_POBJ_HANDLE_MUTEX, &err); MPIR_Assert(err == 0); MPID_Thread_mutex_destroy(&MPIR_THREAD_POBJ_MSGQ_MUTEX, &err); MPIR_Assert(err == 0); MPID_Thread_mutex_destroy(&MPIR_THREAD_POBJ_COMPLETION_MUTEX, &err); MPIR_Assert(err == 0); MPID_Thread_mutex_destroy(&MPIR_THREAD_POBJ_CTX_MUTEX, &err); MPIR_Assert(err == 0); MPID_Thread_mutex_destroy(&MPIR_THREAD_POBJ_PMI_MUTEX, &err); MPIR_Assert(err == 0); #elif MPICH_THREAD_GRANULARITY == MPICH_THREAD_GRANULARITY__VCI MPID_Thread_mutex_destroy(&MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX, &err); MPIR_Assert(err == 0); MPID_Thread_mutex_destroy(&MPIR_THREAD_POBJ_HANDLE_MUTEX, &err); MPIR_Assert(err == 0); #elif MPICH_THREAD_GRANULARITY == MPICH_THREAD_GRANULARITY__LOCKFREE /* Updates to shared data and access to shared services is handled without locks where ever possible. */ #error lock-free not yet implemented #elif MPICH_THREAD_GRANULARITY == MPICH_THREAD_GRANULARITY__SINGLE /* No thread support, make all operations a no-op */ #else #error Unrecognized thread granularity #endif MPID_CS_finalize(); MPID_THREADPRIV_KEY_DESTROY; return MPI_SUCCESS; }
int MPIR_Finalize_async_thread(void) { int mpi_errno = MPI_SUCCESS; #if MPICH_THREAD_LEVEL == MPI_THREAD_MULTIPLE MPIR_Request *request_ptr = NULL; MPI_Request request; MPI_Status status; MPIR_FUNC_TERSE_STATE_DECL(MPID_STATE_MPIR_FINALIZE_ASYNC_THREAD); MPIR_FUNC_TERSE_ENTER(MPID_STATE_MPIR_FINALIZE_ASYNC_THREAD); mpi_errno = MPID_Isend(NULL, 0, MPI_CHAR, 0, WAKE_TAG, progress_comm_ptr, MPIR_CONTEXT_INTRA_PT2PT, &request_ptr); MPIR_Assert(!mpi_errno); request = request_ptr->handle; mpi_errno = MPIR_Wait_impl(&request, &status); MPIR_Assert(!mpi_errno); /* XXX DJG why is this unlock/lock necessary? Should we just YIELD here or later? */ MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); MPID_Thread_mutex_lock(&progress_mutex, &mpi_errno); MPIR_Assert(!mpi_errno); while (!progress_thread_done) { MPID_Thread_cond_wait(&progress_cond, &progress_mutex, &mpi_errno); MPIR_Assert(!mpi_errno); } MPID_Thread_mutex_unlock(&progress_mutex, &mpi_errno); MPIR_Assert(!mpi_errno); mpi_errno = MPIR_Comm_free_impl(progress_comm_ptr); MPIR_Assert(!mpi_errno); MPID_THREAD_CS_ENTER(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); MPID_Thread_cond_destroy(&progress_cond, &mpi_errno); MPIR_Assert(!mpi_errno); MPID_Thread_mutex_destroy(&progress_mutex, &mpi_errno); MPIR_Assert(!mpi_errno); MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPIR_FINALIZE_ASYNC_THREAD); #endif /* MPICH_THREAD_LEVEL == MPI_THREAD_MULTIPLE */ return mpi_errno; }