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; }
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; }