-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/pt2pt/mpir_request.c
        -:    0:Graph:mpir_request.gcno
        -:    0:Data:mpir_request.gcda
        -:    0:Runs:4380
        -:    0:Programs:1376
        -:    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:#undef FUNCNAME
        -:   11:#define FUNCNAME MPIR_Request_complete
        -:   12:#undef FCNAME
        -:   13:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:   14:/* Complete a request, saving the status data if necessary.
        -:   15:   "active" has meaning only if the request is a persistent request; this 
        -:   16:   allows the completion routines to indicate that a persistent request 
        -:   17:   was inactive and did not require any extra completion operation.
        -:   18:
        -:   19:   If debugger information is being provided for pending (user-initiated) 
        -:   20:   send operations, the macros MPIR_SENDQ_FORGET will be defined to 
        -:   21:   call the routine MPIR_Sendq_forget; otherwise that macro will be a no-op.
        -:   22:   The implementation of the MPIR_Sendq_xxx is in src/mpi/debugger/dbginit.c .
        -:   23:*/
        -:   24:int MPIR_Request_complete(MPI_Request * request, MPID_Request * request_ptr, 
        -:   25:			  MPI_Status * status, int * active)
  3843773:   26:{
  3843773:   27:    int mpi_errno = MPI_SUCCESS;
        -:   28:
  3843773:   29:    *active = TRUE;
  3843773:   30:    switch(request_ptr->kind)
        -:   31:    {
        -:   32:	case MPID_REQUEST_SEND:
        -:   33:	{
  1497046:   34:	    if (status != MPI_STATUS_IGNORE)
        -:   35:	    {
  1301981:   36:		status->cancelled = request_ptr->status.cancelled;
        -:   37:	    }
  1497046:   38:	    mpi_errno = request_ptr->status.MPI_ERROR;
        -:   39:	    /* FIXME: are Ibsend requests added to the send queue? */
        -:   40:	    MPIR_SENDQ_FORGET(request_ptr);
  1497046:   41:	    MPID_Request_release(request_ptr);
  1497046:   42:	    *request = MPI_REQUEST_NULL;
  1497046:   43:	    break;
        -:   44:	}
        -:   45:	case MPID_REQUEST_RECV:
        -:   46:	{
  1418508:   47:	    MPIR_Request_extract_status(request_ptr, status);
  1418508:   48:	    mpi_errno = request_ptr->status.MPI_ERROR;
  1418508:   49:	    MPID_Request_release(request_ptr);
  1418508:   50:	    *request = MPI_REQUEST_NULL;
  1418508:   51:	    break;
        -:   52:	}
        -:   53:			
        -:   54:	case MPID_PREQUEST_SEND:
        -:   55:	{
   164243:   56:	    if (request_ptr->partner_request != NULL)
        -:   57:	    {
   150500:   58:		MPID_Request * prequest_ptr = request_ptr->partner_request;
        -:   59:
        -:   60:		/* reset persistent request to inactive state */
   150500:   61:		request_ptr->cc = 0;
   150500:   62:		request_ptr->cc_ptr = &request_ptr->cc;
   150500:   63:		request_ptr->partner_request = NULL;
        -:   64:		
   150500:   65:		if (prequest_ptr->kind != MPID_UREQUEST)
        -:   66:		{
   113482:   67:		    if (status != MPI_STATUS_IGNORE)
        -:   68:		    {
   113458:   69:			status->cancelled = prequest_ptr->status.cancelled;
        -:   70:		    }
   113482:   71:		    mpi_errno = prequest_ptr->status.MPI_ERROR;
        -:   72:		}
        -:   73:		else
        -:   74:		{
        -:   75:		    /* This is needed for persistent Bsend requests */
    37018:   76:		    MPIU_THREADPRIV_DECL;
    37018:   77:		    MPIU_THREADPRIV_GET;
    37018:   78:		    MPIR_Nest_incr();
        -:   79:		    {
        -:   80:			int rc;
        -:   81:			
    37018:   82:			rc = MPIR_Grequest_query(prequest_ptr);
    37018:   83:			if (mpi_errno == MPI_SUCCESS)
        -:   84:			{
    37018:   85:			    mpi_errno = rc;
        -:   86:			}
    37018:   87:			if (status != MPI_STATUS_IGNORE)
        -:   88:			{
    37010:   89:			    status->cancelled = prequest_ptr->status.cancelled;
        -:   90:			}
    37018:   91:			if (mpi_errno == MPI_SUCCESS)
        -:   92:			{
    37018:   93:			    mpi_errno = prequest_ptr->status.MPI_ERROR;
        -:   94:			}
    37018:   95:			rc = MPIR_Grequest_free(prequest_ptr);
    37018:   96:			if (mpi_errno == MPI_SUCCESS)
        -:   97:			{
    37018:   98:			    mpi_errno = rc;
        -:   99:			}
        -:  100:		    }
    37018:  101:		    MPIR_Nest_decr();
        -:  102:		}
        -:  103:
        -:  104:		/* FIXME: MPIR_SENDQ_FORGET(request_ptr); -- it appears that
        -:  105:		   persistent sends are not currently being added to the send
        -:  106:		   queue.  should they be, or should this release be
        -:  107:		   conditional? */
   150500:  108:		MPID_Request_release(prequest_ptr);
        -:  109:	    }
        -:  110:	    else
        -:  111:	    {
    13743:  112:		if (request_ptr->status.MPI_ERROR != MPI_SUCCESS)
        -:  113:		{
        -:  114:		    /* if the persistent request failed to start then make the
        -:  115:		       error code available */
        4:  116:		    if (status != MPI_STATUS_IGNORE)
        -:  117:		    {
        4:  118:			status->cancelled = FALSE;
        -:  119:		    }
        4:  120:		    mpi_errno = request_ptr->status.MPI_ERROR;
        -:  121:		}
        -:  122:		else
        -:  123:		{
    13739:  124:		    MPIR_Status_set_empty(status);
    13739:  125:		    *active = FALSE;
        -:  126:		}
        -:  127:	    }
        -:  128:	    
        -:  129:	    break;
        -:  130:	}
        -:  131:	
        -:  132:	case MPID_PREQUEST_RECV:
        -:  133:	{
   156219:  134:	    if (request_ptr->partner_request != NULL)
        -:  135:	    {
   143417:  136:		MPID_Request * prequest_ptr = request_ptr->partner_request;
        -:  137:
        -:  138:		/* reset persistent request to inactive state */
   143417:  139:		request_ptr->cc = 0;
   143417:  140:		request_ptr->cc_ptr = &request_ptr->cc;
   143417:  141:		request_ptr->partner_request = NULL;
        -:  142:		
   143417:  143:		MPIR_Request_extract_status(prequest_ptr, status);
   143417:  144:		mpi_errno = prequest_ptr->status.MPI_ERROR;
        -:  145:
   143417:  146:		MPID_Request_release(prequest_ptr);
        -:  147:	    }
        -:  148:	    else
        -:  149:	    {
    12802:  150:		MPIR_Status_set_empty(status);
        -:  151:		/* --BEGIN ERROR HANDLING-- */
    12802:  152:		if (request_ptr->status.MPI_ERROR != MPI_SUCCESS)
        -:  153:		{
        -:  154:		    /* if the persistent request failed to start then make the
        -:  155:		       error code available */
    #####:  156:		    mpi_errno = request_ptr->status.MPI_ERROR;
        -:  157:		}
        -:  158:		else
        -:  159:		{
    12802:  160:		    *active = FALSE;
        -:  161:		}
        -:  162:		/* --END ERROR HANDLING-- */
        -:  163:	    }
        -:  164:	    
        -:  165:	    break;
        -:  166:	}
        -:  167:
        -:  168:	case MPID_UREQUEST:
        -:  169:	{
   607757:  170:	    MPIU_THREADPRIV_DECL;
        -:  171:
   607757:  172:	    MPIU_THREADPRIV_GET;
        -:  173:
        -:  174:	    /* The user error handler may make calls to MPI routines, so the
        -:  175:	       nesting counter must be incremented before the handler is
        -:  176:	       called */
   607757:  177:	    MPIR_Nest_incr();
        -:  178:	    {
        -:  179:		int rc;
        -:  180:		
   607757:  181:		rc = MPIR_Grequest_query(request_ptr);
   607757:  182:		if (mpi_errno == MPI_SUCCESS)
        -:  183:		{
   607757:  184:		    mpi_errno = rc;
        -:  185:		}
   607757:  186:		MPIR_Request_extract_status(request_ptr, status);
   607757:  187:		rc = MPIR_Grequest_free(request_ptr);
   607757:  188:		if (mpi_errno == MPI_SUCCESS)
        -:  189:		{
   607757:  190:		    mpi_errno = rc;
        -:  191:		}
        -:  192:		
   607757:  193:		MPID_Request_release(request_ptr);
   607757:  194:		*request = MPI_REQUEST_NULL;
        -:  195:	    }
   607757:  196:	    MPIR_Nest_decr();
        -:  197:	    
   607757:  198:	    break;
        -:  199:	}
        -:  200:	
        -:  201:	default:
        -:  202:	{
        -:  203:	    /* --BEGIN ERROR HANDLING-- */
        -:  204:	    /* This should not happen */
    #####:  205:	    MPIU_ERR_SETANDSTMT1(mpi_errno, MPI_ERR_INTERN,;, "**badcase",
        -:  206:		"**badcase %d", request_ptr->kind);
        -:  207:	    break;
        -:  208:	    /* --END ERROR HANDLING-- */
        -:  209:	}
        -:  210:    }
        -:  211:
  3843773:  212:    return mpi_errno;
        -:  213:}
        -:  214:
        -:  215:
        -:  216:#undef FUNCNAME
        -:  217:#define FUNCNAME MPIR_Request_get_error
        -:  218:#undef FCNAME
        -:  219:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:  220:/* FIXME: What is this routine for?
        -:  221: *  
        -:  222: * [BRT] it is used by testall, although looking at testall now, I think the
        -:  223: * algorithm can be change slightly and eliminate the need for this routine
        -:  224: */
        -:  225:int MPIR_Request_get_error(MPID_Request * request_ptr)
    32395:  226:{
    32395:  227:    int mpi_errno = MPI_SUCCESS;
    32395:  228:    MPIU_THREADPRIV_DECL;
        -:  229:
        -:  230:    /* FIXME: Why do we need to get the thread-private storage here? */
    32395:  231:    MPIU_THREADPRIV_GET;
        -:  232:
    32395:  233:    switch(request_ptr->kind)
        -:  234:    {
        -:  235:	case MPID_REQUEST_SEND:
        -:  236:	case MPID_REQUEST_RECV:
        -:  237:	{
    25590:  238:	    mpi_errno = request_ptr->status.MPI_ERROR;
    25590:  239:	    break;
        -:  240:	}
        -:  241:
        -:  242:	case MPID_PREQUEST_SEND:
        -:  243:	{
     3024:  244:	    if (request_ptr->partner_request != NULL)
        -:  245:	    {
     3024:  246:		if (request_ptr->partner_request->kind == MPID_UREQUEST)
        -:  247:		{
        -:  248:		    /* This is needed for persistent Bsend requests */
      738:  249:		    mpi_errno = MPIR_Grequest_query(
        -:  250:			request_ptr->partner_request);
        -:  251:		}
     3024:  252:		if (mpi_errno == MPI_SUCCESS)
        -:  253:		{
     3024:  254:		    mpi_errno = request_ptr->partner_request->status.MPI_ERROR;
        -:  255:		}
        -:  256:	    }
        -:  257:	    else
        -:  258:	    {
    #####:  259:		mpi_errno = request_ptr->status.MPI_ERROR;
        -:  260:	    }
        -:  261:
        -:  262:	    break;
        -:  263:	}
        -:  264:
        -:  265:	case MPID_PREQUEST_RECV:
        -:  266:	{
     3240:  267:	    if (request_ptr->partner_request != NULL)
        -:  268:	    {
     3240:  269:		mpi_errno = request_ptr->partner_request->status.MPI_ERROR;
        -:  270:	    }
        -:  271:	    else
        -:  272:	    {
    #####:  273:		mpi_errno = request_ptr->status.MPI_ERROR;
        -:  274:	    }
        -:  275:
        -:  276:	    break;
        -:  277:	}
        -:  278:
        -:  279:	case MPID_UREQUEST:
        -:  280:	{
        -:  281:	    int rc;
        -:  282:	    
        -:  283:	    /* The user error handler may make calls to MPI routines, so the 
        -:  284:	       nesting counter must be incremented before the handler 
        -:  285:	       is called */
        -:  286:	    /* Note that we've acquired the thread private storage above */
      541:  287:	    MPIR_Nest_incr();
        -:  288:    
      541:  289:	    switch (request_ptr->greq_lang)
        -:  290:	    {
        -:  291:		case MPID_LANG_C:
        -:  292:#ifdef HAVE_CXX_BINDING
        -:  293:		case MPID_LANG_CXX:
        -:  294:#endif
      541:  295:		    rc = (request_ptr->query_fn)(
        -:  296:			request_ptr->grequest_extra_state,
        -:  297:			&request_ptr->status);
      541:  298:		    MPIU_ERR_CHKANDSTMT1((rc != MPI_SUCCESS), mpi_errno,
        -:  299:			MPI_ERR_OTHER,;, "**user", "**userquery %d", rc);
        -:  300:		    break;
        -:  301:#ifdef HAVE_FORTRAN_BINDING
        -:  302:		case MPID_LANG_FORTRAN:
        -:  303:		case MPID_LANG_FORTRAN90:
        -:  304:		{
        -:  305:		    MPI_Fint ierr;
    #####:  306:		    ((MPIR_Grequest_f77_query_function*)(request_ptr->query_fn))( 
        -:  307:			request_ptr->grequest_extra_state, &request_ptr->status,
        -:  308:			&ierr );
    #####:  309:		    rc = (int) ierr;
    #####:  310:		    MPIU_ERR_CHKANDSTMT1((rc != MPI_SUCCESS), mpi_errno,
        -:  311:			MPI_ERR_OTHER,;, "**user", "**userquery %d", rc);
        -:  312:		    break;
        -:  313:		}
        -:  314:#endif
        -:  315:		
        -:  316:		default:
        -:  317:		{
        -:  318:		    /* --BEGIN ERROR HANDLING-- */
        -:  319:		    /* This should not happen */
    #####:  320:		    MPIU_ERR_SETANDSTMT1(mpi_errno, MPI_ERR_INTERN,;, 
        -:  321:				 "**badcase", 
        -:  322:				 "**badcase %d", request_ptr->greq_lang);
        -:  323:		    break;
        -:  324:		    /* --END ERROR HANDLING-- */
        -:  325:		}
        -:  326:	    }
        -:  327:
      541:  328:	    MPIR_Nest_decr();
      541:  329:	    break;
        -:  330:	}
        -:  331:	
        -:  332:	default:
        -:  333:	{
        -:  334:	    /* --BEGIN ERROR HANDLING-- */
        -:  335:	    /* This should not happen */
    #####:  336:	    MPIU_ERR_SETANDSTMT1(mpi_errno, MPI_ERR_INTERN,;, "**badcase", 
        -:  337:				 "**badcase %d", request_ptr->kind);
        -:  338:	    break;
        -:  339:	    /* --END ERROR HANDLING-- */
        -:  340:	}
        -:  341:    }
        -:  342:
    32395:  343:    return mpi_errno;
        -:  344:}
        -:  345:
        -:  346:#ifdef HAVE_FORTRAN_BINDING
        -:  347:/* Set the language type to Fortran for this (generalized) request */
        -:  348:void MPIR_Grequest_set_lang_f77( MPI_Request greq )
        2:  349:{
        -:  350:    MPID_Request *greq_ptr;
        -:  351:
        2:  352:    MPID_Request_get_ptr( greq, greq_ptr );
        -:  353:
        2:  354:    greq_ptr->greq_lang = MPID_LANG_FORTRAN;
        2:  355:}
        -:  356:#endif
        -:  357:
        -:  358:
        -:  359:#undef FUNCNAME
        -:  360:#define FUNCNAME MPIR_Grequest_cancel
        -:  361:#undef FCNAME
        -:  362:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:  363:int MPIR_Grequest_cancel(MPID_Request * request_ptr, int complete)
        8:  364:{
        -:  365:    int rc;
        8:  366:    int mpi_errno = MPI_SUCCESS;
        -:  367:    
        8:  368:    switch (request_ptr->greq_lang)
        -:  369:    {
        -:  370:	case MPID_LANG_C:
        -:  371:#ifdef HAVE_CXX_BINDING
        -:  372:	case MPID_LANG_CXX:
        -:  373:#endif
        8:  374:	    rc = (request_ptr->cancel_fn)(
        -:  375:		request_ptr->grequest_extra_state, complete);
        8:  376:	    MPIU_ERR_CHKANDSTMT1((rc != MPI_SUCCESS), mpi_errno,
        -:  377:		MPI_ERR_OTHER,;, "**user", "**usercancel %d", rc);
        -:  378:	    break;
        -:  379:#ifdef HAVE_FORTRAN_BINDING
        -:  380:	case MPID_LANG_FORTRAN:
        -:  381:	case MPID_LANG_FORTRAN90:
        -:  382:	{
        -:  383:	    MPI_Fint ierr;
        -:  384:
    #####:  385:	    ((MPIR_Grequest_f77_cancel_function *)(request_ptr->cancel_fn))(
        -:  386:		request_ptr->grequest_extra_state, &complete, &ierr);
    #####:  387:	    rc = (int) ierr;
    #####:  388:	    MPIU_ERR_CHKANDSTMT1((rc != MPI_SUCCESS), mpi_errno, MPI_ERR_OTHER,
        -:  389:		{;}, "**user", "**usercancel %d", rc);
        -:  390:	    break;
        -:  391:	}
        -:  392:#endif
        -:  393:		
        -:  394:	default:
        -:  395:	{
        -:  396:	    /* --BEGIN ERROR HANDLING-- */
        -:  397:	    /* This should not happen */
    #####:  398:	    MPIU_ERR_SETANDSTMT1(mpi_errno, MPI_ERR_INTERN,;, "**badcase",
        -:  399:		"**badcase %d", request_ptr->greq_lang);
        -:  400:	    break;
        -:  401:	    /* --END ERROR HANDLING-- */
        -:  402:	}
        -:  403:    }
        -:  404:
        8:  405:    return mpi_errno;
        -:  406:}
        -:  407:
        -:  408:
        -:  409:#undef FUNCNAME
        -:  410:#define FUNCNAME MPIR_Grequest_query
        -:  411:#undef FCNAME
        -:  412:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:  413:int MPIR_Grequest_query(MPID_Request * request_ptr)
   645513:  414:{
        -:  415:    int rc;
   645513:  416:    int mpi_errno = MPI_SUCCESS;
        -:  417:    
   645513:  418:    switch (request_ptr->greq_lang)
        -:  419:    {
        -:  420:	case MPID_LANG_C:
        -:  421:#ifdef HAVE_CXX_BINDING
        -:  422:	case MPID_LANG_CXX:
        -:  423:#endif
   645511:  424:	    rc = (request_ptr->query_fn)(request_ptr->grequest_extra_state,
        -:  425:		&request_ptr->status);
   645511:  426:	    MPIU_ERR_CHKANDSTMT1((rc != MPI_SUCCESS), mpi_errno, MPI_ERR_OTHER,
        -:  427:		{;}, "**user", "**userquery %d", rc);
        -:  428:	    break;
        -:  429:#ifdef HAVE_FORTRAN_BINDING
        -:  430:	case MPID_LANG_FORTRAN:
        -:  431:	case MPID_LANG_FORTRAN90:
        -:  432:	{
        -:  433:	    MPI_Fint ierr;
        2:  434:	    ((MPIR_Grequest_f77_query_function *)(request_ptr->query_fn))( 
        -:  435:		request_ptr->grequest_extra_state, &request_ptr->status, &ierr );
        2:  436:	    rc = (int)ierr;
        2:  437:	    MPIU_ERR_CHKANDSTMT1((rc != MPI_SUCCESS), mpi_errno, MPI_ERR_OTHER,
        -:  438:		{;}, "**user", "**userquery %d", rc);
        -:  439:	}
        -:  440:	break;
        -:  441:#endif	    
        -:  442:	default:
        -:  443:	{
        -:  444:	    /* --BEGIN ERROR HANDLING-- */
        -:  445:	    /* This should not happen */
    #####:  446:	    MPIU_ERR_SETANDSTMT1(mpi_errno, MPI_ERR_INTERN,;, "**badcase",
        -:  447:		"**badcase %d", request_ptr->greq_lang);
        -:  448:	    break;
        -:  449:	    /* --END ERROR HANDLING-- */
        -:  450:	}
        -:  451:    }
        -:  452:
   645513:  453:    return mpi_errno;
        -:  454:}
        -:  455:
        -:  456:
        -:  457:#undef FUNCNAME
        -:  458:#define FUNCNAME MPIR_Grequest_free
        -:  459:#undef FCNAME
        -:  460:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:  461:int MPIR_Grequest_free(MPID_Request * request_ptr)
   644794:  462:{
        -:  463:    int rc;
   644794:  464:    int mpi_errno = MPI_SUCCESS;
        -:  465:    
   644794:  466:    switch (request_ptr->greq_lang)
        -:  467:    {
        -:  468:	case MPID_LANG_C:
        -:  469:#ifdef HAVE_CXX_BINDING
        -:  470:	case MPID_LANG_CXX:
        -:  471:#endif
   644792:  472:	    rc = (request_ptr->free_fn)(request_ptr->grequest_extra_state);
   644792:  473:	    MPIU_ERR_CHKANDSTMT1((rc != MPI_SUCCESS), mpi_errno, MPI_ERR_OTHER,
        -:  474:		{;}, "**user", "**userfree %d", rc);
        -:  475:	    break;
        -:  476:#ifdef HAVE_FORTRAN_BINDING
        -:  477:	case MPID_LANG_FORTRAN:
        -:  478:	case MPID_LANG_FORTRAN90:
        -:  479:	{
        -:  480:	    MPI_Fint ierr;
        -:  481:		    
        2:  482:	    ((MPIR_Grequest_f77_free_function *)(request_ptr->free_fn))(
        -:  483:		request_ptr->grequest_extra_state, &ierr);
        2:  484:	    rc = (int) ierr;
        2:  485:	    MPIU_ERR_CHKANDSTMT1((rc != MPI_SUCCESS), mpi_errno, MPI_ERR_OTHER,
        -:  486:		{;}, "**user", "**userfree %d", rc);
        -:  487:	    break;
        -:  488:	}
        -:  489:#endif
        -:  490:		
        -:  491:	default:
        -:  492:	{
        -:  493:	    /* --BEGIN ERROR HANDLING-- */
        -:  494:	    /* This should not happen */
    #####:  495:	    MPIU_ERR_SETANDSTMT1(mpi_errno, MPI_ERR_INTERN, {;}, "**badcase",
        -:  496:		"**badcase %d", request_ptr->greq_lang);
        -:  497:	    break;
        -:  498:	    /* --END ERROR HANDLING-- */
        -:  499:	}
        -:  500:    }
        -:  501:
   644794:  502:    return mpi_errno;
        -:  503:}
        -:  504:
        -:  505:/* MPIR_Grequest_progress_poke:  Drives progess on generalized requests.
        -:  506: * Invokes poll_fn for each request in request_ptrs.  Waits for completion of
        -:  507: * multiple requests if possible (all outstanding generalized requests are of
        -:  508: * same greq class) */
        -:  509:#undef FUNCNAME
        -:  510:#define FUNCNAME MPIR_Grequest_progress_poke
        -:  511:#undef FCNAME
        -:  512:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:  513:int MPIR_Grequest_progress_poke(int count, 
        -:  514:		MPID_Request **request_ptrs, 
        -:  515:		MPI_Status array_of_statuses[] )
   595624:  516:{
   595624:  517:    MPIX_Grequest_wait_function *wait_fn = NULL;
        -:  518:    void ** state_ptrs;
        -:  519:    int i, j, n_classes, n_native, n_greq;
   595624:  520:    int mpi_errno = MPI_SUCCESS;
   595624:  521:    MPIU_CHKLMEM_DECL(1);
        -:  522:
   595624:  523:    MPIU_CHKLMEM_MALLOC(state_ptrs, void **, sizeof(void*) * count, mpi_errno, "state_ptrs");
        -:  524:
        -:  525:    /* This somewhat messy for-loop computes how many requests are native
        -:  526:     * requests and how many are generalized requests, and how many generalized
        -:  527:     * request classes those grequests are members of */
  1207798:  528:    for (i=0, j=0, n_classes=1, n_native=0, n_greq=0; i< count; i++)
        -:  529:    {
   612174:  530:	if (request_ptrs[i] == NULL || *request_ptrs[i]->cc_ptr == 0) continue;
   601939:  531:	if (request_ptrs[i]->kind == MPID_UREQUEST)
        -:  532:	{
   177454:  533:	    n_greq += 1;
   177454:  534:	    wait_fn = request_ptrs[i]->wait_fn;
   177454:  535:	    state_ptrs[j] = request_ptrs[i]->grequest_extra_state;
   177454:  536:	    j++;
   177454:  537:	    if (i+1 < count) {
        4:  538:	        if (request_ptrs[i+1] == NULL ||
        -:  539:			(request_ptrs[i]->greq_class != 
        -:  540:				request_ptrs[i+1]->greq_class) )
        4:  541:	            n_classes += 1;
        -:  542:	    }
        -:  543:	} else {
   424485:  544:	    n_native += 1;
        -:  545:	}
        -:  546:    }
        -:  547:
   773072:  548:    if (j > 0 && n_classes == 1 && wait_fn != NULL) {
   177448:  549:        mpi_errno = (wait_fn)(j, state_ptrs, 0, NULL);
        -:  550:    } else {
   852902:  551:	for (i = 0; i< count; i++ )
        -:  552:	{
   434726:  553:	    if (request_ptrs[i] != NULL && 
        -:  554:                request_ptrs[i]->kind == MPID_UREQUEST && 
        -:  555:                *request_ptrs[i]->cc_ptr != 0 &&
        -:  556:                request_ptrs[i]->poll_fn != NULL)
        -:  557:            {
        4:  558:		mpi_errno = (request_ptrs[i]->poll_fn)(request_ptrs[i]->grequest_extra_state, &(array_of_statuses[i]));
        4:  559:                if (mpi_errno) MPIU_ERR_POP(mpi_errno);
        -:  560:	    }
        -:  561:	}
        -:  562:    }
        -:  563:fn_exit:
   595624:  564:    MPIU_CHKLMEM_FREEALL();
   595624:  565:    return mpi_errno;
        -:  566:fn_fail:
        -:  567:    goto fn_exit;
        -:  568:}
        -:  569:
        -:  570:/* MPIR_Grequest_wait: Waits until all generalized requests have
        -:  571:   completed.  This routine groups grequests by class and calls the
        -:  572:   wait_fn on the whole class. */
        -:  573:#undef FUNCNAME
        -:  574:#define FUNCNAME MPIR_Grequest_waitall
        -:  575:#undef FCNAME
        -:  576:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  577:int MPIR_Grequest_waitall(int count, MPID_Request * const * request_ptrs)
   177428:  578:{
        -:  579:    void ** state_ptrs;
        -:  580:    int i;
   177428:  581:    int mpi_error = MPI_SUCCESS;
        -:  582:    MPID_Progress_state progress_state;
   177428:  583:    MPIU_CHKLMEM_DECL(1);
        -:  584:
   177428:  585:    MPIU_CHKLMEM_MALLOC(state_ptrs, void *, sizeof(void*)*count, mpi_error, "state_ptrs");
        -:  586:    
        -:  587:        /* DISABLED CODE: The greq wait_fn function returns when ANY
        -:  588:           of the requests completes, rather than all.  Also, once a
        -:  589:           greq has completed, you can't call wait on it again.  So in
        -:  590:           order to implement wait-all, we would need to rebuild the
        -:  591:           state_ptrs array every time wait_fn completed.  This would
        -:  592:           then be an O(n^2) algorithm.
        -:  593:
        -:  594:           Until a waitall_fn is added for greqs, we'll call wait on
        -:  595:           each greq individually. */
        -:  596:#if 0
        -:  597:    MPIX_Grequest_wait_function *wait_fn = NULL;
        -:  598:    int n_greq;
        -:  599:    MPIX_Grequest_class curr_class;
        -:  600:    /* loop over all requests, group greqs with the same class and
        -:  601:       call wait_fn on the groups.  (Only consecutive greqs with the
        -:  602:       same class are being grouped) */
        -:  603:    n_greq = 0;
        -:  604:    for (i = 0; i < count; ++i)
        -:  605:    {
        -:  606:        /* skip over requests we're not interested in */
        -:  607:        if (request_ptrs[i] == NULL || *request_ptrs[i]->cc_ptr == 0 ||  request_ptrs[i]->kind != MPID_UREQUEST)
        -:  608:            continue;
        -:  609:        
        -:  610:        if (n_greq == 0 || request_ptrs[i]->greq_class == curr_class)
        -:  611:        {
        -:  612:            /* if this is the first grequest of a group, or if it's the
        -:  613:               same class as the last one, add its state to the list  */
        -:  614:            curr_class = request_ptrs[i]->greq_class;
        -:  615:            wait_fn = request_ptrs[i]->wait_fn;
        -:  616:            state_ptrs[n_greq] = request_ptrs[i]->grequest_extra_state;
        -:  617:            ++n_greq;
        -:  618:        }
        -:  619:        else
        -:  620:        {
        -:  621:            /* greq with a new class: wait on the list of greqs we've
        -:  622:               created, then start a new list*/
        -:  623:            mpi_error = (wait_fn)(n_greq, state_ptrs, 0, NULL);
        -:  624:            if (mpi_error) MPIU_ERR_POP(mpi_error);
        -:  625:
        -:  626:            curr_class = request_ptrs[i]->greq_class;
        -:  627:            wait_fn = request_ptrs[i]->wait_fn;
        -:  628:            state_ptrs[0] = request_ptrs[i]->grequest_extra_state;
        -:  629:            n_greq = 1;
        -:  630:        }
        -:  631:    }
        -:  632:    
        -:  633:    if (n_greq)
        -:  634:    {
        -:  635:        /* wait on the last group of greqs */
        -:  636:        mpi_error = (wait_fn)(n_greq, state_ptrs, 0, NULL);
        -:  637:        if (mpi_error) MPIU_ERR_POP(mpi_error);
        -:  638:
        -:  639:    }
        -:  640:#else
   532471:  641:    for (i = 0; i < count; ++i)
        -:  642:    {
        -:  643:        /* skip over requests we're not interested in */
   355043:  644:        if (request_ptrs[i] == NULL ||
        -:  645:            *request_ptrs[i]->cc_ptr == 0 ||
        -:  646:            request_ptrs[i]->kind != MPID_UREQUEST ||
        -:  647:            request_ptrs[i]->wait_fn == NULL)
        -:  648:        {
        -:  649:            continue;
        -:  650:        }
        -:  651:
   354904:  652:        mpi_error = (request_ptrs[i]->wait_fn)(1, &request_ptrs[i]->grequest_extra_state, 0, NULL);
   354904:  653:        if (mpi_error) MPIU_ERR_POP(mpi_error);
   354904:  654:        MPIU_Assert(*request_ptrs[i]->cc_ptr == 0);
        -:  655:    }
        -:  656:
   177428:  657:    MPID_Progress_start(&progress_state);
   532471:  658:    for (i = 0; i < count; ++i)
        -:  659:    {
   355043:  660:        if (request_ptrs[i] == NULL || *request_ptrs[i]->cc_ptr == 0 || request_ptrs[i]->kind != MPID_UREQUEST)
        -:  661:            continue;
        -:  662:        /* We have a greq that doesn't have a wait function; some other
        -:  663:           thread will cause completion via MPI_Grequest_complete().  Rather
        -:  664:           than waste the time by simply yielding the processor to the
        -:  665:           other thread, we'll make progress on regular requests too.  The
        -:  666:           progress engine should permit the other thread to run at some
        -:  667:           point. */
        2:  668:        while (*request_ptrs[i]->cc_ptr != 0)
        -:  669:        {
        1:  670:            mpi_error = MPID_Progress_wait(&progress_state);
        1:  671:            if (mpi_error != MPI_SUCCESS)
        -:  672:            {
        -:  673:                /* --BEGIN ERROR HANDLING-- */
        -:  674:                MPID_Progress_end(&progress_state);
    #####:  675:                goto fn_fail;
        -:  676:                /* --END ERROR HANDLING-- */
        -:  677:            }
        -:  678:        }
        -:  679:    }
        -:  680:    MPID_Progress_end(&progress_state);
        -:  681:#endif
        -:  682:
        -:  683: fn_exit:
   177428:  684:    MPIU_CHKLMEM_FREEALL();
   177428:  685:    return mpi_error;
        -:  686: fn_fail:
        -:  687:    goto fn_exit;
        -:  688:}
        -:  689: