1 /* begin_generated_IBM_copyright_prolog                             */
2 /*                                                                  */
3 /* This is an automatically generated copyright prolog.             */
4 /* After initializing,  DO NOT MODIFY OR MOVE                       */
5 /*  --------------------------------------------------------------- */
6 /* Licensed Materials - Property of IBM                             */
7 /* Blue Gene/Q 5765-PER 5765-PRP                                    */
8 /*                                                                  */
9 /* (C) Copyright IBM Corp. 2011, 2012 All Rights Reserved           */
10 /* US Government Users Restricted Rights -                          */
11 /* Use, duplication, or disclosure restricted                       */
12 /* by GSA ADP Schedule Contract with IBM Corp.                      */
13 /*                                                                  */
14 /*  --------------------------------------------------------------- */
15 /*                                                                  */
16 /* end_generated_IBM_copyright_prolog                               */
17 /*  (C)Copyright IBM Corp.  2007, 2011  */
18 /**
19  * \file src/mpid_recvq.c
20  * \brief Functions to manage the Receive Queues
21  */
22 /*
23  *  (C) 2001 by Argonne National Laboratory.
24  *      See COPYRIGHT in top-level directory.
25  */
26 
27 #include <mpidimpl.h>
28 #include "mpid_recvq.h"
29 
30 /**
31  * \defgroup MPID_RECVQ MPID Receive Queue management
32  *
33  * Functions to manage the Receive Queues
34  */
35 
36 
37 /** \brief Structure to group the common recvq pointers */
38 struct MPIDI_Recvq_t MPIDI_Recvq;
39 
40 #ifdef HAVE_DEBUGGER_SUPPORT
41 struct MPID_Request ** const MPID_Recvq_posted_head_ptr =
42   &MPIDI_Recvq.posted_head;
43 struct MPID_Request ** const MPID_Recvq_unexpected_head_ptr =
44   &MPIDI_Recvq.unexpected_head;
45 #endif /* HAVE_DEBUGGER_SUPPORT */
46 
47 
48 /**
49  * \brief Set up the request queues
50  */
51 void
MPIDI_Recvq_init()52 MPIDI_Recvq_init()
53 {
54   MPIDI_Recvq.posted_head = NULL;
55   MPIDI_Recvq.posted_tail = NULL;
56   MPIDI_Recvq.unexpected_head = NULL;
57   MPIDI_Recvq.unexpected_tail = NULL;
58 }
59 
60 
61 /**
62  * \brief Tear down the request queues
63  */
64 void
MPIDI_Recvq_finalize()65 MPIDI_Recvq_finalize()
66 {
67   if(MPIDI_Process.statistics) MPIDI_Recvq_DumpQueues(MPIDI_Process.verbose);
68 }
69 
70 
71 /**
72  * \brief Find a request in the unexpected queue
73  * \param[in]  source     Find by Sender
74  * \param[in]  tag        Find by Tag
75  * \param[in]  context_id Find by Context ID (communicator)
76  * \return     1/0 if the matching UE request was found or not
77  */
78 int
MPIDI_Recvq_FU(int source,int tag,int context_id,MPI_Status * status)79 MPIDI_Recvq_FU(int source, int tag, int context_id, MPI_Status * status)
80 {
81   MPID_Request * rreq;
82   int found = FALSE;
83 #ifdef USE_STATISTICS
84   unsigned search_length = 0;
85 #endif
86 
87   if (tag != MPI_ANY_TAG && source != MPI_ANY_SOURCE)
88     {
89       rreq = MPIDI_Recvq.unexpected_head;
90       while (rreq != NULL) {
91 #ifdef USE_STATISTICS
92         ++search_length;
93 #endif
94         if ( (MPIDI_Request_getMatchCtxt(rreq) == context_id) &&
95              (MPIDI_Request_getMatchRank(rreq) == source    ) &&
96              (MPIDI_Request_getMatchTag(rreq)  == tag       )
97              )
98           {
99             found = TRUE;
100             if(status != MPI_STATUS_IGNORE)
101               *status = (rreq->status);
102             break;
103           }
104 
105         rreq = rreq->mpid.next;
106       }
107     }
108   else
109     {
110       MPIDI_Message_match match;
111       MPIDI_Message_match mask;
112 
113       match.context_id = context_id;
114       mask.context_id = ~0;
115       if (tag == MPI_ANY_TAG)
116         {
117           match.tag = 0;
118           mask.tag = 0;
119         }
120       else
121         {
122           match.tag = tag;
123           mask.tag = ~0;
124         }
125       if (source == MPI_ANY_SOURCE)
126         {
127           match.rank = 0;
128           mask.rank = 0;
129         }
130       else
131         {
132           match.rank = source;
133           mask.rank = ~0;
134         }
135 
136       rreq = MPIDI_Recvq.unexpected_head;
137       while (rreq != NULL) {
138 #ifdef USE_STATISTICS
139         ++search_length;
140 #endif
141         if ( (  MPIDI_Request_getMatchCtxt(rreq)              == match.context_id) &&
142              ( (MPIDI_Request_getMatchRank(rreq) & mask.rank) == match.rank      ) &&
143              ( (MPIDI_Request_getMatchTag(rreq)  & mask.tag ) == match.tag       )
144              )
145           {
146             found = TRUE;
147             if(status != MPI_STATUS_IGNORE)
148               *status = (rreq->status);
149             break;
150           }
151 
152         rreq = rreq->mpid.next;
153       }
154     }
155 
156 #ifdef USE_STATISTICS
157   MPIDI_Statistics_time(MPIDI_Statistics.recvq.unexpected_search, search_length);
158 #endif
159 
160   return found;
161 }
162 
163 
164 /**
165  * \brief Find a request in the unexpected queue and dequeue it
166  * \param[in]  req        Find by address of request object on sender
167  * \param[in]  source     Find by Sender
168  * \param[in]  tag        Find by Tag
169  * \param[in]  context_id Find by Context ID (communicator)
170  * \return     The matching UE request or NULL
171  */
172 MPID_Request *
MPIDI_Recvq_FDUR(MPI_Request req,int source,int tag,int context_id)173 MPIDI_Recvq_FDUR(MPI_Request req, int source, int tag, int context_id)
174 {
175   MPID_Request * prev_rreq          = NULL; /* previous request in queue */
176   MPID_Request * cur_rreq           = NULL; /* current request in queue */
177   MPID_Request * matching_cur_rreq  = NULL; /* matching request in queue */
178   MPID_Request * matching_prev_rreq = NULL; /* previous in queue to match */
179 #ifdef USE_STATISTICS
180   unsigned search_length = 0;
181 #endif
182 
183   /* ----------------------- */
184   /* first we do the finding */
185   /* ----------------------- */
186   cur_rreq = MPIDI_Recvq.unexpected_head;
187   while (cur_rreq != NULL) {
188 #ifdef USE_STATISTICS
189     ++search_length;
190 #endif
191     if (MPIDI_Request_getPeerRequestH(cur_rreq) == req        &&
192         MPIDI_Request_getMatchCtxt(cur_rreq)    == context_id &&
193         MPIDI_Request_getMatchRank(cur_rreq)    == source     &&
194         MPIDI_Request_getMatchTag(cur_rreq)     == tag)
195       {
196         matching_prev_rreq = prev_rreq;
197         matching_cur_rreq  = cur_rreq;
198         break;
199       }
200     prev_rreq = cur_rreq;
201     cur_rreq  = cur_rreq->mpid.next;
202   }
203 
204   /* ----------------------- */
205   /* found nothing; return   */
206   /* ----------------------- */
207   if (matching_cur_rreq == NULL)
208     goto fn_exit;
209 
210   MPIDI_Recvq_remove(MPIDI_Recvq.unexpected, matching_cur_rreq, matching_prev_rreq);
211 
212  fn_exit:
213 #ifdef USE_STATISTICS
214   MPIDI_Statistics_time(MPIDI_Statistics.recvq.unexpected_search, search_length);
215 #endif
216 
217   return matching_cur_rreq;
218 }
219 
220 
221 /**
222  * \brief Out of band part of find a request in the unexpected queue and dequeue it, or allocate a new request and enqueue it in the posted queue
223  * \param[in]  source     Find by Sender
224  * \param[in]  tag        Find by Tag
225  * \param[in]  context_id Find by Context ID (communicator)
226  * \param[out] foundp    TRUE iff the request was found
227  * \return     The matching UE request or the new posted request
228  */
229 #ifndef OUT_OF_ORDER_HANDLING
230 MPID_Request *
MPIDI_Recvq_FDU(int source,int tag,int context_id,int * foundp)231 MPIDI_Recvq_FDU(int source, int tag, int context_id, int * foundp)
232 #else
233 MPID_Request *
234 MPIDI_Recvq_FDU(int source, pami_task_t pami_source, int tag, int context_id, int * foundp)
235 #endif
236 {
237   int found = FALSE;
238   MPID_Request * rreq = NULL;
239   MPID_Request * prev_rreq;
240 #ifdef USE_STATISTICS
241   unsigned search_length = 0;
242 #endif
243 #ifdef OUT_OF_ORDER_HANDLING
244   MPIDI_In_cntr_t *in_cntr;
245   uint nMsgs=0;
246 
247   if(pami_source != MPI_ANY_SOURCE) {
248     in_cntr=&MPIDI_In_cntr[pami_source];
249     nMsgs = in_cntr->nMsgs + 1;
250   }
251 #endif
252 
253   //This function is typically called when there are unexp recvs
254   if (tag != MPI_ANY_TAG && source != MPI_ANY_SOURCE)
255     {
256       prev_rreq = NULL;
257       rreq = MPIDI_Recvq.unexpected_head;
258       while (rreq != NULL) {
259 #ifdef USE_STATISTICS
260         ++search_length;
261 #endif
262 #ifdef OUT_OF_ORDER_HANDLING
263         if( ((int)(nMsgs-MPIDI_Request_getMatchSeq(rreq))) >= 0 ) {
264 #endif
265         if ( (MPIDI_Request_getMatchCtxt(rreq) == context_id) &&
266              (MPIDI_Request_getMatchRank(rreq) == source    ) &&
267              (MPIDI_Request_getMatchTag(rreq)  == tag       )
268              )
269           {
270 #ifdef OUT_OF_ORDER_HANDLING
271             if(rreq->mpid.nextR != NULL) {       /* recv is in the out of order list */
272               if (MPIDI_Request_getMatchSeq(rreq) == nMsgs) {
273                 in_cntr->nMsgs=nMsgs;
274               }
275               MPIDI_Recvq_remove_req_from_ool(rreq,in_cntr);
276             }
277 #endif
278             MPIDI_Recvq_remove(MPIDI_Recvq.unexpected, rreq, prev_rreq);
279             found = TRUE;
280 #ifdef MPIDI_TRACE
281             MPIDI_In_cntr[(rreq->mpid.partner_id)].R[(rreq->mpid.idx)].matchedInUQ2=1;
282 #endif
283             goto fn_exit;
284           }
285 #ifdef OUT_OF_ORDER_HANDLING
286        }
287 #endif
288 
289         prev_rreq = rreq;
290         rreq = rreq->mpid.next;
291       }
292     }
293   else
294     {
295       MPIDI_Message_match match;
296       MPIDI_Message_match mask;
297 
298       match.context_id = context_id;
299       mask.context_id = ~0;
300       if (tag == MPI_ANY_TAG)
301         {
302           match.tag = 0;
303           mask.tag = 0;
304         }
305       else
306         {
307           match.tag = tag;
308           mask.tag = ~0;
309         }
310       if (source == MPI_ANY_SOURCE)
311         {
312           match.rank = 0;
313           mask.rank = 0;
314         }
315       else
316         {
317           match.rank = source;
318           mask.rank = ~0;
319         }
320 
321       prev_rreq = NULL;
322       rreq = MPIDI_Recvq.unexpected_head;
323       while (rreq != NULL) {
324 #ifdef USE_STATISTICS
325         ++search_length;
326 #endif
327 #ifdef OUT_OF_ORDER_HANDLING
328         if(( ( (int)(nMsgs-MPIDI_Request_getMatchSeq(rreq))) >= 0) || (source == MPI_ANY_SOURCE)) {
329 #endif
330         if ( (  MPIDI_Request_getMatchCtxt(rreq)              == match.context_id) &&
331              ( (MPIDI_Request_getMatchRank(rreq) & mask.rank) == match.rank      ) &&
332              ( (MPIDI_Request_getMatchTag(rreq)  & mask.tag ) == match.tag       )
333              )
334           {
335 #ifdef OUT_OF_ORDER_HANDLING
336             if(source == MPI_ANY_SOURCE) {
337               in_cntr = &MPIDI_In_cntr[MPIDI_Request_getPeerRank_pami(rreq)];
338               nMsgs = in_cntr->nMsgs+1;
339               if((int) (nMsgs-MPIDI_Request_getMatchSeq(rreq)) < 0 )
340                  goto NEXT_MSG;
341             }
342             if (rreq->mpid.nextR != NULL)  { /* recv is in the out of order list */
343               if (MPIDI_Request_getMatchSeq(rreq) == nMsgs)
344                 in_cntr->nMsgs=nMsgs;
345               MPIDI_Recvq_remove_req_from_ool(rreq,in_cntr);
346             }
347 #endif
348             MPIDI_Recvq_remove(MPIDI_Recvq.unexpected, rreq, prev_rreq);
349             found = TRUE;
350             goto fn_exit;
351           }
352 #ifdef OUT_OF_ORDER_HANDLING
353         }
354      NEXT_MSG:
355 #endif
356         prev_rreq = rreq;
357         rreq = rreq->mpid.next;
358       }
359     }
360 
361  fn_exit:
362 #ifdef USE_STATISTICS
363   MPIDI_Statistics_time(MPIDI_Statistics.recvq.unexpected_search, search_length);
364 #endif
365 
366   *foundp = found;
367   return rreq;
368 }
369 
370 
371 /**
372  * \brief Find a request in the posted queue and dequeue it
373  * \param[in]  req        Find by address of request object on sender
374  * \return     The matching posted request or NULL
375  */
376 int
MPIDI_Recvq_FDPR(MPID_Request * req)377 MPIDI_Recvq_FDPR(MPID_Request * req)
378 {
379   MPID_Request * cur_rreq  = NULL;
380   MPID_Request * prev_rreq = NULL;
381   int found = FALSE;
382 #ifdef USE_STATISTICS
383   unsigned search_length = 0;
384 #endif
385 
386   cur_rreq = MPIDI_Recvq.posted_head;
387 
388   while (cur_rreq != NULL) {
389 #ifdef USE_STATISTICS
390     ++search_length;
391 #endif
392     if (cur_rreq == req)
393       {
394         MPIDI_Recvq_remove(MPIDI_Recvq.posted, cur_rreq, prev_rreq);
395         found = TRUE;
396         break;
397       }
398 
399     prev_rreq = cur_rreq;
400     cur_rreq = cur_rreq->mpid.next;
401   }
402 
403 #ifdef USE_STATISTICS
404   MPIDI_Statistics_time(MPIDI_Statistics.recvq.posted_search, search_length);
405 #endif
406 
407   return found;
408 }
409 
410 
411 /**
412  * \brief Find a request in the posted queue and dequeue it, or allocate a new request and enqueue it in the unexpected queue
413  * \param[in]  source     Find by Sender
414  * \param[in]  tag        Find by Tag
415  * \param[in]  context_id Find by Context ID (communicator)
416  * \param[out] foundp    TRUE iff the request was found
417  * \return     The matching posted request or the new UE request
418  */
419 #ifndef OUT_OF_ORDER_HANDLING
420 MPID_Request *
MPIDI_Recvq_FDP_or_AEU(MPID_Request * newreq,int source,int tag,int context_id,int * foundp)421 MPIDI_Recvq_FDP_or_AEU(MPID_Request *newreq, int source, int tag, int context_id, int * foundp)
422 #else
423 MPID_Request *
424 MPIDI_Recvq_FDP_or_AEU(MPID_Request *newreq, int source, pami_task_t pami_source, int tag, int context_id, int msg_seqno, int * foundp)
425 #endif
426 {
427   MPID_Request * rreq;
428   int found = FALSE;
429 
430 #ifndef OUT_OF_ORDER_HANDLING
431   rreq = MPIDI_Recvq_FDP(source, tag, context_id);
432 #else
433   rreq = MPIDI_Recvq_FDP(source, pami_source, tag, context_id, msg_seqno);
434 #endif
435 
436   if (rreq != NULL) {
437       found = TRUE;
438   } else {
439 #ifndef OUT_OF_ORDER_HANDLING
440       rreq = MPIDI_Recvq_AEU(newreq, source, tag, context_id);
441 #else
442       rreq = MPIDI_Recvq_AEU(newreq, source, pami_source, tag, context_id, msg_seqno);
443 #endif
444   }
445   *foundp = found;
446   return rreq;
447 }
448 
449 
450 /**
451  * \brief Allocate a new request and enqueue it in the unexpected queue
452  * \param[in]  source     Find by Sender
453  * \param[in]  tag        Find by Tag
454  * \param[in]  context_id Find by Context ID (communicator)
455  * \return     The matching posted request or the new UE request
456  */
457 #ifndef OUT_OF_ORDER_HANDLING
458 MPID_Request *
MPIDI_Recvq_AEU(MPID_Request * newreq,int source,int tag,int context_id)459 MPIDI_Recvq_AEU(MPID_Request *newreq, int source, int tag, int context_id)
460 #else
461 MPID_Request *
462 MPIDI_Recvq_AEU(MPID_Request *newreq, int source, pami_task_t pami_source, int tag, int context_id, int msg_seqno)
463 #endif
464 {
465   /* A matching request was not found in the posted queue, so we
466      need to allocate a new request and add it to the unexpected
467      queue */
468   MPID_Request *rreq;
469   rreq = newreq;
470   rreq->kind = MPID_REQUEST_RECV;
471 #ifdef  MPIDI_TRACE
472   rreq->mpid.envelope.msginfo.MPIseqno=-1;
473   rreq->mpid.envelope.length=0;
474   rreq->mpid.envelope.data=NULL;
475 #endif
476 #ifndef OUT_OF_ORDER_HANDLING
477   MPIDI_Request_setMatch(rreq, tag, source, context_id);
478   MPIDI_Recvq_append(MPIDI_Recvq.unexpected, rreq);
479 #else
480   MPID_Request *q;
481   MPIDI_In_cntr_t *in_cntr;
482   int insert, i;
483 #ifdef MPIDI_TRACE
484   int idx;
485   idx=(msg_seqno & SEQMASK);
486   recv_status *rstatus;
487   rstatus=&MPIDI_In_cntr[pami_source].R[idx];
488   memset(rstatus,0,sizeof(recv_status));
489 #endif
490 
491 
492   in_cntr = &MPIDI_In_cntr[pami_source];
493   MPIDI_Request_setMatch(rreq, tag, source, context_id); /* mpi rank needed */
494   MPIDI_Request_setPeerRank_pami(rreq, pami_source);
495   MPIDI_Request_setPeerRank_comm(rreq, source);
496   MPIDI_Request_setMatchSeq(rreq, msg_seqno);
497 
498   if (!in_cntr->n_OutOfOrderMsgs) {
499     MPIDI_Recvq_append(MPIDI_Recvq.unexpected, rreq);
500   } else {
501     q=in_cntr->OutOfOrderList;
502     insert=0;
503     for (i=1; i<=in_cntr->n_OutOfOrderMsgs; i++) {
504       if ( context_id == MPIDI_Request_getMatchCtxt(q)) {
505         if (((int)(msg_seqno - MPIDI_Request_getMatchSeq(q))) < 0) {
506            MPIDI_Recvq_insert(MPIDI_Recvq.unexpected, q, rreq);
507            insert=1;
508            break;
509         }
510       }
511       q=q->mpid.nextR;
512     }
513     if (!insert) {
514       MPIDI_Recvq_append(MPIDI_Recvq.unexpected, rreq);
515     }
516    }
517 #ifdef MPIDI_TRACE
518    rstatus->req=rreq;
519    rstatus->msgid=msg_seqno;
520    rstatus->ool=1;
521    rstatus->rtag=tag;
522    rstatus->rctx=context_id;
523    rreq->mpid.idx=idx;
524    rstatus->rsource=pami_source;
525    rreq->mpid.partner_id=pami_source;
526 #endif
527 
528   if (((int)(in_cntr->nMsgs - msg_seqno)) < 0) { /* seqno > nMsgs, out of order */
529     MPIDI_Recvq_enqueue_ool(pami_source,rreq);
530   }
531 #endif
532 
533   return rreq;
534 }
535 
536 
537 /**
538  * \brief Dump the queues
539  */
540 void
MPIDI_Recvq_DumpQueues(int verbose)541 MPIDI_Recvq_DumpQueues(int verbose)
542 {
543   if(verbose < MPIDI_VERBOSE_SUMMARY_ALL)
544     return;
545 
546   MPID_Request * rreq = MPIDI_Recvq.posted_head;
547   MPID_Request * prev_rreq = NULL;
548   unsigned i=0, numposted=0, numue=0;
549   unsigned postedbytes=0, uebytes=0;
550 
551   if(verbose >= MPIDI_VERBOSE_DETAILS_ALL)
552     fprintf(stderr,"Posted Queue:\n-------------\n");
553   while (rreq != NULL) {
554     if(verbose >= MPIDI_VERBOSE_DETAILS_ALL)
555       fprintf(stderr, "P %d: MPItag=%d MPIrank=%d ctxt=%d count=%d\n",
556               i++,
557               MPIDI_Request_getMatchTag(rreq),
558               MPIDI_Request_getMatchRank(rreq),
559               MPIDI_Request_getMatchCtxt(rreq),
560               rreq->mpid.userbufcount
561               );
562     numposted++;
563     postedbytes+=rreq->mpid.userbufcount;
564     prev_rreq = rreq;
565     rreq = rreq->mpid.next;
566   }
567   fprintf(stderr, "Posted Requests %d, Total Mem: %d bytes\n",
568           numposted, postedbytes);
569 
570 
571   i=0;
572   rreq = MPIDI_Recvq.unexpected_head;
573   if(verbose >= MPIDI_VERBOSE_DETAILS_ALL)
574     fprintf(stderr, "Unexpected Queue:\n-----------------\n");
575   while (rreq != NULL) {
576     if(verbose >= MPIDI_VERBOSE_DETAILS_ALL)
577 #ifndef OUT_OF_ORDER_HANDLING
578       fprintf(stderr, "UE %d: MPItag=%d MPIrank=%d ctxt=%d uebuf=%p uebuflen=%u\n",
579               i++,
580               MPIDI_Request_getMatchTag(rreq),
581               MPIDI_Request_getMatchRank(rreq),
582               MPIDI_Request_getMatchCtxt(rreq),
583               rreq->mpid.uebuf,
584               rreq->mpid.uebuflen);
585 #else
586       fprintf(stderr, "UE %d: MPItag=%d MPIrank=%d pami_task_id=%d MPIseq=%d ctxt=%d uebuf=%p uebuflen=%u\n",
587               i++,
588               MPIDI_Request_getMatchTag(rreq),
589               MPIDI_Request_getMatchRank(rreq),
590               MPIDI_Request_getPeerRank_pami(rreq),
591               MPIDI_Request_getMatchSeq(rreq),
592               MPIDI_Request_getMatchCtxt(rreq),
593               rreq->mpid.uebuf,
594               rreq->mpid.uebuflen);
595 #endif
596     numue++;
597     uebytes+=rreq->mpid.uebuflen;
598     prev_rreq = rreq;
599     rreq = rreq->mpid.next;
600   }
601   fprintf(stderr, "Unexpected Requests %d, Total Mem: %d bytes\n",
602           numue, uebytes);
603 }
604 
605 
606 #ifdef OUT_OF_ORDER_HANDLING
607 /**
608  * Insert a request in the OutOfOrderList, make sure this list is
609  * arranged in the ascending order.
610  */
MPIDI_Recvq_enqueue_ool(pami_task_t src,MPID_Request * req)611 void MPIDI_Recvq_enqueue_ool(pami_task_t src, MPID_Request *req)
612 {
613   MPID_Request  *q;
614   void *head;
615   int insert,i;
616   MPIDI_In_cntr_t *in_cntr;
617 
618   in_cntr=&MPIDI_In_cntr[src];
619   if (in_cntr->n_OutOfOrderMsgs != 0) {
620     head=in_cntr->OutOfOrderList;
621     q=in_cntr->OutOfOrderList;
622     insert=0;
623     MPID_assert(q->mpid.nextR != NULL);
624     while(q->mpid.nextR != head) {
625       if (((int)(MPIDI_Request_getMatchSeq(q) - MPIDI_Request_getMatchSeq(req))) > 0) {
626         insert=1;
627         break;
628       }
629       q=q->mpid.nextR;
630     }
631     if (insert) {
632       MPIDI_Recvq_insert_ool(q,req);
633       if (q == head) { /* 1st element in the list */
634         in_cntr->OutOfOrderList=req;
635       }
636     } else {
637       if (((int)(MPIDI_Request_getMatchSeq(q) - MPIDI_Request_getMatchSeq(req))) > 0) {
638         MPIDI_Recvq_insert_ool(q,req);
639         if (q == head) { /* 1st element in the list */
640           in_cntr->OutOfOrderList=req;
641         }
642       } else {
643         MPIDI_Recvq_insert_ool((MPID_Request *)q->mpid.nextR,req);
644       }
645     }
646   } else {   /*  empty list    */
647     in_cntr->OutOfOrderList=req;
648     req->mpid.prevR=req;
649     req->mpid.nextR=req;
650   }
651   in_cntr->n_OutOfOrderMsgs++;
652 #if (MPIDI_STATISTICS)
653   MPID_NSTAT(mpid_statp->unorderedMsgs);
654 #endif
655 } /* void MPIDI_Recvq_insert_ool(pami_task_t src, MPID_Request *N) */
656 
657 
658 /**
659  *  MPIDI_Recvq_insert_ool: place e between q and q->prevR
660  *
661  */
MPIDI_Recvq_insert_ool(MPID_Request * q,MPID_Request * e)662 void  MPIDI_Recvq_insert_ool(MPID_Request *q,MPID_Request *e)
663 {
664   (e)->mpid.prevR = (q)->mpid.prevR;
665   ((MPID_Request *)((q)->mpid.prevR))->mpid.nextR = (e);
666   (e)->mpid.nextR = (q);
667   (q)->mpid.prevR = (e);
668 }
669 #endif
670