Hi,

   I did a rewrite of matching code in OB1. I made it much simpler and 2
times smaller (which is good, less code - less bugs). I also got rid
of huge macros - very helpful if you need to debug something. There
is no performance degradation, actually I even see very small performance
improvement. I ran MTT with this patch and the result is the same as on
trunk. I would like to commit this to the trunk. The patch is attached
for everybody to try.

--
                        Gleb.
diff --git a/ompi/mca/pml/ob1/pml_ob1_recvfrag.c b/ompi/mca/pml/ob1/pml_ob1_recvfrag.c
index d3f7c37..299ae9e 100644
--- a/ompi/mca/pml/ob1/pml_ob1_recvfrag.c
+++ b/ompi/mca/pml/ob1/pml_ob1_recvfrag.c
@@ -184,244 +184,159 @@ void mca_pml_ob1_recv_frag_callback( mca_btl_base_module_t* btl,
     }
 }

-/**
- * Try and match the incoming message fragment to a generic
- * list of receives
- *
- * @param hdr Matching data from received fragment (IN)
- *
- * @param generic_receives Pointer to the receive list used for
- * matching purposes. (IN)
- *
- * @return Matched receive
- *
- * This routine assumes that the appropriate matching locks are
- * set by the upper level routine.
- */
-#define MCA_PML_OB1_MATCH_GENERIC_RECEIVES(hdr,generic_receives,proc,return_match) \
-    do {                                                                           \
-        /* local variables */                                                      \
-        mca_pml_ob1_recv_request_t *generic_recv = (mca_pml_ob1_recv_request_t *)  \
-                     opal_list_get_first(generic_receives);                        \
-        mca_pml_ob1_recv_request_t *last_recv = (mca_pml_ob1_recv_request_t *)     \
-            opal_list_get_end(generic_receives);                                   \
-        register int recv_tag, frag_tag = hdr->hdr_tag;                            \
-                                                                                   \
-        /* Loop over the receives. If the received tag is less than zero  */       \
-        /* enter in a special mode, where we match only our internal tags */       \
-        /* (such as those used by the collectives.*/                               \
-        if( 0 <= frag_tag ) {                                                      \
-            for( ; generic_recv != last_recv;                                      \
-                 generic_recv = (mca_pml_ob1_recv_request_t *)                     \
-                     ((opal_list_item_t *)generic_recv)->opal_list_next) {         \
-                /* Check for a match */                                            \
-                recv_tag = generic_recv->req_recv.req_base.req_tag;                \
-                if ( (frag_tag == recv_tag) || (recv_tag == OMPI_ANY_TAG) ) {      \
-                    break;                                                         \
-                }                                                                  \
-            }                                                                      \
-        } else {                                                                   \
-            for( ; generic_recv != last_recv;                                      \
-                 generic_recv = (mca_pml_ob1_recv_request_t *)                     \
-                     ((opal_list_item_t *)generic_recv)->opal_list_next) {         \
-                /* Check for a match */                                            \
-                recv_tag = generic_recv->req_recv.req_base.req_tag;                \
-                if( OPAL_UNLIKELY(frag_tag == recv_tag) ) {                        \
-                    break;                                                         \
-                }                                                                  \
-            }                                                                      \
-        }                                                                          \
-        if( generic_recv != (mca_pml_ob1_recv_request_t *)                         \
-            opal_list_get_end(generic_receives) ) {                                \
-                                                                                   \
-            /* Match made */                                                       \
-            return_match = generic_recv;                                           \
-                                                                                   \
-            /* remove descriptor from posted specific ireceive list */             \
-            opal_list_remove_item(generic_receives,                                \
-                                  (opal_list_item_t *)generic_recv);               \
-            PERUSE_TRACE_COMM_EVENT (PERUSE_COMM_REQ_REMOVE_FROM_POSTED_Q,         \
-                                     &(generic_recv->req_recv.req_base),           \
-                                     PERUSE_RECV);                                 \
-                                                                                   \
-        }                                                                          \
-    } while(0)
+#define PML_MAX_SEQ ~((mca_pml_sequence_t)0);

-/**
- * Try and match the incoming message fragment to the list of
- * "wild" receives
- *
- * @param hdr Matching data from recived fragment (IN)
- *
- * @param pml_comm Pointer to the communicator structure used for
- * matching purposes. (IN)
- *
- * @return Matched receive
- *
- * This routine assumes that the appropriate matching locks are
- * set by the upper level routine.
- */
+static inline mca_pml_ob1_recv_request_t* get_posted_recv(opal_list_t *queue)
+{
+    if(opal_list_get_size(queue) == 0)
+        return NULL;

-#define MCA_PML_OB1_CHECK_WILD_RECEIVES_FOR_MATCH(hdr,comm,proc,return_match)    \
-    do {                                                                         \
-        /* local parameters */                                                   \
-        opal_list_t* wild_receives = &comm->wild_receives;                       \
-        MCA_PML_OB1_MATCH_GENERIC_RECEIVES(hdr,wild_receives,proc,return_match); \
-    } while(0)
+    return (mca_pml_ob1_recv_request_t*)opal_list_get_first(queue);
+}

+static inline mca_pml_ob1_recv_request_t* get_next_posted_recv(
+        opal_list_t *queue,
+        mca_pml_ob1_recv_request_t* req)
+{
+    opal_list_item_t *i = opal_list_get_next((opal_list_item_t*)req);

-/**
- * Try and match the incoming message fragment to the list of
- * "specific" receives
- *
- * @param hdr Matching data from recived fragment (IN)
- *
- * @param comm Pointer to the communicator structure used for
- * matching purposes. (IN)
- *
- * @return Matched receive
- *
- * This routine assumes that the appropriate matching locks are
- * set by the upper level routine.
- */
-#define MCA_PML_OB1_CHECK_SPECIFIC_RECEIVES_FOR_MATCH(hdr,comm,proc,return_match)    \
-    do {                                                                             \
-        /* local variables */                                                        \
-        opal_list_t* specific_receives = &proc->specific_receives;                   \
-        MCA_PML_OB1_MATCH_GENERIC_RECEIVES(hdr,specific_receives,proc,return_match); \
-    } while(0)
+    if(opal_list_get_end(queue) == i)
+        return NULL;

-/**
- * Try and match the incoming message fragment to the list of
- * "wild" receives and "specific" receives.  Used when both types
- * of receives have been posted,  i.e. when we need to coordinate
- * between multiple lists to make sure ordered delivery occurs.
- *
- * @param hdr Matching data from recived fragment (IN)
- *
- * @param comm Pointer to the communicator structure used for
- * matching purposes. (IN)
- *
- * @return Matched receive
- *
- * This routine assumes that the appropriate matching locks are
- * set by the upper level routine.
- */
+    return (mca_pml_ob1_recv_request_t*)i;
+}

-#define MCA_PML_OB1_CHECK_SPECIFIC_AND_WILD_RECEIVES_FOR_MATCH( hdr,comm,proc,return_match) \
-    do {                                                                \
-        /* local variables */                                           \
-        mca_pml_ob1_recv_request_t *specific_recv, *wild_recv;          \
-        mca_pml_sequence_t wild_recv_seq, specific_recv_seq;            \
-        int frag_tag, wild_recv_tag, specific_recv_tag;                 \
-                                                                        \
-        /* initialization */                                            \
-        frag_tag=hdr->hdr_tag;                                          \
-                                                                        \
-        /*                                                              \
-         * We know that when this is called, both specific and wild irecvs \
-         *  have been posted.                                           \
-         */                                                             \
-        specific_recv = (mca_pml_ob1_recv_request_t *)                  \
-            opal_list_get_first(&(proc)->specific_receives);            \
-        wild_recv = (mca_pml_ob1_recv_request_t *)                      \
-            opal_list_get_first(&comm->wild_receives);                  \
-                                                                        \
-        specific_recv_seq = specific_recv->req_recv.req_base.req_sequence; \
-        wild_recv_seq = wild_recv->req_recv.req_base.req_sequence;      \
-                                                                        \
-        while (true) {                                                  \
-            if (wild_recv_seq < specific_recv_seq) {                    \
-                /* wild recv is earlier than the specific one. */       \
-                /* try and match */                                     \
-                wild_recv_tag = wild_recv->req_recv.req_base.req_tag;   \
-                if ( (frag_tag == wild_recv_tag) ||                     \
-                     ( (wild_recv_tag == OMPI_ANY_TAG) && (0 <= frag_tag) ) ) { \
-                    /* Match made */                                    \
-                    return_match=wild_recv;                             \
-                                                                        \
-                    /* remove this recv from the wild receive queue */  \
-                    opal_list_remove_item(&comm->wild_receives,         \
-                                          (opal_list_item_t *)wild_recv); \
-                                                                        \
-                    PERUSE_TRACE_COMM_EVENT (PERUSE_COMM_REQ_REMOVE_FROM_POSTED_Q, \
-                                             &(wild_recv->req_recv.req_base), \
-                                             PERUSE_RECV);              \
-                                                                        \
-                    break;                                              \
-                }                                                       \
-                                                                        \
-                /* No match, go to the next */                          \
-                wild_recv=(mca_pml_ob1_recv_request_t *)                \
-                    ((opal_list_item_t *)wild_recv)->opal_list_next;    \
-                                                                        \
-                /*                                                      \
-                 * If that was the last wild one, just look at the      \
-                 * rest of the specific ones.                           \
-                 */                                                     \
-                if (wild_recv == (mca_pml_ob1_recv_request_t *)         \
-                    opal_list_get_end(&comm->wild_receives) )           \
-                    {                                                   \
-                        MCA_PML_OB1_CHECK_SPECIFIC_RECEIVES_FOR_MATCH(hdr, comm, proc, return_match); \
-                        break;                                          \
-                    }                                                   \
-                                                                        \
-                /*                                                      \
-                 * Get the sequence number for this recv, and go        \
-                 * back to the top of the loop.                         \
-                 */                                                     \
-                wild_recv_seq = wild_recv->req_recv.req_base.req_sequence; \
-                                                                        \
-            } else {                                                    \
-                /* specific recv is earlier than the wild one. */       \
-                specific_recv_tag=specific_recv->req_recv.req_base.req_tag; \
-                if ( (frag_tag == specific_recv_tag) ||                 \
-                     ( (specific_recv_tag == OMPI_ANY_TAG) && (0<=frag_tag)) ) \
-                    {                                                   \
-                        /* Match made */                                \
-                        return_match = specific_recv;                   \
-                        /* remove descriptor from specific receive list */ \
-                        opal_list_remove_item(&(proc)->specific_receives, \
-                                              (opal_list_item_t *)specific_recv); \
-                                                                        \
-                        PERUSE_TRACE_COMM_EVENT (PERUSE_COMM_REQ_REMOVE_FROM_POSTED_Q, \
-                                                 &(specific_recv->req_recv.req_base), \
-                                                 PERUSE_RECV);          \
-                                                                        \
-                        break;                                          \
-                    }                                                   \
-                                                                        \
-                /* No match, go on to the next specific irecv. */       \
-                specific_recv = (mca_pml_ob1_recv_request_t *)          \
-                    ((opal_list_item_t *)specific_recv)->opal_list_next; \
-                                                                        \
-                /*                                                      \
-                 * If that was the last specific irecv, process the     \
-                 * rest of the wild ones.                               \
-                 */                                                     \
-                if (specific_recv == (mca_pml_ob1_recv_request_t *)     \
-                    opal_list_get_end(&(proc)->specific_receives))      \
-                    {                                                   \
-                        MCA_PML_OB1_CHECK_WILD_RECEIVES_FOR_MATCH(hdr, comm, proc, return_match); \
-                        break;                                          \
-                    }                                                   \
-                /*                                                      \
-                 * Get the sequence number for this recv, and go        \
-                 * back to the top of the loop.                         \
-                 */                                                     \
-                specific_recv_seq = specific_recv->req_recv.req_base.req_sequence; \
-            }                                                           \
-        }                                                               \
-    } while(0)
+static mca_pml_ob1_recv_request_t *match_incomming(
+        mca_pml_ob1_match_hdr_t *hdr, mca_pml_ob1_comm_t *comm,
+        mca_pml_ob1_comm_proc_t *proc)
+{
+    mca_pml_ob1_recv_request_t *specific_recv, *wild_recv;
+    mca_pml_sequence_t wild_recv_seq, specific_recv_seq;
+    int tag = hdr->hdr_tag;
+
+    specific_recv = get_posted_recv(&proc->specific_receives);
+    wild_recv = get_posted_recv(&comm->wild_receives);
+
+    wild_recv_seq = wild_recv ?
+        wild_recv->req_recv.req_base.req_sequence : PML_MAX_SEQ;
+    specific_recv_seq = specific_recv ?
+        specific_recv->req_recv.req_base.req_sequence : PML_MAX_SEQ;
+
+    /* they are equal only if both are PML_MAX_SEQ */
+    while(wild_recv_seq != specific_recv_seq) {
+        mca_pml_ob1_recv_request_t **match;
+        opal_list_t *queue;
+        int req_tag;
+        mca_pml_sequence_t *seq;
+
+        if (OPAL_UNLIKELY(wild_recv_seq < specific_recv_seq)) {
+            match = &wild_recv;
+            queue = &comm->wild_receives;
+            seq = &wild_recv_seq;
+        } else {
+            match = &specific_recv;
+            queue = &proc->specific_receives;
+            seq = &specific_recv_seq;
+        }

+        req_tag = (*match)->req_recv.req_base.req_tag;
+        if(req_tag == tag || (req_tag == OMPI_ANY_TAG && tag >= 0)) {
+            opal_list_remove_item(queue, (opal_list_item_t*)(*match));
+            PERUSE_TRACE_COMM_EVENT(PERUSE_COMM_REQ_REMOVE_FROM_POSTED_Q,
+                    &((*match)->req_recv.req_base), PERUSE_RECV);
+            return *match;
+        }

-/*
- * Specialized matching routines for internal use only.
- */
+        *match = get_next_posted_recv(queue, *match);
+        *seq = (*match) ? (*match)->req_recv.req_base.req_sequence : PML_MAX_SEQ;
+    }

-static bool mca_pml_ob1_check_cantmatch_for_match( opal_list_t *additional_matches,
-                                                   mca_pml_ob1_comm_t* comm,
-                                                   mca_pml_ob1_comm_proc_t *proc );
+    return NULL;
+}
+
+static void append_frag_to_list(opal_list_t *queue, mca_btl_base_module_t *btl,
+        mca_pml_ob1_match_hdr_t *hdr, mca_btl_base_segment_t* segments,
+        size_t num_segments, mca_pml_ob1_recv_frag_t* frag)
+{
+    int rc;
+
+    if(NULL == frag) {
+        MCA_PML_OB1_RECV_FRAG_ALLOC(frag, rc);
+        MCA_PML_OB1_RECV_FRAG_INIT(frag, hdr, segments, num_segments, btl);
+    }
+    opal_list_append(queue, (opal_list_item_t*)frag);
+}
+
+static mca_pml_ob1_recv_request_t *match_one(mca_btl_base_module_t *btl,
+        mca_pml_ob1_match_hdr_t *hdr, mca_btl_base_segment_t* segments,
+        size_t num_segments, ompi_communicator_t *comm_ptr,
+        mca_pml_ob1_comm_proc_t *proc,
+        mca_pml_ob1_recv_frag_t* frag)
+{
+    mca_pml_ob1_recv_request_t *match;
+    mca_pml_ob1_comm_t *comm = (mca_pml_ob1_comm_t *)comm_ptr->c_pml_comm;
+
+    do {
+        match = match_incomming(hdr, comm, proc);
+
+        /* if match found, process data */
+        if(OPAL_UNLIKELY(NULL == match)) {
+            /* if no match found, place on unexpected queue */
+            append_frag_to_list(&proc->unexpected_frags, btl, hdr, segments,
+                    num_segments, frag);
+            PERUSE_TRACE_MSG_EVENT(PERUSE_COMM_MSG_INSERT_IN_UNEX_Q, comm_ptr,
+                                hdr->hdr_src, hdr->hdr_tag, PERUSE_RECV);
+            return NULL;
+        }
+
+        match->req_recv.req_base.req_proc = proc->ompi_proc;
+
+        if(MCA_PML_REQUEST_PROBE == match->req_recv.req_base.req_type) {
+            /* complete the probe */
+            mca_pml_ob1_recv_request_matched_probe(match, btl, segments,
+                    num_segments);
+            /* attempt to match actual request */
+            continue;
+        }
+
+        PERUSE_TRACE_COMM_EVENT(PERUSE_COMM_MSG_MATCH_POSTED_REQ,
+                &(match->req_recv.req_base), PERUSE_RECV);
+        break;
+    } while(true);
+
+    return match;
+}
+
+static mca_pml_ob1_recv_frag_t *check_cantmatch_for_match(
+        mca_pml_ob1_comm_proc_t *proc)
+{
+    /* local parameters */
+    mca_pml_ob1_recv_frag_t *frag;
+
+        /* search the list for a fragment from the send with sequence
+         * number next_msg_seq_expected
+         */
+    for(frag = (mca_pml_ob1_recv_frag_t *) 
+            opal_list_get_first(&proc->frags_cant_match);
+        frag != (mca_pml_ob1_recv_frag_t *)
+            opal_list_get_end(&proc->frags_cant_match);
+        frag = (mca_pml_ob1_recv_frag_t *) 
+            opal_list_get_next(frag))
+    {
+        mca_pml_ob1_match_hdr_t* hdr = &frag->hdr.hdr_match;
+        /*
+         * If the message has the next expected seq from that proc...
+         */
+        if(hdr->hdr_seq != proc->expected_sequence)
+            continue;
+
+
+        opal_list_remove_item(&proc->frags_cant_match, (opal_list_item_t*)frag);
+        return frag;
+    }
+
+    return NULL;
+}

 /**
  * RCS/CTS receive side matching
@@ -464,13 +379,11 @@ static int mca_pml_ob1_recv_frag_match( mca_btl_base_module_t *btl,
     mca_pml_ob1_recv_request_t *match = NULL;
     mca_pml_ob1_comm_t *comm;
     mca_pml_ob1_comm_proc_t *proc;
-    bool additional_match=false;
-    opal_list_t additional_matches;
-    int rc;
+    mca_pml_ob1_recv_frag_t* frag = NULL;

     /* communicator pointer */
     comm_ptr = ompi_comm_lookup(hdr->hdr_ctx);
-    if( OPAL_UNLIKELY(NULL == comm_ptr) ) {
+    if(OPAL_UNLIKELY(NULL == comm_ptr)) {
         /* This is a special case. A message for a not yet exiting communicator can
          * happens, but right now we segfault. Instead, and until we find a better
          * solution, just drop the message. However, in the near future we should
@@ -485,7 +398,7 @@ static int mca_pml_ob1_recv_frag_match( mca_btl_base_module_t *btl,

     /* source sequence number */
     frag_msg_seq = hdr->hdr_seq;
-    proc = comm->procs + hdr->hdr_src;
+    proc = &comm->procs[hdr->hdr_src];

     /**
      * We generate the MSG_ARRIVED event as soon as the PML is aware of a matching
@@ -493,7 +406,7 @@ static int mca_pml_ob1_recv_frag_match( mca_btl_base_module_t *btl,
      * This will allow the tools to figure out if the messages are not received in the
      * correct order (if multiple network interfaces).
      */
-    PERUSE_TRACE_MSG_EVENT( PERUSE_COMM_MSG_ARRIVED, comm_ptr,
+    PERUSE_TRACE_MSG_EVENT(PERUSE_COMM_MSG_ARRIVED, comm_ptr,
                             hdr->hdr_src, hdr->hdr_tag, PERUSE_RECV);

     /* get next expected message sequence number - if threaded
@@ -507,288 +420,70 @@ static int mca_pml_ob1_recv_frag_match( mca_btl_base_module_t *btl,

     /* get sequence number of next message that can be processed */
     next_msg_seq_expected = (uint16_t)proc->expected_sequence;
-    if( OPAL_LIKELY(frag_msg_seq == next_msg_seq_expected) ) {
-
-        /*
-         * This is the sequence number we were expecting,
-         * so we can try matching it to already posted
-         * receives.
-         */
-
-        /* We're now expecting the next sequence number. */
-        (proc->expected_sequence)++;
-
-        /**
-         * We generate the SEARCH_POSTED_QUEUE only when the message is received
-         * in the correct sequence. Otherwise, we delay the event generation until
-         * we reach the correct sequence number.
-         */
-        PERUSE_TRACE_MSG_EVENT( PERUSE_COMM_SEARCH_POSTED_Q_BEGIN, comm_ptr,
-                                hdr->hdr_src, hdr->hdr_tag, PERUSE_RECV);
-
-rematch:
+    if(OPAL_UNLIKELY(frag_msg_seq != next_msg_seq_expected))
+        goto wrong_seq;

-        /*
-         * figure out what sort of matching logic to use, if need to
-         *   look only at "specific" receives, or "wild" receives,
-         *   or if we need to traverse both sets at the same time.
-         */
-        if (opal_list_get_size(&proc->specific_receives) == 0 ){
-            /*
-             * There are only wild irecvs, so specialize the algorithm.
-             */
-            MCA_PML_OB1_CHECK_WILD_RECEIVES_FOR_MATCH(hdr, comm, proc, match);
-    
-        } else if (opal_list_get_size(&comm->wild_receives) == 0 ) {
-            /*
-             * There are only specific irecvs, so specialize the algorithm.
-             */
-            MCA_PML_OB1_CHECK_SPECIFIC_RECEIVES_FOR_MATCH(hdr, comm, proc, match);
-        } else {
-            /*
-             * There are some of each.
-             */
-            MCA_PML_OB1_CHECK_SPECIFIC_AND_WILD_RECEIVES_FOR_MATCH(hdr, comm, proc, match);
-        }
-
-        /* if match found, process data */
-        if( OPAL_LIKELY(match) ) {
-            match->req_recv.req_base.req_proc = proc->ompi_proc;
-
-            /*
-             * update delivered sequence number information, if needed.
-             */
-            if( (match->req_recv.req_base.req_type == MCA_PML_REQUEST_PROBE) ) {
-
-                /* complete the probe */
-                mca_pml_ob1_recv_request_matched_probe(match,btl,segments,num_segments);
-
-                /* attempt to match actual request */
-                match = NULL;
-                goto rematch;
-            } else {
-                if( (match->req_recv.req_base.req_type != MCA_PML_REQUEST_IPROBE) ) {
-                    PERUSE_TRACE_COMM_EVENT( PERUSE_COMM_MSG_MATCH_POSTED_REQ,
-                                              &(match->req_recv.req_base), PERUSE_RECV);
-                }
-            }
+    /*
+     * This is the sequence number we were expecting,
+     * so we can try matching it to already posted
+     * receives.
+     */

-        } else {
+out_of_order_match:
+    /* We're now expecting the next sequence number. */
+    proc->expected_sequence++;

-            /* if no match found, place on unexpected queue */
-            mca_pml_ob1_recv_frag_t* frag;
-            MCA_PML_OB1_RECV_FRAG_ALLOC(frag, rc);
-            if( OPAL_UNLIKELY(OMPI_SUCCESS != rc) ) {
-                OPAL_THREAD_UNLOCK(&comm->matching_lock);
-                /**
-                 * As we return from the match function, we should generate the expected event.
-                 */
-                PERUSE_TRACE_MSG_EVENT( PERUSE_COMM_SEARCH_POSTED_Q_END, comm_ptr,
-                                        hdr->hdr_src, hdr->hdr_tag, PERUSE_RECV);
-
-                return rc;
-            }
-            MCA_PML_OB1_RECV_FRAG_INIT(frag,hdr,segments,num_segments,btl);
-            opal_list_append( &proc->unexpected_frags, (opal_list_item_t *)frag );
-        }
-
-        /**
-         * The match is over. We generate the SEARCH_POSTED_Q_END here, before going
-         * into the mca_pml_ob1_check_cantmatch_for_match so we can make a difference
-         * for the searching time for all messages.
-         */
-        PERUSE_TRACE_MSG_EVENT( PERUSE_COMM_SEARCH_POSTED_Q_END, comm_ptr,
-                                hdr->hdr_src, hdr->hdr_tag, PERUSE_RECV);
-
-        /* 
-         * Now that new message has arrived, check to see if
-         *   any fragments on the c_c_frags_cant_match list
-         *   may now be used to form new matchs
-         */
-        if( OPAL_UNLIKELY(0 < opal_list_get_size(&proc->frags_cant_match)) ) {
-            additional_match = mca_pml_ob1_check_cantmatch_for_match(&additional_matches,comm,proc);
-        }
+    /**
+     * We generate the SEARCH_POSTED_QUEUE only when the message is received
+     * in the correct sequence. Otherwise, we delay the event generation until
+     * we reach the correct sequence number.
+     */
+    PERUSE_TRACE_MSG_EVENT(PERUSE_COMM_SEARCH_POSTED_Q_BEGIN, comm_ptr,
+                            hdr->hdr_src, hdr->hdr_tag, PERUSE_RECV);

-    } else {
+    match = match_one(btl, hdr, segments, num_segments, comm_ptr, proc, frag);

-        /*
-         * This message comes after the next expected, so it
-         * is ahead of sequence.  Save it for later.
-         */
-        mca_pml_ob1_recv_frag_t* frag;
-        MCA_PML_OB1_RECV_FRAG_ALLOC(frag, rc);
-        if( OPAL_UNLIKELY(OMPI_SUCCESS != rc) ) {
-            OPAL_THREAD_UNLOCK(&comm->matching_lock);
-            return rc;
-        }
-        MCA_PML_OB1_RECV_FRAG_INIT(frag,hdr,segments,num_segments,btl);
-        opal_list_append(&proc->frags_cant_match, (opal_list_item_t *)frag);
+    /**
+     * The match is over. We generate the SEARCH_POSTED_Q_END here, before going
+     * into the mca_pml_ob1_check_cantmatch_for_match so we can make a difference
+     * for the searching time for all messages.
+     */
+    PERUSE_TRACE_MSG_EVENT(PERUSE_COMM_SEARCH_POSTED_Q_END, comm_ptr,
+                            hdr->hdr_src, hdr->hdr_tag, PERUSE_RECV);

-    }
     /* release matching lock before processing fragment */
     OPAL_THREAD_UNLOCK(&comm->matching_lock);

-    if( OPAL_LIKELY(match != NULL) ) {
-        mca_pml_ob1_recv_request_progress(match,btl,segments,num_segments);
-    } else {
-        PERUSE_TRACE_MSG_EVENT( PERUSE_COMM_MSG_INSERT_IN_UNEX_Q, comm_ptr,
-                                hdr->hdr_src, hdr->hdr_tag, PERUSE_RECV);
-    } 
-    if( OPAL_UNLIKELY(additional_match) ) {
-        opal_list_item_t* item;
-        while(NULL != (item = opal_list_remove_first(&additional_matches))) {
-            mca_pml_ob1_recv_frag_t* frag = (mca_pml_ob1_recv_frag_t*)item;
-            mca_pml_ob1_recv_request_progress( frag->request, frag->btl, frag->segments,
-                                               frag->num_segments );
+    if(OPAL_LIKELY(match)) {
+        mca_pml_ob1_recv_request_progress(match, btl, segments, num_segments);
+        if(OPAL_UNLIKELY(frag))
             MCA_PML_OB1_RECV_FRAG_RETURN(frag);
-        }
     }
-    return OMPI_SUCCESS;
-}
-

-/**
- * Scan the list of frags that came in ahead of time to see if any
- * can be processed at this time.  If they can, try and match the
- * frags.
- *
- * @param additional_matches List to hold new matches with fragments
- * from the c_frags_cant_match list. (IN/OUT)
- *
- * @param pml_comm Pointer to the communicator structure used for
- * matching purposes. (IN)
- *
- * This routine assumes that the appropriate matching locks are
- * set by the upper level routine.
- */
-
-static bool mca_pml_ob1_check_cantmatch_for_match( opal_list_t *additional_matches,
-                                                   mca_pml_ob1_comm_t* comm,
-                                                   mca_pml_ob1_comm_proc_t *proc )
-{
-    /* local parameters */
-    int match_found;
-    uint16_t next_msg_seq_expected, frag_seq;
-    mca_pml_ob1_recv_frag_t *frag;
-    bool match_made = false;
+    /* 
+     * Now that new message has arrived, check to see if
+     * any fragments on the c_c_frags_cant_match list
+     * may now be used to form new matchs
+     */
+    if(OPAL_UNLIKELY(opal_list_get_size(&proc->frags_cant_match) > 0)) {
+        OPAL_THREAD_LOCK(&comm->matching_lock);
+        if((frag = check_cantmatch_for_match(proc))) {
+            hdr = &frag->hdr.hdr_match;
+            segments = frag->segments;
+            num_segments = frag->num_segments;
+            btl = frag->btl;
+            goto out_of_order_match;
+        }
+    }

+    return OMPI_SUCCESS;
+wrong_seq:
     /*
-     * Loop over all the out of sequence messages.  No ordering is assumed
-     * in the c_frags_cant_match list.
+     * This message comes after the next expected, so it
+     * is ahead of sequence.  Save it for later.
      */
-
-    match_found = 1;
-    while ((0 < opal_list_get_size(&proc->frags_cant_match)) && match_found) {
-
-        /* initialize match flag for this search */
-        match_found = 0;
-
-        /* get sequence number of next message that can be processed */
-        next_msg_seq_expected = proc->expected_sequence;
-
-        /* search the list for a fragment from the send with sequence
-         * number next_msg_seq_expected
-         */
-        for(frag = (mca_pml_ob1_recv_frag_t *) 
-                opal_list_get_first(&proc->frags_cant_match);
-            frag != (mca_pml_ob1_recv_frag_t *)
-                opal_list_get_end(&proc->frags_cant_match);
-            frag = (mca_pml_ob1_recv_frag_t *) 
-                opal_list_get_next(frag))
-        {
-            /*
-             * If the message has the next expected seq from that proc...
-             */
-            frag_seq=frag->hdr.hdr_match.hdr_seq;
-            if (frag_seq == next_msg_seq_expected) {
-                mca_pml_ob1_match_hdr_t* hdr = &frag->hdr.hdr_match;
-                mca_pml_ob1_recv_request_t *match = NULL;
-
-                /* We're now expecting the next sequence number. */
-                (proc->expected_sequence)++;
-
-                /* signal that match was made */
-                match_found = 1;
-
-                /*
-                 * remove frag from list
-                 */
-                opal_list_remove_item(&proc->frags_cant_match,
-                        (opal_list_item_t *)frag);
-
-rematch:
-                /*
-                 * figure out what sort of matching logic to use, if need to
-                 *   look only at "specific" receives, or "wild" receives,
-                 *   or if we need to traverse both sets at the same time.
-                 */
-                proc = comm->procs + hdr->hdr_src;
-                if (opal_list_get_size(&proc->specific_receives) == 0 ) {
-                    /*
-                     * There are only wild irecvs, so specialize the algorithm.
-                     */
-                    MCA_PML_OB1_CHECK_WILD_RECEIVES_FOR_MATCH(hdr, comm, proc, match);
-                } else if (opal_list_get_size(&comm->wild_receives) == 0 ) {
-                    /*
-                     * There are only specific irecvs, so specialize the algorithm.
-                     */
-                    MCA_PML_OB1_CHECK_SPECIFIC_RECEIVES_FOR_MATCH(hdr, comm, proc, match);
-                } else {
-                    /*
-                     * There are some of each.
-                     */
-                    MCA_PML_OB1_CHECK_SPECIFIC_AND_WILD_RECEIVES_FOR_MATCH(hdr, comm, proc, match);
-
-                }
-
-                /* if match found, process data */
-                if( OPAL_LIKELY(match) ) {
-                    match->req_recv.req_base.req_proc = proc->ompi_proc;
-
-                    /*
-                     * If this was a probe need to queue fragment on unexpected list
-                     */
-                    if( (match->req_recv.req_base.req_type == MCA_PML_REQUEST_PROBE) ) {
-
-                        /* complete the probe */
-                        mca_pml_ob1_recv_request_matched_probe(match,frag->btl,frag->segments,frag->num_segments);
-
-                        /* retry the match */
-                        match = NULL;
-                        goto rematch;
-
-                    } else {
-
-                        /* associate the receive descriptor with the fragment
-                         * descriptor */
-                        frag->request=match;
-
-                        /* add this fragment descriptor to the list of
-                         * descriptors to be processed later
-                         */
-                        if(match_made == false) {
-                            match_made = true;
-                            OBJ_CONSTRUCT(additional_matches, opal_list_t);
-                        }
-                        opal_list_append(additional_matches, (opal_list_item_t *)frag);
-                    }
-
-                } else {
-    
-                    /* if no match found, place on unexpected queue */
-                    opal_list_append( &proc->unexpected_frags, (opal_list_item_t *)frag);
-                }
-
-                /* c_frags_cant_match is not an ordered list, so exit loop
-                 * and re-start search for next sequence number */
-                break;
-
-            } /* end if (frag_seq == next_msg_seq_expected) */
-            
-        } /* end for (frag) loop */
-        
-    } /* end while loop */
-
-    return match_made;
+    append_frag_to_list(&proc->frags_cant_match, btl, hdr, segments,
+            num_segments, NULL);
+    OPAL_THREAD_UNLOCK(&comm->matching_lock);
+    return OMPI_SUCCESS;
 }
-
diff --git a/ompi/mca/pml/ob1/pml_ob1_recvfrag.h b/ompi/mca/pml/ob1/pml_ob1_recvfrag.h
index 0bcab04..ed210e3 100644
--- a/ompi/mca/pml/ob1/pml_ob1_recvfrag.h
+++ b/ompi/mca/pml/ob1/pml_ob1_recvfrag.h
@@ -40,7 +40,6 @@ typedef struct mca_pml_ob1_buffer_t mca_pml_ob1_buffer_t;
 struct mca_pml_ob1_recv_frag_t {
     ompi_free_list_item_t super;
     mca_pml_ob1_hdr_t hdr;
-    struct mca_pml_ob1_recv_request_t* request;
     size_t num_segments;
     mca_btl_base_module_t* btl;
     mca_btl_base_segment_t segments[MCA_BTL_DES_MAX_SEGMENTS];
diff --git a/ompi/mca/pml/ob1/pml_ob1_recvreq.c b/ompi/mca/pml/ob1/pml_ob1_recvreq.c
index e881834..ba37033 100644
--- a/ompi/mca/pml/ob1/pml_ob1_recvreq.c
+++ b/ompi/mca/pml/ob1/pml_ob1_recvreq.c
@@ -31,9 +31,6 @@
 #include "orte/mca/errmgr/errmgr.h"
 #include "ompi/datatype/dt_arch.h"

-static mca_pml_ob1_recv_frag_t* mca_pml_ob1_recv_request_match_specific_proc(
-    mca_pml_ob1_recv_request_t* request, mca_pml_ob1_comm_proc_t* proc);
-
 void mca_pml_ob1_recv_request_process_pending(void)
 {
     mca_pml_ob1_recv_request_t* recvreq;
@@ -479,8 +476,6 @@ void mca_pml_ob1_recv_request_progress( mca_pml_ob1_recv_request_t* recvreq,
                                              data_offset,
                                              bytes_received,
                                              bytes_delivered);
-            recvreq->req_match_received = true;
-            opal_atomic_wmb();
             break;

         case MCA_PML_OB1_HDR_TYPE_RNDV:
@@ -505,8 +500,6 @@ void mca_pml_ob1_recv_request_progress( mca_pml_ob1_recv_request_t* recvreq,
                                                  bytes_received,
                                                  bytes_delivered );
             }
-            recvreq->req_match_received = true;
-            opal_atomic_wmb();
             break;

         case MCA_PML_OB1_HDR_TYPE_RGET:
@@ -514,7 +507,6 @@ void mca_pml_ob1_recv_request_progress( mca_pml_ob1_recv_request_t* recvreq,
             recvreq->req_recv.req_bytes_packed = hdr->hdr_rndv.hdr_msg_length;
             MCA_PML_OB1_RECV_REQUEST_MATCHED(recvreq,&hdr->hdr_match);
             mca_pml_ob1_recv_request_rget(recvreq, btl, &hdr->hdr_rget);
-            recvreq->req_match_received = true;
             return;

         case MCA_PML_OB1_HDR_TYPE_FRAG:
@@ -744,71 +736,72 @@ int mca_pml_ob1_recv_request_schedule_once(
     return OMPI_SUCCESS;
 }

-/*
- * This routine is used to match a posted receive when the source process 
- * is specified.
-*/
+#define IS_PROB_REQ(R) \
+    ((MCA_PML_REQUEST_IPROBE == (R)->req_recv.req_base.req_type) || \
+     (MCA_PML_REQUEST_PROBE == (R)->req_recv.req_base.req_type))

-void mca_pml_ob1_recv_request_match_specific(mca_pml_ob1_recv_request_t* request)
+inline void append_recv_req_to_queue(opal_list_t*, mca_pml_ob1_recv_request_t*);
+mca_pml_ob1_recv_frag_t *recv_req_match_specific_proc(
+        const mca_pml_ob1_recv_request_t*, mca_pml_ob1_comm_proc_t*);
+
+inline void append_recv_req_to_queue(opal_list_t *queue,
+        mca_pml_ob1_recv_request_t *req)
 {
-    mca_pml_ob1_comm_t* comm = request->req_recv.req_base.req_comm->c_pml_comm;
-    mca_pml_ob1_comm_proc_t* proc = comm->procs + request->req_recv.req_base.req_peer;
-    mca_pml_ob1_recv_frag_t* frag;
-   
-    /* check for a specific match */
-    OPAL_THREAD_LOCK(&comm->matching_lock);
+    if(OPAL_UNLIKELY(req->req_recv.req_base.req_type == MCA_PML_REQUEST_IPROBE))
+        return;
+
+    opal_list_append(queue, (opal_list_item_t*)req);
+
     /**
-     * The laps of time between the ACTIVATE event and the SEARCH_UNEX one include
-     * the cost of the request lock.
+     * We don't want to generate this kind of event for MPI_Probe. Hopefully,
+     * the compiler will optimize out the empty if loop in the case where PERUSE
+     * support is not required by the user.
      */
-    PERUSE_TRACE_COMM_EVENT( PERUSE_COMM_SEARCH_UNEX_Q_BEGIN,
-                             &(request->req_recv.req_base), PERUSE_RECV );
+    if(req->req_recv.req_base.req_type != MCA_PML_REQUEST_PROBE) {
+        PERUSE_TRACE_COMM_EVENT(PERUSE_COMM_REQ_INSERT_IN_POSTED_Q,
+                                 &(req->req_recv.req_base), PERUSE_RECV);
+    }
+}

-    /* assign sequence number */
-    request->req_recv.req_base.req_sequence = comm->recv_sequence++;
+/*
+ *  this routine tries to match a posted receive.  If a match is found,
+ *  it places the request in the appropriate matched receive list. This
+ *  function has to be called with the communicator matching lock held.
+*/
+mca_pml_ob1_recv_frag_t *recv_req_match_specific_proc(
+        const mca_pml_ob1_recv_request_t *req,
+        mca_pml_ob1_comm_proc_t *proc)
+{
+    opal_list_t* unexpected_frags = &proc->unexpected_frags;
+    opal_list_item_t *i;
+    mca_pml_ob1_recv_frag_t* frag;
+    int tag = req->req_recv.req_base.req_tag;

-    if (opal_list_get_size(&proc->unexpected_frags) > 0 &&
-        (frag = mca_pml_ob1_recv_request_match_specific_proc(request, proc)) != NULL) {
-        OPAL_THREAD_UNLOCK(&comm->matching_lock);
+    if(opal_list_get_size(unexpected_frags) == 0)
+        return NULL;

-        PERUSE_TRACE_COMM_EVENT( PERUSE_COMM_SEARCH_UNEX_Q_END,
-                                 &(request->req_recv.req_base), PERUSE_RECV );
+    for (i =  opal_list_get_first(unexpected_frags);
+         i != opal_list_get_end(unexpected_frags);
+         i =  opal_list_get_next(i)) {
+        frag = (mca_pml_ob1_recv_frag_t*)i;

-        if( !((MCA_PML_REQUEST_IPROBE == request->req_recv.req_base.req_type) ||
-              (MCA_PML_REQUEST_PROBE == request->req_recv.req_base.req_type)) ) {
-            mca_pml_ob1_recv_request_progress(request,frag->btl,frag->segments,frag->num_segments);
-            MCA_PML_OB1_RECV_FRAG_RETURN(frag);
-        } else {
-            mca_pml_ob1_recv_request_matched_probe(request,frag->btl,frag->segments,frag->num_segments);
-        }
-        return; /* match found */
+        if(frag->hdr.hdr_match.hdr_tag == tag ||
+                (OMPI_ANY_TAG == tag && frag->hdr.hdr_match.hdr_tag >= 0))
+            return frag;
     }

-    PERUSE_TRACE_COMM_EVENT( PERUSE_COMM_SEARCH_UNEX_Q_END,
-                             &(request->req_recv.req_base), PERUSE_RECV );
-
-    /* We didn't find any matches.  Record this irecv so we can match 
-     * it when the message comes in.
-     */
-    if(request->req_recv.req_base.req_type != MCA_PML_REQUEST_IPROBE) { 
-        opal_list_append(&proc->specific_receives, (opal_list_item_t*)request);
-        if(request->req_recv.req_base.req_type != MCA_PML_REQUEST_PROBE) {
-            PERUSE_TRACE_COMM_EVENT( PERUSE_COMM_REQ_INSERT_IN_POSTED_Q,
-                                     &(request->req_recv.req_base), PERUSE_RECV );
-        }
-    }
-    OPAL_THREAD_UNLOCK(&comm->matching_lock);
+    return NULL;
 }

-
 /*
  * this routine is used to try and match a wild posted receive - where
  * wild is determined by the value assigned to the source process
 */

-void mca_pml_ob1_recv_request_match_wild(mca_pml_ob1_recv_request_t* request)
+static mca_pml_ob1_recv_frag_t *recv_req_match_wild(
+        mca_pml_ob1_recv_request_t* req, mca_pml_ob1_comm_proc_t **p)
 {
-    mca_pml_ob1_comm_t* comm = request->req_recv.req_base.req_comm->c_pml_comm;
+    mca_pml_ob1_comm_t* comm = req->req_recv.req_base.req_comm->c_pml_comm;
     mca_pml_ob1_comm_proc_t* proc = comm->procs;
     size_t proc_count = comm->num_procs;
     size_t i;
@@ -819,123 +812,101 @@ void mca_pml_ob1_recv_request_match_wild(mca_pml_ob1_recv_request_t* request)
      * process, then an inner loop over the messages from the
      * process.
     */
-    OPAL_THREAD_LOCK(&comm->matching_lock);
-    /**
-     * The laps of time between the ACTIVATE event and the SEARCH_UNEX one include
-     * the cost of the request lock.
-     */
-    PERUSE_TRACE_COMM_EVENT( PERUSE_COMM_SEARCH_UNEX_Q_BEGIN,
-                             &(request->req_recv.req_base), PERUSE_RECV );
-
-    /* assign sequence number */
-    request->req_recv.req_base.req_sequence = comm->recv_sequence++;
-
     for (i = 0; i < proc_count; i++) {
         mca_pml_ob1_recv_frag_t* frag;

-        /* continue if no frags to match */
-        if (opal_list_get_size(&proc->unexpected_frags) == 0) {
-            proc++;
-            continue;
+        /* loop over messages from the current proc */
+        if((frag = recv_req_match_specific_proc(req, &proc[i]))) {
+            *p = &proc[i];
+            return frag; /* match found */
         }
+    }

-        /* loop over messages from the current proc */
-        if ((frag = mca_pml_ob1_recv_request_match_specific_proc(request, proc)) != NULL) {
-            OPAL_THREAD_UNLOCK(&comm->matching_lock);
+    *p = NULL;
+    return NULL;
+}

-            PERUSE_TRACE_COMM_EVENT( PERUSE_COMM_SEARCH_UNEX_Q_END,
-                                     &(request->req_recv.req_base), PERUSE_RECV );

-            if( !((MCA_PML_REQUEST_IPROBE == request->req_recv.req_base.req_type) ||
-                  (MCA_PML_REQUEST_PROBE == request->req_recv.req_base.req_type)) ) {
-                mca_pml_ob1_recv_request_progress(request,frag->btl,frag->segments,frag->num_segments);
-                MCA_PML_OB1_RECV_FRAG_RETURN(frag);
-            } else {
-                mca_pml_ob1_recv_request_matched_probe(request,frag->btl,frag->segments,frag->num_segments);
-            }
-            return; /* match found */
-        }
-        proc++;
-    } 
+void mca_pml_ob1_recv_req_start(mca_pml_ob1_recv_request_t *req)
+{
+    mca_pml_ob1_comm_t* comm = req->req_recv.req_base.req_comm->c_pml_comm;
+    mca_pml_ob1_comm_proc_t* proc;
+    mca_pml_ob1_recv_frag_t* frag;
+    opal_list_t *queue;

-    PERUSE_TRACE_COMM_EVENT( PERUSE_COMM_SEARCH_UNEX_Q_END,
-                             &(request->req_recv.req_base), PERUSE_RECV );
+    /* init/re-init the request */
+    req->req_lock = 0;
+    req->req_pipeline_depth  = 0;
+    req->req_bytes_received  = 0;
+    req->req_bytes_delivered = 0;
+    /* What about req_rdma_cnt ? */
+    req->req_rdma_idx = 0;
+    req->req_pending = false;
+    req->req_ack_sent = false;
+    req->req_match_received = false;

-    /* We didn't find any matches.  Record this irecv so we can match to
-     * it when the message comes in.
-    */
- 
-    if(request->req_recv.req_base.req_type != MCA_PML_REQUEST_IPROBE) {
-        opal_list_append(&comm->wild_receives, (opal_list_item_t*)request);
-        /**
-         * We don't want to generate this kind of event for MPI_Probe. Hopefully,
-         * the compiler will optimize out the empty if loop in the case where PERUSE
-         * support is not required by the user.
-         */
-        if(request->req_recv.req_base.req_type != MCA_PML_REQUEST_PROBE) {
-            PERUSE_TRACE_COMM_EVENT( PERUSE_COMM_REQ_INSERT_IN_POSTED_Q,
-                                     &(request->req_recv.req_base), PERUSE_RECV );
-        }
-    }
-    OPAL_THREAD_UNLOCK(&comm->matching_lock);
-}
+    MCA_PML_BASE_RECV_START(&req->req_recv.req_base);

+    OPAL_THREAD_LOCK(&comm->matching_lock);
+    /**
+     * The laps of time between the ACTIVATE event and the SEARCH_UNEX one include
+     * the cost of the request lock.
+     */
+    PERUSE_TRACE_COMM_EVENT(PERUSE_COMM_SEARCH_UNEX_Q_BEGIN,
+                             &(req->req_recv.req_base), PERUSE_RECV);

-/*
- *  this routine tries to match a posted receive.  If a match is found,
- *  it places the request in the appropriate matched receive list. This
- *  function has to be called with the communicator matching lock held.
-*/
+    /* assign sequence number */
+    req->req_recv.req_base.req_sequence = comm->recv_sequence++;

-static mca_pml_ob1_recv_frag_t* mca_pml_ob1_recv_request_match_specific_proc(
-    mca_pml_ob1_recv_request_t* request, 
-    mca_pml_ob1_comm_proc_t* proc)
-{
-    opal_list_t* unexpected_frags = &proc->unexpected_frags;
-    mca_pml_ob1_recv_frag_t* frag;
-    mca_pml_ob1_match_hdr_t* hdr;
-    int tag = request->req_recv.req_base.req_tag;
-
-    if( OMPI_ANY_TAG == tag ) {
-        for (frag =  (mca_pml_ob1_recv_frag_t*)opal_list_get_first(unexpected_frags);
-             frag != (mca_pml_ob1_recv_frag_t*)opal_list_get_end(unexpected_frags);
-             frag =  (mca_pml_ob1_recv_frag_t*)opal_list_get_next(frag)) {
-            hdr = &(frag->hdr.hdr_match);
-            
-            /* check first frag - we assume that process matching has been done already */
-            if( hdr->hdr_tag >= 0 ) {
-                goto find_fragment;
-            } 
-        }
+
+    /* attempt to match posted recv */
+    if(req->req_recv.req_base.req_peer == OMPI_ANY_SOURCE) {
+        frag = recv_req_match_wild(req, &proc);
+        queue = &comm->wild_receives;
+        if(proc)
+            req->req_recv.req_base.req_proc = proc->ompi_proc;
     } else {
-        for (frag =  (mca_pml_ob1_recv_frag_t*)opal_list_get_first(unexpected_frags);
-             frag != (mca_pml_ob1_recv_frag_t*)opal_list_get_end(unexpected_frags);
-             frag =  (mca_pml_ob1_recv_frag_t*)opal_list_get_next(frag)) {
-            hdr = &(frag->hdr.hdr_match);
-            
-            /* check first frag - we assume that process matching has been done already */
-            if ( tag == hdr->hdr_tag ) {
-                /* we assume that the tag is correct from MPI point of view (ie. >= 0 ) */
-                goto find_fragment;
-            } 
+        proc = &comm->procs[req->req_recv.req_base.req_peer];
+        req->req_recv.req_base.req_proc = proc->ompi_proc;
+        frag = recv_req_match_specific_proc(req, proc);
+        queue = &proc->specific_receives;
+        /* wild cardrecv will be prepared on match */ 
+        if((0 != req->req_recv.req_base.req_datatype->size) &&
+                (0 != req->req_recv.req_base.req_count)) {
+            prepare_recv_req_converter(req);
         }
     }
-    return NULL;
- find_fragment:
-    request->req_recv.req_base.req_proc = proc->ompi_proc;
-    if( !((MCA_PML_REQUEST_IPROBE == request->req_recv.req_base.req_type) ||
-          (MCA_PML_REQUEST_PROBE == request->req_recv.req_base.req_type)) ) {

-        PERUSE_TRACE_COMM_EVENT( PERUSE_COMM_REQ_MATCH_UNEX,
-                                &(request->req_recv.req_base), PERUSE_RECV );
+    if(OPAL_UNLIKELY(NULL == frag)) {
+        PERUSE_TRACE_COMM_EVENT(PERUSE_COMM_SEARCH_UNEX_Q_END,
+                &(req->req_recv.req_base), PERUSE_RECV);
+        /* We didn't find any matches.  Record this irecv so we can match
+           it when the message comes in. */
+        append_recv_req_to_queue(queue, req);
+        OPAL_THREAD_UNLOCK(&comm->matching_lock);
+    } else {
+        if(OPAL_LIKELY(!IS_PROB_REQ(req))) {
+            PERUSE_TRACE_COMM_EVENT(PERUSE_COMM_REQ_MATCH_UNEX,
+                    &(req->req_recv.req_base), PERUSE_RECV);

-        PERUSE_TRACE_MSG_EVENT( PERUSE_COMM_MSG_REMOVE_FROM_UNEX_Q,
-                                request->req_recv.req_base.req_comm,
-                                hdr->hdr_src, hdr->hdr_tag, PERUSE_RECV );
-        opal_list_remove_item(unexpected_frags, (opal_list_item_t*)frag);
-        frag->request = request;
-    }
+            PERUSE_TRACE_MSG_EVENT(PERUSE_COMM_MSG_REMOVE_FROM_UNEX_Q,
+                    req->req_recv.req_base.req_comm, hdr->hdr_src, hdr->hdr_tag,
+                    PERUSE_RECV);

-    return frag;
-}
+            PERUSE_TRACE_COMM_EVENT(PERUSE_COMM_SEARCH_UNEX_Q_END,
+                    &(req->req_recv.req_base), PERUSE_RECV);
+
+            opal_list_remove_item(&proc->unexpected_frags,
+                    (opal_list_item_t*)frag);
+            OPAL_THREAD_UNLOCK(&comm->matching_lock);

+            mca_pml_ob1_recv_request_progress(req, frag->btl, frag->segments,
+                    frag->num_segments);
+            MCA_PML_OB1_RECV_FRAG_RETURN(frag);
+        } else {
+            OPAL_THREAD_UNLOCK(&comm->matching_lock);
+            mca_pml_ob1_recv_request_matched_probe(req, frag->btl,
+                    frag->segments, frag->num_segments);
+        }
+    }
+}
diff --git a/ompi/mca/pml/ob1/pml_ob1_recvreq.h b/ompi/mca/pml/ob1/pml_ob1_recvreq.h
index 649b9c2..90647e5 100644
--- a/ompi/mca/pml/ob1/pml_ob1_recvreq.h
+++ b/ompi/mca/pml/ob1/pml_ob1_recvreq.h
@@ -194,96 +194,42 @@ recv_request_pml_complete_check(mca_pml_ob1_recv_request_t *recvreq)
     return false;
 }

-/**
- * Attempt to match the request against the unexpected fragment list
- * for all source ranks w/in the communicator.
- *
- * @param request (IN)   Request to match.
- */
-void mca_pml_ob1_recv_request_match_wild(mca_pml_ob1_recv_request_t* request);
-
-/**
- * Attempt to match the request against the unexpected fragment list
- * for a specific source rank.
- *
- * @param request (IN)   Request to match.
- */
-void mca_pml_ob1_recv_request_match_specific(mca_pml_ob1_recv_request_t* request);
-
-/**
- *  Initialize diagnostic code for tracing rdma protocol timing
- */
+extern void mca_pml_ob1_recv_req_start(mca_pml_ob1_recv_request_t *req);
+#define MCA_PML_OB1_RECV_REQUEST_START(r) mca_pml_ob1_recv_req_start(r)

-/**
- * Start an initialized request.
- *
- * @param request  Receive request.
- * @return         OMPI_SUCESS or error status on failure.
- */
-#define MCA_PML_OB1_RECV_REQUEST_START(request)                                   \
-do {                                                                              \
-    /* init/re-init the request */                                                \
-    (request)->req_lock = 0;                                                      \
-    (request)->req_pipeline_depth  = 0;                                           \
-    (request)->req_bytes_received  = 0;                                           \
-    (request)->req_bytes_delivered = 0;                                           \
-    /* What about req_rdma_cnt ? */                                               \
-    (request)->req_rdma_idx = 0;                                                  \
-    (request)->req_pending = false;                                               \
-    (request)->req_ack_sent = false;                                              \
-    (request)->req_match_received = false;                                         \
-                                                                                  \
-    MCA_PML_BASE_RECV_START( &(request)->req_recv.req_base );                     \
-                                                                                  \
-    /* attempt to match posted recv */                                            \
-    if((request)->req_recv.req_base.req_peer == OMPI_ANY_SOURCE) {                \
-        mca_pml_ob1_recv_request_match_wild(request);                             \
-    } else {                                                                      \
-        (request)->req_recv.req_base.req_proc =                                   \
-            (request)->req_recv.req_base.req_comm->c_pml_comm->procs              \
-                [(request)->req_recv.req_base.req_peer].ompi_proc;                \
-        if( (0 != (request)->req_recv.req_base.req_datatype->size) &&             \
-            (0 != (request)->req_recv.req_base.req_count) ) {                     \
-            ompi_convertor_copy_and_prepare_for_recv(                             \
-                (request)->req_recv.req_base.req_proc->proc_convertor,            \
-                (request)->req_recv.req_base.req_datatype,                        \
-                (request)->req_recv.req_base.req_count,                           \
-                (request)->req_recv.req_base.req_addr,                            \
-                0,                                                                \
-                &(request)->req_recv.req_base.req_convertor );                    \
-            ompi_convertor_get_unpacked_size( &(request)->req_recv.req_base.req_convertor, \
-                                              &(request)->req_bytes_delivered );  \
-        }                                                                         \
-        mca_pml_ob1_recv_request_match_specific(request);                         \
-    }                                                                             \
-} while (0)
-
-
-/**
- *
- */
-
-#define MCA_PML_OB1_RECV_REQUEST_MATCHED( request, hdr )                           \
-do {                                                                               \
-    (request)->req_recv.req_base.req_ompi.req_status.MPI_SOURCE = (hdr)->hdr_src;  \
-    (request)->req_recv.req_base.req_ompi.req_status.MPI_TAG = (hdr)->hdr_tag;     \
-                                                                                   \
-    if((request)->req_recv.req_bytes_packed > 0) {                                 \
-        if( MPI_ANY_SOURCE == (request)->req_recv.req_base.req_peer ) {            \
-            ompi_convertor_copy_and_prepare_for_recv(                              \
-                         (request)->req_recv.req_base.req_proc->proc_convertor,    \
-                         (request)->req_recv.req_base.req_datatype,                \
-                         (request)->req_recv.req_base.req_count,                   \
-                         (request)->req_recv.req_base.req_addr,                    \
-                         0,                                                        \
-                         &(request)->req_recv.req_base.req_convertor );            \
-            ompi_convertor_get_unpacked_size( &(request)->req_recv.req_base.req_convertor,  \
-                                              &(request)->req_bytes_delivered );   \
-        }                                                                          \
-        PERUSE_TRACE_COMM_EVENT (PERUSE_COMM_REQ_XFER_BEGIN,                       \
-                                 &((request)->req_recv.req_base), PERUSE_RECV);    \
-    }                                                                              \
-} while (0)
+static inline void prepare_recv_req_converter(mca_pml_ob1_recv_request_t *req)
+{
+    ompi_convertor_copy_and_prepare_for_recv(
+            req->req_recv.req_base.req_proc->proc_convertor,
+            req->req_recv.req_base.req_datatype,
+            req->req_recv.req_base.req_count,
+            req->req_recv.req_base.req_addr,
+            0,
+            &req->req_recv.req_base.req_convertor);
+    ompi_convertor_get_unpacked_size(&req->req_recv.req_base.req_convertor,
+            &req->req_bytes_delivered);
+ }
+
+#define MCA_PML_OB1_RECV_REQUEST_MATCHED(request, hdr) \
+    recv_req_matched(request, hdr)
+
+static inline void recv_req_matched(mca_pml_ob1_recv_request_t *req,
+        mca_pml_ob1_match_hdr_t *hdr)
+{
+    req->req_recv.req_base.req_ompi.req_status.MPI_SOURCE = hdr->hdr_src;
+    req->req_recv.req_base.req_ompi.req_status.MPI_TAG = hdr->hdr_tag;
+    req->req_match_received = true;
+    opal_atomic_wmb();
+
+    if(req->req_recv.req_bytes_packed > 0) {
+        if(MPI_ANY_SOURCE == req->req_recv.req_base.req_peer) {
+            /* non wildcard prepared during post recv */
+            prepare_recv_req_converter(req);
+        }
+        PERUSE_TRACE_COMM_EVENT(PERUSE_COMM_REQ_XFER_BEGIN,
+                &req->req_recv.req_base, PERUSE_RECV);
+    }
+}


 /**

Reply via email to