/* MSGQUEUE lock must be held by caller */ void MPIDI_Callback_process_unexp(MPID_Request *newreq, pami_context_t context, const MPIDI_MsgInfo * msginfo, size_t sndlen, pami_endpoint_t sender, const void * sndbuf, pami_recv_t * recv, unsigned isSync) { MPID_Request *rreq = NULL; /* ---------------------------------------------------- */ /* Fallback position: */ /* + Request was not posted, or */ /* + Request was long & not contiguous. */ /* We must allocate enough space to hold the message. */ /* The temporary buffer will be unpacked later. */ /* ---------------------------------------------------- */ unsigned rank = msginfo->MPIrank; unsigned tag = msginfo->MPItag; unsigned context_id = msginfo->MPIctxt; #ifndef OUT_OF_ORDER_HANDLING rreq = MPIDI_Recvq_AEU(newreq, rank, tag, context_id); #else unsigned msg_seqno = msginfo->MPIseqno; rreq = MPIDI_Recvq_AEU(newreq, rank, PAMIX_Endpoint_query(sender), tag, context_id, msg_seqno); #endif /* ---------------------- */ /* Copy in information. */ /* ---------------------- */ rreq->status.MPI_SOURCE = rank; rreq->status.MPI_TAG = tag; MPIR_STATUS_SET_COUNT(rreq->status, sndlen); MPIDI_Request_setCA (rreq, MPIDI_CA_COMPLETE); MPIDI_Request_cpyPeerRequestH(rreq, msginfo); MPIDI_Request_setSync (rreq, isSync); /* Set the rank of the sender if a sync msg. */ #ifndef OUT_OF_ORDER_HANDLING if (isSync) { #endif MPIDI_Request_setPeerRank_comm(rreq, rank); MPIDI_Request_setPeerRank_pami(rreq, PAMIX_Endpoint_query(sender)); #ifndef OUT_OF_ORDER_HANDLING } #endif MPID_assert(!sndlen || rreq->mpid.uebuf != NULL); TRACE_MEMSET_R(PAMIX_Endpoint_query(sender),msg_seqno,recv_status); TRACE_SET_R_VAL(PAMIX_Endpoint_query(sender),(msginfo->MPIseqno & SEQMASK),msgid,msginfo->MPIseqno); TRACE_SET_R_VAL(PAMIX_Endpoint_query(sender),(msginfo->MPIseqno & SEQMASK),rtag,tag); TRACE_SET_R_VAL(PAMIX_Endpoint_query(sender),(msginfo->MPIseqno & SEQMASK),rctx,msginfo->MPIctxt); TRACE_SET_R_VAL(PAMIX_Endpoint_query(sender),(msginfo->MPIseqno & SEQMASK),rlen,sndlen); TRACE_SET_R_VAL(PAMIX_Endpoint_query(sender),(msginfo->MPIseqno & SEQMASK),fl.f.sync,isSync); TRACE_SET_R_VAL(PAMIX_Endpoint_query(sender),(msginfo->MPIseqno & SEQMASK),rsource,PAMIX_Endpoint_query(sender)); TRACE_SET_REQ_VAL(rreq->mpid.idx,(msginfo->MPIseqno & SEQMASK)); if (recv != NULL) { recv->local_fn = MPIDI_RecvDoneCB_mutexed; recv->cookie = rreq; /* -------------------------------------------------- */ /* Let PAMI know where to put the rest of the data. */ /* -------------------------------------------------- */ recv->addr = rreq->mpid.uebuf; } else { /* ------------------------------------------------- */ /* We have the data; copy it and complete the msg. */ /* ------------------------------------------------- */ memcpy(rreq->mpid.uebuf, sndbuf, sndlen); MPIDI_RecvDoneCB(context, rreq, PAMI_SUCCESS); /* caller must release rreq, after unlocking MSGQUEUE */ } }
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; }