int MPIDI_CH3_EagerContigSend( MPID_Request **sreq_p, MPIDI_CH3_Pkt_type_t reqtype, const void * buf, MPIDI_msg_sz_t data_sz, int rank, int tag, MPID_Comm * comm, int context_offset ) { int mpi_errno = MPI_SUCCESS; MPIDI_VC_t * vc; MPIDI_CH3_Pkt_t upkt; MPIDI_CH3_Pkt_eager_send_t * const eager_pkt = &upkt.eager_send; MPID_Request *sreq = *sreq_p; MPL_IOV iov[2]; MPIDI_Pkt_init(eager_pkt, reqtype); eager_pkt->match.parts.rank = comm->rank; eager_pkt->match.parts.tag = tag; eager_pkt->match.parts.context_id = comm->context_id + context_offset; eager_pkt->sender_req_id = MPI_REQUEST_NULL; eager_pkt->data_sz = data_sz; iov[0].MPL_IOV_BUF = (MPL_IOV_BUF_CAST)eager_pkt; iov[0].MPL_IOV_LEN = sizeof(*eager_pkt); MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST, "sending contiguous eager message, data_sz=" MPIDI_MSG_SZ_FMT, data_sz)); iov[1].MPL_IOV_BUF = (MPL_IOV_BUF_CAST) buf; iov[1].MPL_IOV_LEN = data_sz; MPIDI_Comm_get_vc_set_active(comm, rank, &vc); MPIDI_VC_FAI_send_seqnum(vc, seqnum); MPIDI_Pkt_set_seqnum(eager_pkt, seqnum); MPIU_DBG_MSGPKT(vc,tag,eager_pkt->match.parts.context_id,rank,data_sz,"EagerContig"); MPID_THREAD_CS_ENTER(POBJ, vc->pobj_mutex); mpi_errno = MPIDI_CH3_iStartMsgv(vc, iov, 2, sreq_p); MPID_THREAD_CS_EXIT(POBJ, vc->pobj_mutex); if (mpi_errno != MPI_SUCCESS) { MPIR_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**ch3|eagermsg"); } sreq = *sreq_p; if (sreq != NULL) { MPIDI_Request_set_seqnum(sreq, seqnum); MPIDI_Request_set_type(sreq, MPIDI_REQUEST_TYPE_SEND); } fn_fail: return mpi_errno; }
/* * This function does all of the work or either revoking the communciator for * the first time or keeping track of an ongoing revocation. * * comm_ptr - The communicator being revoked * is_remote - If we received the revocation from a remote process, this should * be set to true. This way we'll know to decrement the counter twice * (once for our local revocation and once for the remote). */ int MPID_Comm_revoke(MPIR_Comm *comm_ptr, int is_remote) { MPIDI_VC_t *vc; MPL_IOV iov[MPL_IOV_LIMIT]; int mpi_errno = MPI_SUCCESS; int i, size, my_rank; MPIR_Request *request; MPIDI_CH3_Pkt_t upkt; MPIDI_CH3_Pkt_revoke_t *revoke_pkt = &upkt.revoke; MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_COMM_REVOKE); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_COMM_REVOKE); if (0 == comm_ptr->revoked) { /* Mark the communicator as revoked locally */ comm_ptr->revoked = 1; if (comm_ptr->node_comm) comm_ptr->node_comm->revoked = 1; if (comm_ptr->node_roots_comm) comm_ptr->node_roots_comm->revoked = 1; /* Start a counter to track how many revoke messages we've received from * other ranks */ comm_ptr->dev.waiting_for_revoke = comm_ptr->local_size - 1 - is_remote; /* Subtract the processes who already know about the revoke */ MPL_DBG_MSG_FMT(MPIDI_CH3_DBG_OTHER, VERBOSE, (MPL_DBG_FDEST, "Comm %08x waiting_for_revoke: %d", comm_ptr->handle, comm_ptr->dev.waiting_for_revoke)); /* Keep a reference to this comm so it doesn't get destroyed while * it's being revoked */ MPIR_Comm_add_ref(comm_ptr); /* Send out the revoke message */ MPIDI_Pkt_init(revoke_pkt, MPIDI_CH3_PKT_REVOKE); revoke_pkt->revoked_comm = comm_ptr->context_id; size = comm_ptr->remote_size; my_rank = comm_ptr->rank; for (i = 0; i < size; i++) { if (i == my_rank) continue; request = NULL; MPIDI_Comm_get_vc_set_active(comm_ptr, i, &vc); iov[0].MPL_IOV_BUF = (MPL_IOV_BUF_CAST) revoke_pkt; iov[0].MPL_IOV_LEN = sizeof(*revoke_pkt); MPID_THREAD_CS_ENTER(POBJ, vc->pobj_mutex); mpi_errno = MPIDI_CH3_iStartMsgv(vc, iov, 1, &request); MPID_THREAD_CS_EXIT(POBJ, vc->pobj_mutex); if (mpi_errno) comm_ptr->dev.waiting_for_revoke--; if (NULL != request) /* We don't need to keep a reference to this request. The * progress engine will keep a reference until it completes * later */ MPIR_Request_free(request); } /* Check to see if we are done revoking */ if (comm_ptr->dev.waiting_for_revoke == 0) { MPIR_Comm_release(comm_ptr); } /* Go clean up all of the existing operations involving this * communicator. This includes completing existing MPI requests, MPID * requests, and cleaning up the unexpected queue to make sure there * aren't any unexpected messages hanging around. */ /* Clean up the receive and unexpected queues */ MPID_THREAD_CS_ENTER(POBJ, MPIR_THREAD_POBJ_MSGQ_MUTEX); MPIDI_CH3U_Clean_recvq(comm_ptr); MPID_THREAD_CS_EXIT(POBJ, MPIR_THREAD_POBJ_MSGQ_MUTEX); } else if (is_remote) { /* If this is local, we've already revoked and don't need to do it again. */ /* Decrement the revoke counter */ comm_ptr->dev.waiting_for_revoke--; MPL_DBG_MSG_FMT(MPIDI_CH3_DBG_OTHER, VERBOSE, (MPL_DBG_FDEST, "Comm %08x waiting_for_revoke: %d", comm_ptr->handle, comm_ptr->dev.waiting_for_revoke)); /* Check to see if we are done revoking */ if (comm_ptr->dev.waiting_for_revoke == 0) { MPIR_Comm_release(comm_ptr); } } MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_COMM_REVOKE); return MPI_SUCCESS; }