-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/pt2pt/waitany.c
        -:    0:Graph:waitany.gcno
        -:    0:Data:waitany.gcda
        -:    0:Runs:649
        -:    0:Programs:186
        -:    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)
     3410:   68:{
        -:   69:    static const char FCNAME[] = "MPI_Waitany";
        -:   70:    MPID_Request * request_ptr_array[MPID_REQUEST_PTR_ARRAY_SIZE];
     3410:   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;
     3410:   78:    int mpi_errno = MPI_SUCCESS;
     3410:   79:    MPIU_CHKLMEM_DECL(1);
     3410:   80:    MPIU_THREADPRIV_DECL;
        -:   81:    MPID_MPI_STATE_DECL(MPID_STATE_MPI_WAITANY);
        -:   82:
     3410:   83:    MPIR_ERRTEST_INITIALIZED_ORDIE();
        -:   84:    
     3410:   85:    MPIU_THREAD_CS_ENTER(ALLFUNC,);
        -:   86:    MPID_MPI_PT2PT_FUNC_ENTER(MPID_STATE_MPI_WAITANY);
        -:   87:
        -:   88:    /* Check the arguments */
        -:   89:#   ifdef HAVE_ERROR_CHECKING
        -:   90:    {
        -:   91:        MPID_BEGIN_ERROR_CHECKS;
        -:   92:        {
     3410:   93:	    MPIR_ERRTEST_COUNT(count, mpi_errno);
     3410:   94:            if (mpi_errno != MPI_SUCCESS) goto fn_fail;
        -:   95:
     3410:   96:	    if (count != 0) {
     3409:   97:		MPIR_ERRTEST_ARGNULL(array_of_requests, "array_of_requests", mpi_errno);
        -:   98:		/* NOTE: MPI_STATUS_IGNORE != NULL */
     3409:   99:		MPIR_ERRTEST_ARGNULL(status, "status", mpi_errno);
        -:  100:	    }
     3410:  101:	    MPIR_ERRTEST_ARGNULL(index, "index", mpi_errno);
     3410:  102:	    if (mpi_errno != MPI_SUCCESS) goto fn_fail;
        -:  103:	}
        -:  104:        MPID_END_ERROR_CHECKS;
        -:  105:    }
        -:  106:#   endif /* HAVE_ERROR_CHECKING */
        -:  107:    
        -:  108:    /* ... body of routine ...  */
        -:  109:    
        -:  110:    /* Convert MPI request handles to a request object pointers */
     3410:  111:    if (count > MPID_REQUEST_PTR_ARRAY_SIZE)
        -:  112:    {
      351:  113:	MPIU_CHKLMEM_MALLOC_ORJUMP(request_ptrs, MPID_Request **, count * sizeof(MPID_Request *), mpi_errno, "request pointers");
        -:  114:    }
        -:  115:
     3410:  116:    n_inactive = 0;
     3410:  117:    init_req_array = TRUE;
     3410:  118:    found_nonnull_req = FALSE;
        -:  119:    
     3410:  120:    MPID_Progress_start(&progress_state);
        -:  121:    for(;;)
        -:  122:    {
    38352:  123:	for (i = 0; i < count; i++)
        -:  124:	{
    36608:  125:            if (init_req_array)
        -:  126:            {   
        -:  127:#ifdef HAVE_ERROR_CHECKING
        -:  128:                MPID_BEGIN_ERROR_CHECKS;
        -:  129:                {
    26990:  130:                    MPIR_ERRTEST_ARRAYREQUEST_OR_NULL(array_of_requests[i], 
        -:  131:						      i, mpi_errno);
    26990:  132:                    if (mpi_errno != MPI_SUCCESS) goto fn_progress_end_fail;
        -:  133:                }
        -:  134:                MPID_END_ERROR_CHECKS;
        -:  135:#endif /* HAVE_ERROR_CHECKING */
    26990:  136:                if (array_of_requests[i] != MPI_REQUEST_NULL)
        -:  137:                {
    19685:  138:                    MPID_Request_get_ptr(array_of_requests[i], request_ptrs[i]);
        -:  139:                    /* Validate object pointers if error checking is enabled */
        -:  140:#ifdef HAVE_ERROR_CHECKING
        -:  141:                    {
        -:  142:                        MPID_BEGIN_ERROR_CHECKS;
        -:  143:                        {
    19685:  144:                            MPID_Request_valid_ptr( request_ptrs[i], mpi_errno );
    19685:  145:                            if (mpi_errno != MPI_SUCCESS) goto fn_progress_end_fail;
        -:  146:                        }
        -:  147:                        MPID_END_ERROR_CHECKS;
        -:  148:                    }
        -:  149:#endif	    
        -:  150:                }
        -:  151:                else
        -:  152:                {
     7305:  153:                    request_ptrs[i] = NULL;
     7305:  154:                    ++n_inactive;
        -:  155:                }
        -:  156:            }
    36608:  157:            if (request_ptrs[i] == NULL)
    15187:  158:                continue;
        -:  159:            /* we found at least one non-null request */
    21421:  160:            found_nonnull_req = TRUE;
        -:  161:            
    21421:  162:	    if (request_ptrs[i]->kind == MPID_UREQUEST && request_ptrs[i]->poll_fn != NULL)
        -:  163:	    {
        -:  164:                /* this is a generalized request; make progress on it */
        4:  165:		mpi_errno = (request_ptrs[i]->poll_fn)(request_ptrs[i]->grequest_extra_state, status);
        4:  166:		if (mpi_errno != MPI_SUCCESS) goto fn_progress_end_fail;
        -:  167:	    }
    21421:  168:	    if (*request_ptrs[i]->cc_ptr == 0)
        -:  169:	    {
    11098:  170:		mpi_errno = MPIR_Request_complete(&array_of_requests[i], 
        -:  171:						  request_ptrs[i], status, 
        -:  172:						  &active_flag);
    11098:  173:		if (active_flag)
        -:  174:		{
     3399:  175:		    *index = i;
     3399:  176:		    goto break_l1;
        -:  177:		}
        -:  178:		else
        -:  179:		{
     7699:  180:		    ++n_inactive;
     7699:  181:		    request_ptrs[i] = NULL;
        -:  182:
     7699:  183:		    if (n_inactive == count)
        -:  184:		    {
        2:  185:			*index = MPI_UNDEFINED;
        -:  186:			/* status is set to empty by MPIR_Request_complete */
        2:  187:			goto break_l1;
        -:  188:		    }
        -:  189:		}
        -:  190:	    }
        -:  191:	}
     1744:  192:        init_req_array = FALSE;
        -:  193:
     1744:  194:        if (!found_nonnull_req)
        -:  195:        {
        -:  196:            /* all requests were NULL */
        9:  197:            *index = MPI_UNDEFINED;
        9:  198:            if (status != NULL)    /* could be null if count=0 */
        9:  199:                MPIR_Status_set_empty(status);
        -:  200:            goto break_l1;
        -:  201:        }
        -:  202:
     1735:  203:	mpi_errno = MPID_Progress_wait(&progress_state);
     1735:  204:	if (mpi_errno != MPI_SUCCESS) goto fn_progress_end_fail;
        -:  205:    }
     3410:  206:  break_l1:
        -:  207:    MPID_Progress_end(&progress_state);
        -:  208:
        -:  209:    /* ... end of body of routine ... */
        -:  210:    
     3410:  211:  fn_exit:
     3410:  212:    if (count > MPID_REQUEST_PTR_ARRAY_SIZE)
        -:  213:    {
      351:  214:	MPIU_CHKLMEM_FREEALL();
        -:  215:    }
        -:  216:
        -:  217:    MPID_MPI_PT2PT_FUNC_EXIT(MPID_STATE_MPI_WAITANY);
     3410:  218:    MPIU_THREAD_CS_EXIT(ALLFUNC,);
     3410:  219:    return mpi_errno;
        -:  220:
    #####:  221:  fn_progress_end_fail:
        -:  222:    MPID_Progress_end(&progress_state);
        -:  223:
    #####:  224:  fn_fail:
        -:  225:    /* --BEGIN ERROR HANDLING-- */
        -:  226:#ifdef HAVE_ERROR_CHECKING
    #####:  227:    mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, 
        -:  228:				     FCNAME, __LINE__, MPI_ERR_OTHER,
        -:  229:				     "**mpi_waitany", 
        -:  230:				     "**mpi_waitany %d %p %p %p", 
        -:  231:				     count, array_of_requests, index, status);
        -:  232:#endif
    #####:  233:    mpi_errno = MPIR_Err_return_comm(NULL, FCNAME, mpi_errno);
    #####:  234:    goto fn_exit;
        -:  235:    /* --END ERROR HANDLING-- */
        -:  236:}