/* 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 */
    }
}
Example #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;
}