static int ckpt_cb(void *arg) { int rc, ret; const struct cr_restart_info* ri; if (MPIDI_Process.my_pg_rank == 0) { MPIDI_nem_ckpt_start_checkpoint = TRUE; /* poke the progress engine in case we're waiting in a blocking recv */ MPIDI_CH3_Progress_signal_completion(); } do { ret = sem_wait(&ckpt_sem); } while (ret == -1 && errno == EINTR); CHECK_ERR(ret, "sem_wait"); if (MPID_nem_netmod_func->ckpt_precheck) { int mpi_errno; mpi_errno = MPID_nem_netmod_func->ckpt_precheck(); CHECK_ERR_MPI(mpi_errno, mpi_errno, "ckpt_precheck failed"); } rc = cr_checkpoint(0); if (rc < 0) { ckpt_result = CKPT_ERROR; } else if (rc) { ckpt_result = CKPT_RESTART; ri = cr_get_restart_info(); CHECK_ERR(!ri, "cr_get_restart_info"); ret = restore_env(ri->requester, MPIDI_Process.my_pg_rank); CHECK_ERR(ret, "restore_env"); ret = restore_stdinouterr(MPIDI_Process.my_pg_rank); CHECK_ERR(ret, "restore_stdinouterr"); ret = reinit_pmi(); CHECK_ERR(ret, "reinit_pmi"); if (MPID_nem_netmod_func->ckpt_restart) { int mpi_errno; mpi_errno = MPID_nem_netmod_func->ckpt_restart(); CHECK_ERR_MPI(mpi_errno, mpi_errno, "ckpt_restart failed"); } } else { ckpt_result = CKPT_CONTINUE; if (MPID_nem_netmod_func->ckpt_continue) { int mpi_errno; mpi_errno = MPID_nem_netmod_func->ckpt_continue(); CHECK_ERR_MPI(mpi_errno, mpi_errno, "ckpt_continue failed"); } } do { ret = sem_post(&cont_sem); } while (ret == -1 && errno == EINTR); CHECK_ERR(ret, "sem_post"); return 0; }
static void sigusr1_handler(int sig) { ++sigusr1_count; /* poke the progress engine in case we're waiting in a blocking recv */ MPIDI_CH3_Progress_signal_completion(); if (prev_sighandler) prev_sighandler(sig); }
static int pkt_ckpt_marker_handler(MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt, MPIDI_msg_sz_t *buflen, MPID_Request **req) { int mpi_errno = MPI_SUCCESS; MPID_nem_pkt_ckpt_marker_t * const ckpt_pkt = (MPID_nem_pkt_ckpt_marker_t *)pkt; MPIDI_STATE_DECL(MPID_STATE_PKT_CKPT_MARKER_HANDLER); MPIDI_FUNC_ENTER(MPID_STATE_PKT_CKPT_MARKER_HANDLER); if (!checkpointing) { mpi_errno = MPIDI_nem_ckpt_start(); if (mpi_errno) MPIU_ERR_POP(mpi_errno); } MPIU_Assert(current_wave == ckpt_pkt->wave); --marker_count; /* We're checkpointing the shared memory region, so we don't need to flush the channels between local processes, only remote processes */ if (marker_count == 0) { MPIDI_nem_ckpt_finish_checkpoint = TRUE; /* make sure we break out of receive loop into progress loop */ MPIDI_CH3_Progress_signal_completion(); } *buflen = sizeof(MPIDI_CH3_Pkt_t); *req = NULL; fn_exit: MPIDI_FUNC_EXIT(MPID_STATE_PKT_CKPT_MARKER_HANDLER); return mpi_errno; fn_fail: goto fn_exit; }
static int MPIDI_CH3I_Progress_handle_sock_event(MPIDU_Sock_event_t * event) { int mpi_errno = MPI_SUCCESS; MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3I_PROGRESS_HANDLE_SOCK_EVENT); MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3I_PROGRESS_HANDLE_SOCK_EVENT); MPIU_DBG_MSG_D(CH3_OTHER,VERBOSE,"Socket event of type %d", event->op_type ); switch (event->op_type) { case MPIDU_SOCK_OP_READ: { MPIDI_CH3I_Connection_t * conn = (MPIDI_CH3I_Connection_t *) event->user_ptr; MPID_Request * rreq = conn->recv_active; /* --BEGIN ERROR HANDLING-- */ if (event->error != MPI_SUCCESS) { /* FIXME: the following should be handled by the close protocol */ if (MPIR_ERR_GET_CLASS(event->error) != MPIDU_SOCK_ERR_CONN_CLOSED) { mpi_errno = event->error; MPIU_ERR_POP(mpi_errno); } break; } /* --END ERROR HANDLING-- */ if (conn->state == CONN_STATE_CONNECTED) { if (conn->recv_active == NULL) { MPIDI_msg_sz_t buflen = sizeof (MPIDI_CH3_Pkt_t); MPIU_Assert(conn->pkt.type < MPIDI_CH3_PKT_END_CH3); mpi_errno = pktArray[conn->pkt.type]( conn->vc, &conn->pkt, &buflen, &rreq ); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_POP(mpi_errno); } MPIU_Assert(buflen == sizeof (MPIDI_CH3_Pkt_t)); if (rreq == NULL) { if (conn->state != CONN_STATE_CLOSING) { /* conn->recv_active = NULL; -- already set to NULL */ mpi_errno = connection_post_recv_pkt(conn); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_POP(mpi_errno); } } } else { mpi_errno = ReadMoreData( conn, rreq ); if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } } } else /* incoming data */ { int (*reqFn)(MPIDI_VC_t *, MPID_Request *, int *); int complete; reqFn = rreq->dev.OnDataAvail; if (!reqFn) { MPIU_Assert(MPIDI_Request_get_type(rreq)!=MPIDI_REQUEST_TYPE_GET_RESP); MPIDI_CH3U_Request_complete(rreq); complete = TRUE; } else { mpi_errno = reqFn( conn->vc, rreq, &complete ); if (mpi_errno) MPIU_ERR_POP(mpi_errno); } if (complete) { conn->recv_active = NULL; mpi_errno = connection_post_recv_pkt(conn); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_POP(mpi_errno); } } else /* more data to be read */ { mpi_errno = ReadMoreData( conn, rreq ); if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } } } } else if (conn->state == CONN_STATE_OPEN_LRECV_DATA) { mpi_errno = MPIDI_CH3_Sockconn_handle_connopen_event( conn ); if (mpi_errno) { MPIU_ERR_POP( mpi_errno ); } } else /* Handling some internal connection establishment or tear down packet */ { mpi_errno = MPIDI_CH3_Sockconn_handle_conn_event( conn ); if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } } break; } /* END OF SOCK_OP_READ */ case MPIDU_SOCK_OP_WRITE: { MPIDI_CH3I_Connection_t * conn = (MPIDI_CH3I_Connection_t *) event->user_ptr; /* --BEGIN ERROR HANDLING-- */ if (event->error != MPI_SUCCESS) { mpi_errno = event->error; MPIU_ERR_POP(mpi_errno); } /* --END ERROR HANDLING-- */ if (conn->send_active) { MPID_Request * sreq = conn->send_active; int (*reqFn)(MPIDI_VC_t *, MPID_Request *, int *); int complete; reqFn = sreq->dev.OnDataAvail; if (!reqFn) { MPIU_Assert(MPIDI_Request_get_type(sreq)!=MPIDI_REQUEST_TYPE_GET_RESP); MPIDI_CH3U_Request_complete(sreq); complete = TRUE; } else { mpi_errno = reqFn( conn->vc, sreq, &complete ); if (mpi_errno) MPIU_ERR_POP(mpi_errno); } if (complete) { mpi_errno = connection_pop_sendq_req(conn); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_POP(mpi_errno); } } else /* more data to send */ { for(;;) { MPID_IOV * iovp; MPIU_Size_t nb; iovp = sreq->dev.iov; mpi_errno = MPIDU_Sock_writev(conn->sock, iovp, sreq->dev.iov_count, &nb); /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) { mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER, "**ch3|sock|immedwrite", "ch3|sock|immedwrite %p %p %p", sreq, conn, conn->vc); goto fn_fail; } /* --END ERROR HANDLING-- */ MPIU_DBG_MSG_FMT(CH3_CHANNEL,VERBOSE, (MPIU_DBG_FDEST,"immediate writev, vc=%p, sreq=0x%08x, nb=" MPIDI_MSG_SZ_FMT, conn->vc, sreq->handle, nb)); if (nb > 0 && adjust_iov(&iovp, &sreq->dev.iov_count, nb)) { reqFn = sreq->dev.OnDataAvail; if (!reqFn) { MPIU_Assert(MPIDI_Request_get_type(sreq)!=MPIDI_REQUEST_TYPE_GET_RESP); MPIDI_CH3U_Request_complete(sreq); complete = TRUE; } else { mpi_errno = reqFn( conn->vc, sreq, &complete ); if (mpi_errno) MPIU_ERR_POP(mpi_errno); } if (complete) { mpi_errno = connection_pop_sendq_req(conn); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_POP(mpi_errno); } break; } } else { MPIU_DBG_MSG_FMT(CH3_CHANNEL,VERBOSE, (MPIU_DBG_FDEST,"posting writev, vc=%p, conn=%p, sreq=0x%08x", conn->vc, conn, sreq->handle)); mpi_errno = MPIDU_Sock_post_writev(conn->sock, iovp, sreq->dev.iov_count, NULL); /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) { mpi_errno = MPIR_Err_create_code( mpi_errno, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER, "**ch3|sock|postwrite", "ch3|sock|postwrite %p %p %p", sreq, conn, conn->vc); goto fn_fail; } /* --END ERROR HANDLING-- */ break; } } } } else /* finished writing internal packet header */ { /* the connection is not active yet */ mpi_errno = MPIDI_CH3_Sockconn_handle_connwrite( conn ); if (mpi_errno) { MPIU_ERR_POP( mpi_errno ); } } break; } /* END OF SOCK_OP_WRITE */ case MPIDU_SOCK_OP_ACCEPT: { mpi_errno = MPIDI_CH3_Sockconn_handle_accept_event(); if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } break; } case MPIDU_SOCK_OP_CONNECT: { mpi_errno = MPIDI_CH3_Sockconn_handle_connect_event( (MPIDI_CH3I_Connection_t *) event->user_ptr, event->error ); if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } break; } case MPIDU_SOCK_OP_CLOSE: { mpi_errno = MPIDI_CH3_Sockconn_handle_close_event( (MPIDI_CH3I_Connection_t *) event->user_ptr ); if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } break; } case MPIDU_SOCK_OP_WAKEUP: { MPIDI_CH3_Progress_signal_completion(); /* MPIDI_CH3I_progress_completion_count++; */ break; } } fn_exit: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_PROGRESS_HANDLE_SOCK_EVENT); return mpi_errno; fn_fail: goto fn_exit; }
static int MPIDI_CH3i_Progress_wait(MPID_Progress_state * progress_state) { MPIDU_Sock_event_t event; int mpi_errno = MPI_SUCCESS; MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3I_PROGRESS_WAIT); MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3I_PROGRESS_WAIT); /* * MT: the following code will be needed if progress can occur between * MPIDI_CH3_Progress_start() and * MPIDI_CH3_Progress_wait(), or iterations of MPIDI_CH3_Progress_wait(). * * This is presently not possible, and thus the code is commented out. */ # if 0 /* FIXME: Was (USE_THREAD_IMPL == MPICH_THREAD_IMPL_NOT_IMPLEMENTED), which really meant not-using-global-mutex-thread model . This was true for the single threaded case, but was probably not intended for that case*/ { if (progress_state->ch.completion_count != MPIDI_CH3I_progress_completion_count) { goto fn_exit; } } # endif # ifdef MPICH_IS_THREADED MPIU_THREAD_CHECK_BEGIN { if (MPIDI_CH3I_progress_blocked == TRUE) { /* * Another thread is already blocking in the progress engine. * * MT: Another thread is already blocking in poll. Right now, * calls to MPIDI_CH3_Progress_wait() are effectively * serialized by the device. The only way another thread may * enter this function is if MPIDU_Sock_wait() blocks. If * this changes, a flag other than MPIDI_CH3I_Progress_blocked * may be required to determine if another thread is in * the progress engine. */ MPIDI_CH3I_Progress_delay(MPIDI_CH3I_progress_completion_count); goto fn_exit; } } MPIU_THREAD_CHECK_END # endif do { int made_progress = FALSE; /* make progress on NBC schedules, must come before we block on sock_wait */ mpi_errno = MPIDU_Sched_progress(&made_progress); if (mpi_errno) MPIU_ERR_POP(mpi_errno); if (made_progress) { MPIDI_CH3_Progress_signal_completion(); break; } # ifdef MPICH_IS_THREADED /* The logic for this case is just complicated enough that we write separate code for each possibility */ # ifdef HAVE_RUNTIME_THREADCHECK if (MPIR_ThreadInfo.isThreaded) { MPIDI_CH3I_progress_blocked = TRUE; mpi_errno = MPIDU_Sock_wait(MPIDI_CH3I_sock_set, MPIDU_SOCK_INFINITE_TIME, &event); MPIDI_CH3I_progress_blocked = FALSE; MPIDI_CH3I_progress_wakeup_signalled = FALSE; } else { mpi_errno = MPIDU_Sock_wait(MPIDI_CH3I_sock_set, MPIDU_SOCK_INFINITE_TIME, &event); } # else MPIDI_CH3I_progress_blocked = TRUE; mpi_errno = MPIDU_Sock_wait(MPIDI_CH3I_sock_set, MPIDU_SOCK_INFINITE_TIME, &event); MPIDI_CH3I_progress_blocked = FALSE; MPIDI_CH3I_progress_wakeup_signalled = FALSE; # endif /* HAVE_RUNTIME_THREADCHECK */ # else mpi_errno = MPIDU_Sock_wait(MPIDI_CH3I_sock_set, MPIDU_SOCK_INFINITE_TIME, &event); # endif /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) { MPIU_Assert(MPIR_ERR_GET_CLASS(mpi_errno) != MPIDU_SOCK_ERR_TIMEOUT); MPIU_ERR_SET(mpi_errno,MPI_ERR_OTHER,"**progress_sock_wait"); goto fn_fail; } /* --END ERROR HANDLING-- */ mpi_errno = MPIDI_CH3I_Progress_handle_sock_event(&event); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**ch3|sock|handle_sock_event"); } } while (progress_state->ch.completion_count == MPIDI_CH3I_progress_completion_count); /* * We could continue to call MPIU_Sock_wait in a non-blocking fashion * and process any other events; however, this would not * give the application a chance to post new receives, and thus could * result in an increased number of unexpected messages * that would need to be buffered. */ # if MPICH_IS_THREADED { /* * Awaken any threads which are waiting for the progress that just * occurred */ MPIDI_CH3I_Progress_continue(MPIDI_CH3I_progress_completion_count); } # endif fn_exit: /* * Reset the progress state so it is fresh for the next iteration */ progress_state->ch.completion_count = MPIDI_CH3I_progress_completion_count; MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_PROGRESS_WAIT); return mpi_errno; fn_fail: goto fn_exit; }
int MPIDI_CH3_PktHandler_RndvReqToSend( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt, MPIDI_msg_sz_t *buflen, MPID_Request **rreqp ) { MPID_Request * rreq; int found; MPIDI_CH3_Pkt_rndv_req_to_send_t * rts_pkt = &pkt->rndv_req_to_send; int mpi_errno = MPI_SUCCESS; MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST, "received rndv RTS pkt, sreq=0x%08x, rank=%d, tag=%d, context=%d, data_sz=" MPIDI_MSG_SZ_FMT, rts_pkt->sender_req_id, rts_pkt->match.parts.rank, rts_pkt->match.parts.tag, rts_pkt->match.parts.context_id, rts_pkt->data_sz)); MPIU_DBG_MSGPKT(vc,rts_pkt->match.parts.tag,rts_pkt->match.parts.context_id, rts_pkt->match.parts.rank,rts_pkt->data_sz, "ReceivedRndv"); MPIU_THREAD_CS_ENTER(MSGQUEUE,); rreq = MPIDI_CH3U_Recvq_FDP_or_AEU(&rts_pkt->match, &found); MPIU_ERR_CHKANDJUMP1(!rreq, mpi_errno,MPI_ERR_OTHER, "**nomemreq", "**nomemuereq %d", MPIDI_CH3U_Recvq_count_unexp()); set_request_info(rreq, rts_pkt, MPIDI_REQUEST_RNDV_MSG); MPIU_THREAD_CS_EXIT(MSGQUEUE,); *buflen = sizeof(MPIDI_CH3_Pkt_t); if (found) { MPID_Request * cts_req; MPIDI_CH3_Pkt_t upkt; MPIDI_CH3_Pkt_rndv_clr_to_send_t * cts_pkt = &upkt.rndv_clr_to_send; MPIU_DBG_MSG(CH3_OTHER,VERBOSE,"posted request found"); /* FIXME: What if the receive user buffer is not big enough to hold the data about to be cleared for sending? */ MPIU_DBG_MSG(CH3_OTHER,VERBOSE,"sending rndv CTS packet"); MPIDI_Pkt_init(cts_pkt, MPIDI_CH3_PKT_RNDV_CLR_TO_SEND); cts_pkt->sender_req_id = rts_pkt->sender_req_id; cts_pkt->receiver_req_id = rreq->handle; MPIU_THREAD_CS_ENTER(CH3COMM,vc); mpi_errno = MPIU_CALL(MPIDI_CH3,iStartMsg(vc, cts_pkt, sizeof(*cts_pkt), &cts_req)); MPIU_THREAD_CS_EXIT(CH3COMM,vc); if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**ch3|ctspkt"); } if (cts_req != NULL) { MPID_Request_release(cts_req); } } else { MPIU_DBG_MSG(CH3_OTHER,VERBOSE,"unexpected request allocated"); /* * A MPID_Probe() may be waiting for the request we just * inserted, so we need to tell the progress engine to exit. * * FIXME: This will cause MPID_Progress_wait() to return to the * MPI layer each time an unexpected RTS packet is * received. MPID_Probe() should atomically increment a * counter and MPIDI_CH3_Progress_signal_completion() * should only be called if that counter is greater than zero. */ MPIDI_CH3_Progress_signal_completion(); } *rreqp = NULL; fn_fail: return mpi_errno; }
/*@ MPIDI_CH3U_Handle_connection - handle connection event Input Parameters: + vc - virtual connection . event - connection event NOTE: This routine is used to transition the VC state. The only events currently handled are TERMINATED events. This routine should be called (with TERMINATED) whenever a connection is terminated whether normally (in MPIDI_CH3_Connection_terminate() ), or abnormally. FIXME: Currently state transitions resulting from receiving CLOSE packets are performed in MPIDI_CH3_PktHandler_Close(). Perhaps that should move here. @*/ int MPIDI_CH3U_Handle_connection(MPIDI_VC_t * vc, MPIDI_VC_Event_t event) { int inuse; int mpi_errno = MPI_SUCCESS; MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPIDI_CH3U_HANDLE_CONNECTION); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPIDI_CH3U_HANDLE_CONNECTION); switch (event) { case MPIDI_VC_EVENT_TERMINATED: { switch (vc->state) { case MPIDI_VC_STATE_CLOSED: /* Normal termination. */ MPIDI_CHANGE_VC_STATE(vc, INACTIVE); /* MT: this is not thread safe */ MPIDI_Outstanding_close_ops -= 1; MPL_DBG_MSG_D(MPIDI_CH3_DBG_DISCONNECT,TYPICAL, "outstanding close operations = %d", MPIDI_Outstanding_close_ops); if (MPIDI_Outstanding_close_ops == 0) { MPIDI_CH3_Progress_signal_completion(); mpi_errno = MPIDI_CH3_Channel_close(); if (mpi_errno) MPIR_ERR_POP(mpi_errno); } break; case MPIDI_VC_STATE_INACTIVE: /* VC was terminated before it was activated. This can happen if a failed process was detected before the process used the VC. */ MPL_DBG_MSG(MPIDI_CH3_DBG_DISCONNECT,TYPICAL, "VC terminated before it was activated. We probably got a failed" " process notification."); MPIDI_CH3U_Complete_posted_with_error(vc); ++MPIDI_Failed_vc_count; MPIDI_CHANGE_VC_STATE(vc, MORIBUND); break; case MPIDI_VC_STATE_ACTIVE: case MPIDI_VC_STATE_REMOTE_CLOSE: /* This is a premature termination. This process has not started the close protocol. There may be outstanding sends or receives on the local side, remote side or both. */ MPL_DBG_MSG(MPIDI_CH3_DBG_DISCONNECT,TYPICAL, "Connection closed prematurely."); MPIDI_CH3U_Complete_posted_with_error(vc); ++MPIDI_Failed_vc_count; MPIDU_Ftb_publish_vc(MPIDU_FTB_EV_UNREACHABLE, vc); MPIDI_CHANGE_VC_STATE(vc, MORIBUND); break; case MPIDI_VC_STATE_LOCAL_CLOSE: /* This is a premature termination. This process has started the close protocol, but hasn't received a CLOSE packet from the remote side. This process may not have been able to send the CLOSE ack=F packet to the remote side. There may be outstanding sends or receives on the local or remote sides. */ case MPIDI_VC_STATE_CLOSE_ACKED: /* This is a premature termination. Both sides have started the close protocol. This process has received CLOSE ack=F, but not CLOSE ack=t. This process may not have been able to send CLOSE ack=T. There should not be any outstanding sends or receives on either side. */ MPL_DBG_MSG_D(MPIDI_CH3_DBG_DISCONNECT,TYPICAL, "Connection closed prematurely during close protocol. " "Outstanding close operations = %d", MPIDI_Outstanding_close_ops); MPIDI_CH3U_Complete_posted_with_error(vc); ++MPIDI_Failed_vc_count; MPIDU_Ftb_publish_vc(MPIDU_FTB_EV_UNREACHABLE, vc); MPIDI_CHANGE_VC_STATE(vc, MORIBUND); /* MT: this is not thread safe */ MPIDI_Outstanding_close_ops -= 1; if (MPIDI_Outstanding_close_ops == 0) { MPIDI_CH3_Progress_signal_completion(); mpi_errno = MPIDI_CH3_Channel_close(); if (mpi_errno) MPIR_ERR_POP(mpi_errno); } break; default: { MPL_DBG_MSG_D(MPIDI_CH3_DBG_DISCONNECT,TYPICAL, "Unhandled connection state %d when closing connection",vc->state); mpi_errno = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_INTERN, "**ch3|unhandled_connection_state", "**ch3|unhandled_connection_state %p %d", vc, vc->state); goto fn_fail; break; } } /* FIXME: Decrement the reference count? Who increments? */ /* FIXME: The reference count is often already 0. But not always */ /* MPIR_Object_set_ref(vc, 0); ??? */ /* * FIXME: The VC used in connect accept has a NULL * process group */ /* XXX DJG FIXME-MT should we be checking this ref_count? */ if (vc->pg != NULL && (MPIR_Object_get_ref(vc) == 0)) { /* FIXME: Who increments the reference count that this is decrementing? */ /* When the reference count for a vc becomes zero, decrement the reference count of the associated process group. */ /* FIXME: This should be done when the reference count of the vc is first decremented */ MPIDI_PG_release_ref(vc->pg, &inuse); if (inuse == 0) { MPIDI_PG_Destroy(vc->pg); } } break; } default: { break; } } fn_exit: MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPIDI_CH3U_HANDLE_CONNECTION); return mpi_errno; fn_fail: goto fn_exit; }
int MPIDI_CH3_PktHandler_RndvReqToSend( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt, intptr_t *buflen, MPIR_Request **rreqp ) { MPIR_Request * rreq; int found; MPIDI_CH3_Pkt_rndv_req_to_send_t * rts_pkt = &pkt->rndv_req_to_send; int mpi_errno = MPI_SUCCESS; MPL_DBG_MSG_FMT(MPIDI_CH3_DBG_OTHER,VERBOSE,(MPL_DBG_FDEST, "received rndv RTS pkt, sreq=0x%08x, rank=%d, tag=%d, context=%d, data_sz=%" PRIdPTR, rts_pkt->sender_req_id, rts_pkt->match.parts.rank, rts_pkt->match.parts.tag, rts_pkt->match.parts.context_id, rts_pkt->data_sz)); MPL_DBG_MSGPKT(vc,rts_pkt->match.parts.tag,rts_pkt->match.parts.context_id, rts_pkt->match.parts.rank,rts_pkt->data_sz, "ReceivedRndv"); MPID_THREAD_CS_ENTER(POBJ, MPIR_THREAD_POBJ_MSGQ_MUTEX); rreq = MPIDI_CH3U_Recvq_FDP_or_AEU(&rts_pkt->match, &found); MPIR_ERR_CHKANDJUMP1(!rreq, mpi_errno,MPI_ERR_OTHER, "**nomemreq", "**nomemuereq %d", MPIDI_CH3U_Recvq_count_unexp()); /* If the completion counter is 0, that means that the communicator to * which this message is being sent has been revoked and we shouldn't * bother finishing this. */ if (!found && MPIR_cc_get(rreq->cc) == 0) { *rreqp = NULL; goto fn_fail; } set_request_info(rreq, rts_pkt, MPIDI_REQUEST_RNDV_MSG); MPID_THREAD_CS_EXIT(POBJ, MPIR_THREAD_POBJ_MSGQ_MUTEX); *buflen = sizeof(MPIDI_CH3_Pkt_t); if (found) { MPIR_Request * cts_req; MPIDI_CH3_Pkt_t upkt; MPIDI_CH3_Pkt_rndv_clr_to_send_t * cts_pkt = &upkt.rndv_clr_to_send; MPL_DBG_MSG(MPIDI_CH3_DBG_OTHER,VERBOSE,"posted request found"); /* FIXME: What if the receive user buffer is not big enough to hold the data about to be cleared for sending? */ MPL_DBG_MSG(MPIDI_CH3_DBG_OTHER,VERBOSE,"sending rndv CTS packet"); MPIDI_Pkt_init(cts_pkt, MPIDI_CH3_PKT_RNDV_CLR_TO_SEND); cts_pkt->sender_req_id = rts_pkt->sender_req_id; cts_pkt->receiver_req_id = rreq->handle; MPID_THREAD_CS_ENTER(POBJ, vc->pobj_mutex); mpi_errno = MPIDI_CH3_iStartMsg(vc, cts_pkt, sizeof(*cts_pkt), &cts_req); MPID_THREAD_CS_EXIT(POBJ, vc->pobj_mutex); if (mpi_errno != MPI_SUCCESS) { MPIR_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**ch3|ctspkt"); } if (cts_req != NULL) { MPIR_Request_free(cts_req); } } else { MPL_DBG_MSG(MPIDI_CH3_DBG_OTHER,VERBOSE,"unexpected request allocated"); /* * A MPID_Probe() may be waiting for the request we just * inserted, so we need to tell the progress engine to exit. * * FIXME: This will cause MPID_Progress_wait() to return to the * MPI layer each time an unexpected RTS packet is * received. MPID_Probe() should atomically increment a * counter and MPIDI_CH3_Progress_signal_completion() * should only be called if that counter is greater than zero. */ MPIDI_CH3_Progress_signal_completion(); } *rreqp = NULL; fn_fail: return mpi_errno; }