-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/pt2pt/waitany.c
        -:    0:Graph:waitany.gcno
        -:    0:Data:waitany.gcda
        -:    0:Runs:643
        -:    0:Programs:117
        -:    1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
        -:    2:/*
        -:    3: *
        -:    4: *  (C) 2001 by Argonne National Laboratory.
        -:    5: *      See COPYRIGHT in top-level directory.
        -:    6: */
        -:    7:
        -:    8:#include "mpiimpl.h"
        -:    9:
        -:   10:#if !defined(MPID_REQUEST_PTR_ARRAY_SIZE)
        -:   11:#define MPID_REQUEST_PTR_ARRAY_SIZE 16
        -:   12:#endif
        -:   13:
        -:   14:/* -- Begin Profiling Symbol Block for routine MPI_Waitany */
        -:   15:#if defined(HAVE_PRAGMA_WEAK)
        -:   16:#pragma weak MPI_Waitany = PMPI_Waitany
        -:   17:#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
        -:   18:#pragma _HP_SECONDARY_DEF PMPI_Waitany  MPI_Waitany
        -:   19:#elif defined(HAVE_PRAGMA_CRI_DUP)
        -:   20:#pragma _CRI duplicate MPI_Waitany as PMPI_Waitany
        -:   21:#endif
        -:   22:/* -- End Profiling Symbol Block */
        -:   23:
        -:   24:/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
        -:   25:   the MPI routines */
        -:   26:#ifndef MPICH_MPI_FROM_PMPI
        -:   27:#undef MPI_Waitany
        -:   28:#define MPI_Waitany PMPI_Waitany
        -:   29:
        -:   30:#endif
        -:   31:
        -:   32:#undef FUNCNAME
        -:   33:#define FUNCNAME MPI_Waitany
        -:   34:
        -:   35:/*@
        -:   36:    MPI_Waitany - Waits for any specified MPI Request to complete
        -:   37:
        -:   38:Input Parameters:
        -:   39:+ count - list length (integer) 
        -:   40:- array_of_requests - array of requests (array of handles) 
        -:   41:
        -:   42:Output Parameters:
        -:   43:+ index - index of handle for operation that completed (integer).  In the
        -:   44:range '0' to 'count-1'.  In Fortran, the range is '1' to 'count'.
        -:   45:- status - status object (Status).  May be 'MPI_STATUS_IGNORE'.
        -:   46:
        -:   47:Notes:
        -:   48:If all of the requests are 'MPI_REQUEST_NULL', then 'index' is returned as 
        -:   49:'MPI_UNDEFINED', and 'status' is returned as an empty status.
        -:   50:
        -:   51:While it is possible to list a request handle more than once in the
        -:   52:array_of_requests, such an action is considered erroneous and may cause the
        -:   53:program to unexecpectedly terminate or produce incorrect results.
        -:   54:
        -:   55:.N waitstatus
        -:   56:
        -:   57:.N ThreadSafe
        -:   58:
        -:   59:.N Fortran
        -:   60:
        -:   61:.N Errors
        -:   62:.N MPI_SUCCESS
        -:   63:.N MPI_ERR_REQUEST
        -:   64:.N MPI_ERR_ARG
        -:   65:@*/
        -:   66:int MPI_Waitany(int count, MPI_Request array_of_requests[], int *index, 
        -:   67:		MPI_Status *status)
     3362:   68:{
        -:   69:    static const char FCNAME[] = "MPI_Waitany";
        -:   70:    MPID_Request * request_ptr_array[MPID_REQUEST_PTR_ARRAY_SIZE];
     3362:   71:    MPID_Request ** request_ptrs = request_ptr_array;
        -:   72:    MPID_Progress_state progress_state;
        -:   73:    int i;
        -:   74:    int n_inactive;
        -:   75:    int active_flag;
        -:   76:    int init_req_array;
        -:   77:    int found_nonnull_req;
     3362:   78:    int mpi_errno = MPI_SUCCESS;
     3362:   79:    MPIU_CHKLMEM_DECL(1);
        -:   80:    MPID_MPI_STATE_DECL(MPID_STATE_MPI_WAITANY);
        -:   81:
     3362:   82:    MPIR_ERRTEST_INITIALIZED_ORDIE();
        -:   83:    
        -:   84:    MPIU_THREAD_CS_ENTER(ALLFUNC,);
        -:   85:    MPID_MPI_PT2PT_FUNC_ENTER(MPID_STATE_MPI_WAITANY);
        -:   86:
        -:   87:    /* Check the arguments */
        -:   88:#   ifdef HAVE_ERROR_CHECKING
        -:   89:    {
        -:   90:        MPID_BEGIN_ERROR_CHECKS;
        -:   91:        {
     3362:   92:	    MPIR_ERRTEST_COUNT(count, mpi_errno);
     3362:   93:            if (mpi_errno != MPI_SUCCESS) goto fn_fail;
        -:   94:
     3362:   95:	    if (count != 0) {
     3361:   96:		MPIR_ERRTEST_ARGNULL(array_of_requests, "array_of_requests", mpi_errno);
        -:   97:		/* NOTE: MPI_STATUS_IGNORE != NULL */
     3361:   98:		MPIR_ERRTEST_ARGNULL(status, "status", mpi_errno);
        -:   99:	    }
     3362:  100:	    MPIR_ERRTEST_ARGNULL(index, "index", mpi_errno);
     3362:  101:	    if (mpi_errno != MPI_SUCCESS) goto fn_fail;
        -:  102:	}
        -:  103:        MPID_END_ERROR_CHECKS;
        -:  104:    }
        -:  105:#   endif /* HAVE_ERROR_CHECKING */
        -:  106:    
        -:  107:    /* ... body of routine ...  */
        -:  108:    
        -:  109:    /* Convert MPI request handles to a request object pointers */
     3362:  110:    if (count > MPID_REQUEST_PTR_ARRAY_SIZE)
        -:  111:    {
      321:  112:	MPIU_CHKLMEM_MALLOC_ORJUMP(request_ptrs, MPID_Request **, count * sizeof(MPID_Request *), mpi_errno, "request pointers");
        -:  113:    }
        -:  114:
     3362:  115:    n_inactive = 0;
     3362:  116:    init_req_array = TRUE;
     3362:  117:    found_nonnull_req = FALSE;
        -:  118:    
     3362:  119:    MPID_Progress_start(&progress_state);
        -:  120:    for(;;)
        -:  121:    {
    35576:  122:	for (i = 0; i < count; i++)
        -:  123:	{
    33896:  124:            if (init_req_array)
        -:  125:            {   
        -:  126:#ifdef HAVE_ERROR_CHECKING
        -:  127:                MPID_BEGIN_ERROR_CHECKS;
        -:  128:                {
    25619:  129:                    MPIR_ERRTEST_REQUEST_OR_NULL(array_of_requests[i], mpi_errno);
    25619:  130:                    if (mpi_errno != MPI_SUCCESS) goto fn_progress_end_fail;
        -:  131:                }
        -:  132:                MPID_END_ERROR_CHECKS;
        -:  133:#endif /* HAVE_ERROR_CHECKING */
    25619:  134:                if (array_of_requests[i] != MPI_REQUEST_NULL)
        -:  135:                {
    18761:  136:                    MPID_Request_get_ptr(array_of_requests[i], request_ptrs[i]);
        -:  137:                    /* Validate object pointers if error checking is enabled */
        -:  138:#ifdef HAVE_ERROR_CHECKING
        -:  139:                    {
        -:  140:                        MPID_BEGIN_ERROR_CHECKS;
        -:  141:                        {
    18761:  142:                            MPID_Request_valid_ptr( request_ptrs[i], mpi_errno );
    18761:  143:                            if (mpi_errno != MPI_SUCCESS) goto fn_progress_end_fail;
        -:  144:                        }
        -:  145:                        MPID_END_ERROR_CHECKS;
        -:  146:                    }
        -:  147:#endif	    
        -:  148:                }
        -:  149:                else
        -:  150:                {
     6858:  151:                    request_ptrs[i] = NULL;
     6858:  152:                    ++n_inactive;
        -:  153:                }
        -:  154:            }
    33896:  155:            if (request_ptrs[i] == NULL)
    13459:  156:                continue;
        -:  157:            /* we found at least one non-null request */
    20437:  158:            found_nonnull_req = TRUE;
        -:  159:            
    20437:  160:	    if (request_ptrs[i]->kind == MPID_UREQUEST && request_ptrs[i]->poll_fn != NULL)
        -:  161:	    {
        -:  162:                /* this is a generalized request; make progress on it */
    #####:  163:		mpi_errno = (request_ptrs[i]->poll_fn)(request_ptrs[i]->grequest_extra_state, status);
    #####:  164:		if (mpi_errno != MPI_SUCCESS) goto fn_progress_end_fail;
        -:  165:	    }
    20437:  166:	    if (*request_ptrs[i]->cc_ptr == 0)
        -:  167:	    {
    11031:  168:		mpi_errno = MPIR_Request_complete(&array_of_requests[i], 
        -:  169:						  request_ptrs[i], status, 
        -:  170:						  &active_flag);
    11031:  171:		if (active_flag)
        -:  172:		{
     3355:  173:		    *index = i;
     3355:  174:		    goto break_l1;
        -:  175:		}
        -:  176:		else
        -:  177:		{
     7676:  178:		    ++n_inactive;
     7676:  179:		    request_ptrs[i] = NULL;
        -:  180:
     7676:  181:		    if (n_inactive == count)
        -:  182:		    {
        2:  183:			*index = MPI_UNDEFINED;
        -:  184:			/* status is set to empty by MPIR_Request_complete */
        2:  185:			goto break_l1;
        -:  186:		    }
        -:  187:		}
        -:  188:	    }
        -:  189:	}
     1680:  190:        init_req_array = FALSE;
        -:  191:
     1680:  192:        if (!found_nonnull_req)
        -:  193:        {
        -:  194:            /* all requests were NULL */
        5:  195:            *index = MPI_UNDEFINED;
        5:  196:            if (status != NULL)    /* could be null if count=0 */
        5:  197:                MPIR_Status_set_empty(status);
        -:  198:            goto break_l1;
        -:  199:        }
        -:  200:
     1675:  201:	mpi_errno = MPID_Progress_wait(&progress_state);
     1675:  202:	if (mpi_errno != MPI_SUCCESS) goto fn_progress_end_fail;
        -:  203:    }
     3362:  204:  break_l1:
        -:  205:    MPID_Progress_end(&progress_state);
        -:  206:
        -:  207:    /* ... end of body of routine ... */
        -:  208:    
     3362:  209:  fn_exit:
     3362:  210:    if (count > MPID_REQUEST_PTR_ARRAY_SIZE)
        -:  211:    {
      321:  212:	MPIU_CHKLMEM_FREEALL();
        -:  213:    }
        -:  214:
        -:  215:    MPID_MPI_PT2PT_FUNC_EXIT(MPID_STATE_MPI_WAITANY);
        -:  216:    MPIU_THREAD_CS_EXIT(ALLFUNC,);
     3362:  217:    return mpi_errno;
        -:  218:
    #####:  219:  fn_progress_end_fail:
        -:  220:    MPID_Progress_end(&progress_state);
        -:  221:
    #####:  222:  fn_fail:
        -:  223:    /* --BEGIN ERROR HANDLING-- */
        -:  224:#ifdef HAVE_ERROR_CHECKING
    #####:  225:    mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, 
        -:  226:				     FCNAME, __LINE__, MPI_ERR_OTHER,
        -:  227:				     "**mpi_waitany", 
        -:  228:				     "**mpi_waitany %d %p %p %p", 
        -:  229:				     count, array_of_requests, index, status);
        -:  230:#endif
    #####:  231:    mpi_errno = MPIR_Err_return_comm(NULL, FCNAME, mpi_errno);
    #####:  232:    goto fn_exit;
        -:  233:    /* --END ERROR HANDLING-- */
        -:  234:}