-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/init/async.c
        -:    0:Graph:async.gcno
        -:    0:Data:async.gcda
        -:    0:Runs:4382
        -:    0:Programs:1376
        -:    1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
        -:    2:/*
        -:    3: *  (C) 2001 by Argonne National Laboratory.
        -:    4: *      See COPYRIGHT in top-level directory.
        -:    5: */
        -:    6:
        -:    7:#include "mpiimpl.h"
        -:    8:#include "mpi_init.h"
        -:    9:#include "mpiu_thread.h"
        -:   10:
        -:   11:static MPI_Comm progress_comm;
        -:   12:static MPIU_Thread_id_t progress_thread_id;
        -:   13:static MPIU_Thread_mutex_t progress_mutex;
        -:   14:static MPIU_Thread_cond_t progress_cond;
        -:   15:static volatile int progress_thread_done = 0;
        -:   16:
        -:   17:#undef FUNCNAME
        -:   18:#define FUNCNAME MPIR_Init_async_thread
        -:   19:#undef FCNAME
        -:   20:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:   21:static void progress_fn(void * data)
    #####:   22:{
        -:   23:#if MPICH_THREAD_LEVEL >= MPI_THREAD_SERIALIZED
    #####:   24:    int mpi_errno = MPI_SUCCESS;
    #####:   25:    MPIU_THREADPRIV_DECL;
        -:   26:
        -:   27:    /* Explicitly add CS_ENTER/EXIT since this thread is created from
        -:   28:     * within an internal function and will call NMPI functions
        -:   29:     * directly. */
        -:   30:    /* FIXME: The CS_ENTER/EXIT code should be abstracted out
        -:   31:     * correctly, instead of relying on the #if protection here. */
        -:   32:#if MPIU_THREAD_GRANULARITY == MPIU_THREAD_GRANULARITY_GLOBAL
    #####:   33:    MPID_CS_ENTER();
        -:   34:#endif
        -:   35:
        -:   36:    /* FIXME: We assume that waiting on some request forces progress
        -:   37:     * on all requests. With fine-grained threads, will this still
        -:   38:     * work as expected? We can imagine an approach where a request on
        -:   39:     * a non-conflicting communicator would not touch the remaining
        -:   40:     * requests to avoid locking issues. Once the fine-grained threads
        -:   41:     * code is fully functional, we need to revisit this and, if
        -:   42:     * appropriate, either change what we do in this thread, or delete
        -:   43:     * this comment. */
        -:   44:
    #####:   45:    MPIU_THREADPRIV_GET;
        -:   46:
    #####:   47:    MPIR_Nest_incr();
    #####:   48:    mpi_errno = NMPI_Recv(NULL, 0, MPI_CHAR, 0, 0, progress_comm, MPI_STATUS_IGNORE);
    #####:   49:    MPIU_Assert(!mpi_errno);
    #####:   50:    MPIR_Nest_decr();
        -:   51:
        -:   52:    /* Send a signal to the main thread saying we are done */
    #####:   53:    MPIU_Thread_mutex_lock(&progress_mutex, &mpi_errno);
    #####:   54:    MPIU_Assert(!mpi_errno);
        -:   55:
    #####:   56:    progress_thread_done = 1;
        -:   57:
    #####:   58:    MPIU_Thread_mutex_unlock(&progress_mutex, &mpi_errno);
    #####:   59:    MPIU_Assert(!mpi_errno);
        -:   60:
    #####:   61:    MPIU_Thread_cond_signal(&progress_cond, &mpi_errno);
    #####:   62:    MPIU_Assert(!mpi_errno);
        -:   63:
        -:   64:#if MPIU_THREAD_GRANULARITY == MPIU_THREAD_GRANULARITY_GLOBAL
    #####:   65:    MPID_CS_EXIT();
        -:   66:#endif
        -:   67:
        -:   68:#endif /* MPICH_THREAD_LEVEL >= MPI_THREAD_SERIALIZED */
        -:   69:    return;
        -:   70:}
        -:   71:
        -:   72:#undef FUNCNAME
        -:   73:#define FUNCNAME MPIR_Init_async_thread
        -:   74:#undef FCNAME
        -:   75:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:   76:int MPIR_Init_async_thread(void)
    #####:   77:{
    #####:   78:    int mpi_errno = MPI_SUCCESS;
        -:   79:#if MPICH_THREAD_LEVEL >= MPI_THREAD_SERIALIZED
    #####:   80:    MPIU_THREADPRIV_DECL;
        -:   81:    MPID_MPI_STATE_DECL(MPID_STATE_MPIR_INIT_ASYNC_THREAD);
        -:   82:
        -:   83:    MPID_MPI_FUNC_ENTER(MPID_STATE_MPIR_INIT_ASYNC_THREAD);
        -:   84:
    #####:   85:    MPIU_THREADPRIV_GET;
        -:   86:
        -:   87:    /* Dup comm world for the progress thread */
    #####:   88:    MPIR_Nest_incr();
    #####:   89:    mpi_errno = NMPI_Comm_dup(MPI_COMM_SELF, &progress_comm);
    #####:   90:    MPIU_Assert(!mpi_errno);
    #####:   91:    MPIR_Nest_decr();
        -:   92:
    #####:   93:    MPIU_Thread_cond_create(&progress_cond, &mpi_errno);
    #####:   94:    MPIU_Assert(!mpi_errno);
        -:   95:
    #####:   96:    MPIU_Thread_mutex_create(&progress_mutex, &mpi_errno);
    #####:   97:    MPIU_Assert(!mpi_errno);
        -:   98:
    #####:   99:    MPIU_Thread_create((MPIU_Thread_func_t) progress_fn, NULL, &progress_thread_id, &mpi_errno);
    #####:  100:    MPIU_Assert(!mpi_errno);
        -:  101:
        -:  102:    MPID_MPI_FUNC_EXIT(MPID_STATE_MPIR_INIT_ASYNC_THREAD);
        -:  103:
        -:  104:#endif /* MPICH_THREAD_LEVEL >= MPI_THREAD_SERIALIZED */
    #####:  105:    return mpi_errno;
        -:  106:}
        -:  107:
        -:  108:#undef FUNCNAME
        -:  109:#define FUNCNAME MPIR_Finalize_async_thread
        -:  110:#undef FCNAME
        -:  111:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:  112:int MPIR_Finalize_async_thread(void)
    #####:  113:{
    #####:  114:    int mpi_errno = MPI_SUCCESS;
        -:  115:#if MPICH_THREAD_LEVEL >= MPI_THREAD_SERIALIZED
    #####:  116:    MPIU_THREADPRIV_DECL;
        -:  117:    MPID_MPI_STATE_DECL(MPID_STATE_MPIR_FINALIZE_ASYNC_THREAD);
        -:  118:
        -:  119:    MPID_MPI_FUNC_ENTER(MPID_STATE_MPIR_FINALIZE_ASYNC_THREAD);
        -:  120:
    #####:  121:    MPIU_THREADPRIV_GET;
        -:  122:
    #####:  123:    MPIR_Nest_incr();
    #####:  124:    mpi_errno = NMPI_Send(NULL, 0, MPI_CHAR, 0, 0, progress_comm);
    #####:  125:    MPIU_Assert(!mpi_errno);
    #####:  126:    MPIR_Nest_decr();
        -:  127:
        -:  128:#if MPIU_THREAD_GRANULARITY == MPIU_THREAD_GRANULARITY_GLOBAL
    #####:  129:    MPID_CS_EXIT();
        -:  130:#endif
        -:  131:
    #####:  132:    MPIU_Thread_mutex_lock(&progress_mutex, &mpi_errno);
    #####:  133:    MPIU_Assert(!mpi_errno);
        -:  134:
    #####:  135:    while (!progress_thread_done) {
    #####:  136:        MPIU_Thread_cond_wait(&progress_cond, &progress_mutex, &mpi_errno);
    #####:  137:        MPIU_Assert(!mpi_errno);
        -:  138:    }
        -:  139:
    #####:  140:    MPIU_Thread_mutex_unlock(&progress_mutex, &mpi_errno);
    #####:  141:    MPIU_Assert(!mpi_errno);
        -:  142:
        -:  143:#if MPIU_THREAD_GRANULARITY == MPIU_THREAD_GRANULARITY_GLOBAL
    #####:  144:    MPID_CS_ENTER();
        -:  145:#endif
        -:  146:
    #####:  147:    MPIU_Thread_cond_destroy(&progress_cond, &mpi_errno);
    #####:  148:    MPIU_Assert(!mpi_errno);
        -:  149:
    #####:  150:    MPIU_Thread_mutex_destroy(&progress_mutex, &mpi_errno);
    #####:  151:    MPIU_Assert(!mpi_errno);
        -:  152:
        -:  153:    MPID_MPI_FUNC_EXIT(MPID_STATE_MPIR_FINALIZE_ASYNC_THREAD);
        -:  154:
        -:  155:#endif /* MPICH_THREAD_LEVEL >= MPI_THREAD_SERIALIZED */
    #####:  156:    return mpi_errno;
        -:  157:}