Beispiel #1
0
int MPIR_Test_impl(MPI_Request *request, int *flag, MPI_Status *status)
{
    int mpi_errno = MPI_SUCCESS;
    int active_flag;
    MPID_Request *request_ptr = NULL;

    /* If this is a null request handle, then return an empty status */
    if (*request == MPI_REQUEST_NULL) {
	MPIR_Status_set_empty(status);
	*flag = TRUE;
	goto fn_exit;
    }
    
    *flag = FALSE;

    MPID_Request_get_ptr( *request, request_ptr );

    /* If the request is already completed AND we want to avoid calling
     the progress engine, we could make the call to MPID_Progress_test
     conditional on the request not being completed. */
    mpi_errno = MPID_Progress_test();
    if (mpi_errno != MPI_SUCCESS) goto fn_fail;

    if (request_ptr->kind == MPID_UREQUEST &&
        request_ptr->greq_fns != NULL &&
        request_ptr->greq_fns->poll_fn != NULL)
    {
        mpi_errno = (request_ptr->greq_fns->poll_fn)(request_ptr->greq_fns->grequest_extra_state, status);
        if (mpi_errno) MPIU_ERR_POP(mpi_errno);
    }

    if (MPID_Request_is_complete(request_ptr)) {
	mpi_errno = MPIR_Request_complete(request, request_ptr, status,
					  &active_flag);
	*flag = TRUE;
	if (mpi_errno) MPIU_ERR_POP(mpi_errno);
	/* Fall through to the exit */
    }
        
 fn_exit:
    return mpi_errno;
 fn_fail:
    goto fn_exit;
}
Beispiel #2
0
int MPIR_Test(MPI_Request * request, int *flag, MPI_Status * status)
{
    int mpi_errno = MPI_SUCCESS;
    int active_flag;
    MPIR_Request *request_ptr = NULL;

    /* If this is a null request handle, then return an empty status */
    if (*request == MPI_REQUEST_NULL) {
        MPIR_Status_set_empty(status);
        *flag = TRUE;
        goto fn_exit;
    }

    MPIR_Request_get_ptr(*request, request_ptr);
    MPIR_Assert(request_ptr != NULL);

    mpi_errno = MPID_Test(request_ptr, flag, status);
    if (mpi_errno)
        MPIR_ERR_POP(mpi_errno);

    if (*flag) {
        mpi_errno = MPIR_Request_completion_processing(request_ptr, status, &active_flag);
        if (!MPIR_Request_is_persistent(request_ptr)) {
            MPIR_Request_free(request_ptr);
            *request = MPI_REQUEST_NULL;
        }
        if (mpi_errno)
            MPIR_ERR_POP(mpi_errno);
        /* Fall through to the exit */
    } else if (unlikely(MPIR_Request_is_anysrc_mismatched(request_ptr))) {
        MPIR_ERR_SET(mpi_errno, MPIX_ERR_PROC_FAILED_PENDING, "**failure_pending");
        if (status != MPI_STATUS_IGNORE)
            status->MPI_ERROR = mpi_errno;
        goto fn_fail;
    }
  fn_exit:
    return mpi_errno;
  fn_fail:
    goto fn_exit;
}
Beispiel #3
0
/* Complete a request, saving the status data if necessary.
   "active" has meaning only if the request is a persistent request; this 
   allows the completion routines to indicate that a persistent request 
   was inactive and did not require any extra completion operation.

   If debugger information is being provided for pending (user-initiated) 
   send operations, the macros MPIR_SENDQ_FORGET will be defined to 
   call the routine MPIR_Sendq_forget; otherwise that macro will be a no-op.
   The implementation of the MPIR_Sendq_xxx is in src/mpi/debugger/dbginit.c .
*/
int MPIR_Request_complete(MPI_Request * request, MPID_Request * request_ptr, 
			  MPI_Status * status, int * active)
{
    int mpi_errno = MPI_SUCCESS;

    *active = TRUE;
    switch(request_ptr->kind)
    {
	case MPID_REQUEST_SEND:
	{
	    if (status != MPI_STATUS_IGNORE)
	    {
		MPIR_STATUS_SET_CANCEL_BIT(*status, MPIR_STATUS_GET_CANCEL_BIT(request_ptr->status));
	    }
	    mpi_errno = request_ptr->status.MPI_ERROR;
	    MPIR_SENDQ_FORGET(request_ptr);
	    MPID_Request_release(request_ptr);
            if (NULL != request) *request = MPI_REQUEST_NULL;
	    break;
	}
	case MPID_REQUEST_RECV:
	{
	    MPIR_Request_extract_status(request_ptr, status);
	    mpi_errno = request_ptr->status.MPI_ERROR;
	    MPID_Request_release(request_ptr);
            if (NULL != request) *request = MPI_REQUEST_NULL;
	    break;
	}
			
	case MPID_PREQUEST_SEND:
	{
	    if (request_ptr->partner_request != NULL)
	    {
		MPID_Request * prequest_ptr = request_ptr->partner_request;

		/* reset persistent request to inactive state */
                MPID_cc_set(&request_ptr->cc, 0);
		request_ptr->cc_ptr = &request_ptr->cc;
		request_ptr->partner_request = NULL;
		
		if (prequest_ptr->kind != MPID_UREQUEST)
		{
		    if (status != MPI_STATUS_IGNORE)
		    {
			MPIR_STATUS_SET_CANCEL_BIT(*status, MPIR_STATUS_GET_CANCEL_BIT(prequest_ptr->status));
		    }
		    mpi_errno = prequest_ptr->status.MPI_ERROR;
		}
		else
		{
		    /* This is needed for persistent Bsend requests */
                    int rc;
			
                    rc = MPIR_Grequest_query(prequest_ptr);
                    if (mpi_errno == MPI_SUCCESS)
                    {
                        mpi_errno = rc;
                    }
                    if (status != MPI_STATUS_IGNORE)
                    {
                        MPIR_STATUS_SET_CANCEL_BIT(*status, MPIR_STATUS_GET_CANCEL_BIT(prequest_ptr->status));
                    }
                    if (mpi_errno == MPI_SUCCESS)
                    {
                        mpi_errno = prequest_ptr->status.MPI_ERROR;
                    }
                    rc = MPIR_Grequest_free(prequest_ptr);
                    if (mpi_errno == MPI_SUCCESS)
                    {
                        mpi_errno = rc;
                    }
		}

		MPID_Request_release(prequest_ptr);
	    }
	    else
	    {
		if (request_ptr->status.MPI_ERROR != MPI_SUCCESS)
		{
		    /* if the persistent request failed to start then make the
		       error code available */
		    if (status != MPI_STATUS_IGNORE)
		    {
			MPIR_STATUS_SET_CANCEL_BIT(*status, FALSE);
		    }
		    mpi_errno = request_ptr->status.MPI_ERROR;
		}
		else
		{
		    MPIR_Status_set_empty(status);
		    *active = FALSE;
		}
	    }
	    
	    break;
	}
	
	case MPID_PREQUEST_RECV:
	{
	    if (request_ptr->partner_request != NULL)
	    {
		MPID_Request * prequest_ptr = request_ptr->partner_request;

		/* reset persistent request to inactive state */
                MPID_cc_set(&request_ptr->cc, 0);
		request_ptr->cc_ptr = &request_ptr->cc;
		request_ptr->partner_request = NULL;
		
		MPIR_Request_extract_status(prequest_ptr, status);
		mpi_errno = prequest_ptr->status.MPI_ERROR;

		MPID_Request_release(prequest_ptr);
	    }
	    else
	    {
		MPIR_Status_set_empty(status);
		/* --BEGIN ERROR HANDLING-- */
		if (request_ptr->status.MPI_ERROR != MPI_SUCCESS)
		{
		    /* if the persistent request failed to start then make the
		       error code available */
		    mpi_errno = request_ptr->status.MPI_ERROR;
		}
		else
		{
		    *active = FALSE;
		}
		/* --END ERROR HANDLING-- */
	    }
	    
	    break;
	}

	case MPID_UREQUEST:
	{
            int rc;
            
            rc = MPIR_Grequest_query(request_ptr);
            if (mpi_errno == MPI_SUCCESS)
            {
                mpi_errno = rc;
            }
            MPIR_Request_extract_status(request_ptr, status);
            rc = MPIR_Grequest_free(request_ptr);
            if (mpi_errno == MPI_SUCCESS)
            {
                mpi_errno = rc;
            }
            
            MPID_Request_release(request_ptr);
            if (NULL != request) *request = MPI_REQUEST_NULL;
	    
	    break;
	}

        case MPID_COLL_REQUEST:
        case MPID_WIN_REQUEST:
        {
            mpi_errno = request_ptr->status.MPI_ERROR;
            MPIR_Request_extract_status(request_ptr, status);
            MPID_Request_release(request_ptr);
            if (NULL != request) *request = MPI_REQUEST_NULL;
            break;
        }
	
	default:
	{
	    /* --BEGIN ERROR HANDLING-- */
	    /* This should not happen */
	    MPIR_ERR_SETANDSTMT1(mpi_errno, MPI_ERR_INTERN,;, "**badcase",
		"**badcase %d", request_ptr->kind);
	    break;
	    /* --END ERROR HANDLING-- */
	}
    }