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; }
static int MPIDI_CH3I_Progress_delay(unsigned int completion_count) { int mpi_errno = MPI_SUCCESS; /* FIXME should be appropriately abstracted somehow */ # if defined(MPICH_IS_THREADED) && (MPIU_THREAD_GRANULARITY == MPIU_THREAD_GRANULARITY_GLOBAL) { while (completion_count == MPIDI_CH3I_progress_completion_count) { MPID_Thread_cond_wait(&MPIDI_CH3I_progress_completion_cond, &MPIR_ThreadInfo.global_mutex); } } # endif return mpi_errno; }