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 + -
显示快捷键?