int MPIDI_CH3U_Receive_data_unexpected(MPIR_Request * rreq, void *buf, intptr_t *buflen, int *complete)
{
    int mpi_errno = MPI_SUCCESS;
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPIDI_CH3U_RECEIVE_DATA_UNEXPECTED);

    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPIDI_CH3U_RECEIVE_DATA_UNEXPECTED);

    /* FIXME: to improve performance, allocate temporary buffer from a 
       specialized buffer pool. */
    /* FIXME: to avoid memory exhaustion, integrate buffer pool management
       with flow control */
    MPL_DBG_MSG(MPIDI_CH3_DBG_OTHER,VERBOSE,"unexpected request allocated");
    
    rreq->dev.tmpbuf = MPL_malloc(rreq->dev.recv_data_sz, MPL_MEM_BUFFER);
    if (!rreq->dev.tmpbuf) {
	MPIR_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER,"**nomem","**nomem %d",
			     rreq->dev.recv_data_sz);
    }
    rreq->dev.tmpbuf_sz = rreq->dev.recv_data_sz;
    
    /* if all of the data has already been received, copy it
       now, otherwise build an iov and let the channel copy it */
    if (rreq->dev.recv_data_sz <= *buflen)
    {
        MPIR_Memcpy(rreq->dev.tmpbuf, buf, rreq->dev.recv_data_sz);
        *buflen = rreq->dev.recv_data_sz;
        rreq->dev.recv_pending_count = 1;
        *complete = TRUE;
    }
    else
    {
        rreq->dev.iov[0].MPL_IOV_BUF = (MPL_IOV_BUF_CAST)((char *)rreq->dev.tmpbuf);
        rreq->dev.iov[0].MPL_IOV_LEN = rreq->dev.recv_data_sz;
        rreq->dev.iov_count = 1;
        rreq->dev.recv_pending_count = 2;
        *buflen = 0;
        *complete = FALSE;
    }

    if (MPIDI_Request_get_msg_type(rreq) == MPIDI_REQUEST_EAGER_MSG)
        MPIR_T_PVAR_LEVEL_INC(RECVQ, unexpected_recvq_buffer_size, rreq->dev.tmpbuf_sz);

    rreq->dev.OnDataAvail = MPIDI_CH3_ReqHandler_UnpackUEBufComplete;

 fn_fail:
    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPIDI_CH3U_RECEIVE_DATA_UNEXPECTED);
    return mpi_errno;
}
Exemple #2
0
MPID_Request *
MPIDI_Recvq_AEU(MPID_Request *newreq, int source, pami_task_t pami_source, int tag, int context_id, int msg_seqno)
#endif
{
  /* A matching request was not found in the posted queue, so we
     need to allocate a new request and add it to the unexpected
     queue */
  MPID_Request *rreq;
  rreq = newreq;
  rreq->kind = MPID_REQUEST_RECV;
  TRACE_MEMSET_R(pami_source,msg_seqno,recv_status);
  TRACE_SET_REQ_VAL(rreq->mpid.envelope.msginfo.MPIseqno,-1);
  TRACE_SET_REQ_VAL(rreq->mpid.envelope.length,-1);
  TRACE_SET_REQ_VAL(rreq->mpid.envelope.data,(void *) 0);
#ifndef OUT_OF_ORDER_HANDLING
  MPIDI_Request_setMatch(rreq, tag, source, context_id);
#ifdef QUEUE_BINARY_SEARCH_SUPPORT
  if(MPIDI_Process.queue_binary_search_support_on) {
    MPIDI_Recvq_insert_uexp((void*)rreq, source, tag, context_id);
    MPIR_T_PVAR_LEVEL_INC(RECVQ, unexpected_recvq_length, 1);
  } else {
#endif
    MPIDI_Recvq_append(MPIDI_Recvq.unexpected, rreq);
    MPIR_T_PVAR_LEVEL_INC(RECVQ, unexpected_recvq_length, 1);
#ifdef QUEUE_BINARY_SEARCH_SUPPORT
  }
#endif

#else /* OUT_OF_ORDER_HANDLING */
  MPID_Request *q;
  MPIDI_In_cntr_t *in_cntr;
  int insert, i;

  in_cntr = &MPIDI_In_cntr[pami_source];
  MPIDI_Request_setMatch(rreq, tag, source, context_id); /* mpi rank needed */
  MPIDI_Request_setPeerRank_pami(rreq, pami_source);
  MPIDI_Request_setPeerRank_comm(rreq, source);
  MPIDI_Request_setMatchSeq(rreq, msg_seqno);
#ifdef QUEUE_BINARY_SEARCH_SUPPORT
  if(MPIDI_Process.queue_binary_search_support_on)
  { 
    MPIDI_Recvq_insert_uexp((void*)rreq, source, tag, context_id, msg_seqno);
    MPIR_T_PVAR_LEVEL_INC(RECVQ, unexpected_recvq_length, 1);
  }
  else
  {
#endif
    if (!in_cntr->n_OutOfOrderMsgs) {
      MPIDI_Recvq_append(MPIDI_Recvq.unexpected, rreq);
      MPIR_T_PVAR_LEVEL_INC(RECVQ, unexpected_recvq_length, 1);
    } else {
      q=in_cntr->OutOfOrderList;
      insert=0;
      for (i=1; i<=in_cntr->n_OutOfOrderMsgs; i++) {
        if ( context_id == MPIDI_Request_getMatchCtxt(q)) {
          if (((int)(msg_seqno - MPIDI_Request_getMatchSeq(q))) < 0) {
             MPIDI_Recvq_insert(MPIDI_Recvq.unexpected, q, rreq);
             MPIR_T_PVAR_LEVEL_INC(RECVQ, unexpected_recvq_length, 1);
             insert=1;
             break;
          }
        }
        q=q->mpid.nextR;
      }
      if (!insert) {
        MPIDI_Recvq_append(MPIDI_Recvq.unexpected, rreq);
        MPIR_T_PVAR_LEVEL_INC(RECVQ, unexpected_recvq_length, 1);
      }
    }
   TRACE_SET_R_VAL(pami_source,(msg_seqno & SEQMASK),req,rreq);
   TRACE_SET_R_VAL(pami_source,(msg_seqno & SEQMASK),msgid,msg_seqno);
   TRACE_SET_R_BIT(pami_source,(msg_seqno & SEQMASK),fl.f.ool);
   TRACE_SET_R_VAL(pami_source,(msg_seqno & SEQMASK),rtag,tag);
   TRACE_SET_R_VAL(pami_source,(msg_seqno & SEQMASK),rctx,context_id);
   TRACE_SET_REQ_VAL(rreq->mpid.idx,(msg_seqno & SEQMASK));
   TRACE_SET_R_VAL(pami_source,(msg_seqno & SEQMASK),rsource,pami_source);
   TRACE_SET_REQ_VAL(rreq->mpid.partner_id,pami_source);
#ifdef QUEUE_BINARY_SEARCH_SUPPORT
  }
#endif

  if (((int)(in_cntr->nMsgs - msg_seqno)) < 0) { /* seqno > nMsgs, out of order */
    MPIDI_Recvq_enqueue_ool(pami_source,rreq);
  }
#endif/* OUT_OF_ORDER_HANDLING */

  return rreq;
}