pml_ob1_recvfrag.c

来自「MPI stands for the Message Passing Inter」· C语言 代码 · 共 772 行 · 第 1/3 页

C
772
字号
#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)/** * 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)/** * 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. */#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)/* * Specialized matching routines for internal use only. */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 );/** * RCS/CTS receive side matching * * @param hdr list of parameters needed for matching *                    This list is also embeded in frag, *                    but this allows to save a memory copy when *                    a match is made in this routine. (IN) * @param frag   pointer to receive fragment which we want *                    to match (IN/OUT).  If a match is not made, *                    hdr is copied to frag. * @param match_made  parameter indicating if we matched frag/ *                    hdr (OUT) * @param additional_matches  if a match is made with frag, we *                    may be able to match fragments that previously *                    have arrived out-of-order.  If this is the *                    case, the associated fragment descriptors are *                    put on this list for further processing. (OUT) * * @return OMPI error code * * This routine is used to try and match a newly arrived message fragment *   to pre-posted receives.  The following assumptions are made *   - fragments are received out of order *   - for long messages, e.g. more than one fragment, a RTS/CTS algorithm *       is used. *   - 2nd and greater fragments include a receive descriptor pointer *   - fragments may be dropped *   - fragments may be corrupt *   - this routine may be called simultaneously by more than one thread */static int mca_pml_ob1_recv_frag_match( mca_btl_base_module_t *btl,                                         mca_pml_ob1_match_hdr_t *hdr,                                        mca_btl_base_segment_t* segments,                                        size_t num_segments ){    /* local variables */    uint16_t next_msg_seq_expected, frag_msg_seq;    ompi_communicator_t *comm_ptr;    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;    /* communicator pointer */    comm_ptr=ompi_comm_lookup(hdr->hdr_ctx);    comm=(mca_pml_ob1_comm_t *)comm_ptr->c_pml_comm;    /* source sequence number */    frag_msg_seq = hdr->hdr_seq;    proc = comm->procs + hdr->hdr_src;    /**     * We generate the MSG_ARRIVED event as soon as the PML is aware of a matching     * fragment arrival. Independing if it is received on the correct order or not.     * 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,                            hdr->hdr_src, hdr->hdr_tag, PERUSE_RECV);    /* get next expected message sequence number - if threaded     * run, lock to make sure that if another thread is processing      * a frag from the same message a match is made only once.     * Also, this prevents other posted receives (for a pair of     * end points) from being processed, and potentially "loosing"     * the fragment.     */    OPAL_THREAD_LOCK(&comm->matching_lock);    /* get sequence number of next message that can be processed */    next_msg_seq_expected = (uint16_t)proc->expected_sequence;    if(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:        /*         * figure out what sort of matching logic to use, if need to         *   look only at "specific" receives, or "wild" receives,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?