示例#1
0
int MPID_Mrecv(void *buf, int count, MPI_Datatype datatype,
               MPIR_Request *message, MPI_Status *status)
{
    int mpi_errno = MPI_SUCCESS;
    MPI_Request req_handle; /* dummy for MPIR_Request_complete */
    int active_flag; /* dummy for MPIR_Request_complete */
    MPIR_Request *rreq = NULL;

    if (message == NULL) {
        /* treat as though MPI_MESSAGE_NO_PROC was passed */
        MPIR_Status_set_procnull(status);
        goto fn_exit;
    }

    /* There is no optimized MPID_Mrecv at this time because there is no real
     * optimization potential in that case.  MPID_Recv exists to prevent
     * creating a request unnecessarily for messages that are already present
     * and eligible for immediate completion. */
    mpi_errno = MPID_Imrecv(buf, count, datatype, message, &rreq);
    if (mpi_errno) MPIR_ERR_POP(mpi_errno);

    if (!MPIR_Request_is_complete(rreq)) {
        MPID_Progress_state progress_state;

        MPID_Progress_start(&progress_state);
        while (!MPIR_Request_is_complete(rreq))
        {
            mpi_errno = MPID_Progress_wait(&progress_state);
            if (mpi_errno) {
                /* --BEGIN ERROR HANDLING-- */
                MPID_Progress_end(&progress_state);
                MPIR_ERR_POP(mpi_errno);
                /* --END ERROR HANDLING-- */
            }
        }
        MPID_Progress_end(&progress_state);
    }
    mpi_errno = MPIR_Request_complete(&req_handle, rreq, status, &active_flag);
    if (mpi_errno) MPIR_ERR_POP(mpi_errno);

fn_exit:
    return mpi_errno;
fn_fail:
    goto fn_exit;
}
示例#2
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;
}