📄 ch3u_handle_recv_pkt.c
字号:
#undef FUNCNAME#define FUNCNAME MPIDI_CH3I_Try_acquire_win_lock#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_CH3I_Try_acquire_win_lock(MPID_Win *win_ptr, int requested_lock){ int existing_lock; MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3I_TRY_ACQUIRE_WIN_LOCK); MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3I_TRY_ACQUIRE_WIN_LOCK); existing_lock = win_ptr->current_lock_type; /* Locking Rules: Requested Existing Action -------- -------- ------ Shared Exclusive Queue it Shared NoLock/Shared Grant it Exclusive NoLock Grant it Exclusive Exclusive/Shared Queue it */ if ( ( (requested_lock == MPI_LOCK_SHARED) && ((existing_lock == MPID_LOCK_NONE) || (existing_lock == MPI_LOCK_SHARED) ) ) || ( (requested_lock == MPI_LOCK_EXCLUSIVE) && (existing_lock == MPID_LOCK_NONE) ) ) { /* grant lock. set new lock type on window */ win_ptr->current_lock_type = requested_lock; /* if shared lock, incr. ref. count */ if (requested_lock == MPI_LOCK_SHARED) win_ptr->shared_lock_ref_cnt++; MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_TRY_ACQUIRE_WIN_LOCK); return 1; } else { /* do not grant lock */ MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_TRY_ACQUIRE_WIN_LOCK); return 0; }}#undef FUNCNAME#define FUNCNAME MPIDI_CH3I_Send_lock_granted_pkt#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_CH3I_Send_lock_granted_pkt(MPIDI_VC_t *vc, MPI_Win source_win_handle){ MPIDI_CH3_Pkt_t upkt; MPIDI_CH3_Pkt_lock_granted_t *lock_granted_pkt = &upkt.lock_granted; MPID_Request *req = NULL; int mpi_errno; MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3I_SEND_LOCK_GRANTED_PKT); MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3I_SEND_LOCK_GRANTED_PKT); /* send lock granted packet */ MPIDI_Pkt_init(lock_granted_pkt, MPIDI_CH3_PKT_LOCK_GRANTED); lock_granted_pkt->source_win_handle = source_win_handle; mpi_errno = MPIU_CALL(MPIDI_CH3,iStartMsg(vc, lock_granted_pkt, sizeof(*lock_granted_pkt), &req)); if (mpi_errno) { MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**ch3|rmamsg"); } if (req != NULL) { MPID_Request_release(req); } fn_fail: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_SEND_LOCK_GRANTED_PKT); return mpi_errno;}/* ------------------------------------------------------------------------ *//* Here are the functions that implement the packet actions. They'll be moved * to more modular places where it will be easier to replace subsets of the * in order to experiement with alternative data transfer methods, such as * sending some data with a rendezvous request or including data within * an eager message. * * The convention for the names of routines that handle packets is * MPIDI_CH3_PktHandler_<type>( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt ) * as in * MPIDI_CH3_PktHandler_EagerSend * * Each packet type also has a routine that understands how to print that * packet type, this routine is * MPIDI_CH3_PktPrint_<type>( FILE *, MPIDI_CH3_Pkt_t * ) * *//* ------------------------------------------------------------------------ */#undef FUNCNAME#define FUNCNAME MPIDI_CH3_PktHandler_Put#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_CH3_PktHandler_Put( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt, MPIDI_msg_sz_t *buflen, MPID_Request **rreqp ){ MPIDI_CH3_Pkt_put_t * put_pkt = &pkt->put; MPID_Request *req = NULL; int predefined; int type_size; int complete = 0; char *data_buf = NULL; MPIDI_msg_sz_t data_len; int mpi_errno = MPI_SUCCESS; MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3_PKTHANDLER_PUT); MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3_PKTHANDLER_PUT); MPIU_DBG_MSG(CH3_OTHER,VERBOSE,"received put pkt"); if (put_pkt->count == 0) { MPID_Win *win_ptr; /* it's a 0-byte message sent just to decrement the completion counter. This happens only in post/start/complete/wait sync model; therefore, no need to check lock queue. */ if (put_pkt->target_win_handle != MPI_WIN_NULL) { MPID_Win_get_ptr(put_pkt->target_win_handle, win_ptr); /* FIXME: MT: this has to be done atomically */ win_ptr->my_counter -= 1; } *buflen = sizeof(MPIDI_CH3_Pkt_t); MPIDI_CH3_Progress_signal_completion(); *rreqp = NULL; goto fn_exit; } data_len = *buflen - sizeof(MPIDI_CH3_Pkt_t); data_buf = (char *)pkt + sizeof(MPIDI_CH3_Pkt_t); req = MPID_Request_create(); MPIU_Object_set_ref(req, 1); req->dev.user_buf = put_pkt->addr; req->dev.user_count = put_pkt->count; req->dev.target_win_handle = put_pkt->target_win_handle; req->dev.source_win_handle = put_pkt->source_win_handle; MPIDI_CH3I_DATATYPE_IS_PREDEFINED(put_pkt->datatype, predefined); if (predefined) { MPIDI_Request_set_type(req, MPIDI_REQUEST_TYPE_PUT_RESP); req->dev.datatype = put_pkt->datatype; MPID_Datatype_get_size_macro(put_pkt->datatype, type_size); req->dev.recv_data_sz = type_size * put_pkt->count; if (req->dev.recv_data_sz == 0) { MPIDI_CH3U_Request_complete( req ); *buflen = sizeof(MPIDI_CH3_Pkt_t); *rreqp = NULL; goto fn_exit; } mpi_errno = MPIDI_CH3U_Receive_data_found(req, data_buf, &data_len, &complete); MPIU_ERR_CHKANDJUMP1(mpi_errno, mpi_errno, MPI_ERR_OTHER, "**ch3|postrecv", "**ch3|postrecv %s", "MPIDI_CH3_PKT_PUT"); /* FIXME: Only change the handling of completion if post_data_receive reset the handler. There should be a cleaner way to do this */ if (!req->dev.OnDataAvail) { req->dev.OnDataAvail = MPIDI_CH3_ReqHandler_PutAccumRespComplete; } /* return the number of bytes processed in this function */ *buflen = sizeof(MPIDI_CH3_Pkt_t) + data_len; if (complete) { mpi_errno = MPIDI_CH3_ReqHandler_PutAccumRespComplete(vc, req, &complete); if (mpi_errno) MPIU_ERR_POP(mpi_errno); if (complete) { *rreqp = NULL; goto fn_exit; } } } else { /* derived datatype */ MPIDI_Request_set_type(req, MPIDI_REQUEST_TYPE_PUT_RESP_DERIVED_DT); req->dev.datatype = MPI_DATATYPE_NULL; req->dev.dtype_info = (MPIDI_RMA_dtype_info *) MPIU_Malloc(sizeof(MPIDI_RMA_dtype_info)); if (! req->dev.dtype_info) { MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem"); } req->dev.dataloop = MPIU_Malloc(put_pkt->dataloop_size); if (! req->dev.dataloop) { MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem"); } /* if we received all of the dtype_info and dataloop, copy it now and call the handler, otherwise set the iov and let the channel copy it */ if (data_len >= sizeof(MPIDI_RMA_dtype_info) + put_pkt->dataloop_size) { /* copy all of dtype_info and dataloop */ memcpy(req->dev.dtype_info, data_buf, sizeof(MPIDI_RMA_dtype_info)); memcpy(req->dev.dataloop, data_buf + sizeof(MPIDI_RMA_dtype_info), put_pkt->dataloop_size); *buflen = sizeof(MPIDI_CH3_Pkt_t) + sizeof(MPIDI_RMA_dtype_info) + put_pkt->dataloop_size; /* All dtype data has been received, call req handler */ mpi_errno = MPIDI_CH3_ReqHandler_PutRespDerivedDTComplete(vc, req, &complete); MPIU_ERR_CHKANDJUMP1(mpi_errno, mpi_errno, MPI_ERR_OTHER, "**ch3|postrecv", "**ch3|postrecv %s", "MPIDI_CH3_PKT_PUT"); if (complete) { *rreqp = NULL; goto fn_exit; } } else { req->dev.iov[0].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)((char *)req->dev.dtype_info); req->dev.iov[0].MPID_IOV_LEN = sizeof(MPIDI_RMA_dtype_info); req->dev.iov[1].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)req->dev.dataloop; req->dev.iov[1].MPID_IOV_LEN = put_pkt->dataloop_size; req->dev.iov_count = 2; *buflen = sizeof(MPIDI_CH3_Pkt_t); req->dev.OnDataAvail = MPIDI_CH3_ReqHandler_PutRespDerivedDTComplete; } } *rreqp = req; if (mpi_errno != MPI_SUCCESS) { MPIU_ERR_SET1(mpi_errno,MPI_ERR_OTHER,"**ch3|postrecv", "**ch3|postrecv %s", "MPIDI_CH3_PKT_PUT"); } fn_exit: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3_PKTHANDLER_PUT); return mpi_errno; fn_fail: goto fn_exit;}#undef FUNCNAME#define FUNCNAME MPIDI_CH3_PktHandler_Get#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_CH3_PktHandler_Get( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt, MPIDI_msg_sz_t *buflen, MPID_Request **rreqp ){ MPIDI_CH3_Pkt_get_t * get_pkt = &pkt->get; MPID_Request *req = NULL; MPID_IOV iov[MPID_IOV_LIMIT]; int predefined; int complete; char *data_buf = NULL; MPIDI_msg_sz_t data_len; int mpi_errno = MPI_SUCCESS; int type_size; MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3_PKTHANDLER_GET); MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3_PKTHANDLER_GET); MPIU_DBG_MSG(CH3_OTHER,VERBOSE,"received get pkt"); data_len = *buflen - sizeof(MPIDI_CH3_Pkt_t); data_buf = (char *)pkt + sizeof(MPIDI_CH3_Pkt_t); req = MPID_Request_create(); req->dev.target_win_handle = get_pkt->target_win_handle; req->dev.source_win_handle = get_pkt->source_win_handle; MPIDI_CH3I_DATATYPE_IS_PREDEFINED(get_pkt->datatype, predefined); if (predefined) { /* basic datatype. send the data. */ MPIDI_CH3_Pkt_t upkt; MPIDI_CH3_Pkt_get_resp_t * get_resp_pkt = &upkt.get_resp; MPIDI_Request_set_type(req, MPIDI_REQUEST_TYPE_GET_RESP); req->dev.OnDataAvail = MPIDI_CH3_ReqHandler_GetSendRespComplete; req->dev.OnFinal = MPIDI_CH3_ReqHandler_GetSendRespComplete; req->kind = MPID_REQUEST_SEND; MPIDI_Pkt_init(get_resp_pkt, MPIDI_CH3_PKT_GET_RESP); get_resp_pkt->request_handle = get_pkt->request_handle; iov[0].MPID_IOV_BUF = (MPID_IOV_BUF_CAST) get_resp_pkt; iov[0].MPID_IOV_LEN = sizeof(*get_resp_pkt); iov[1].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)get_pkt->addr; MPID_Datatype_get_size_macro(get_pkt->datatype, type_size); iov[1].MPID_IOV_LEN = get_pkt->count * type_size; mpi_errno = MPIU_CALL(MPIDI_CH3,iSendv(vc, req, iov, 2)); /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) { MPIU_Object_set_ref(req, 0); MPIDI_CH3_Request_destroy(req); MPIU_ERR_SETFATALANDJUMP(mpi_errno,MPI_ERR_OTHER,"**ch3|rmamsg"); } /* --END ERROR HANDLING-- */ *buflen = sizeof(MPIDI_CH3_Pkt_t); *rreqp = NULL; } else { /* derived datatype. first get the dtype_info and dataloop. */ MPIDI_Request_set_type(req, MPIDI_REQUEST_TYPE_GET_RESP_DERIVED_DT); req->dev.OnDataAvail = MPIDI_CH3_ReqHandler_GetRespDerivedDTComplete; req->dev.OnFinal = 0; req->dev.user_buf = get_pkt->addr; req->dev.user_count = get_pkt->count; req->dev.datatype = MPI_DATATYPE_NULL; req->dev.request_handle = get_pkt->request_handle; req->dev.dtype_info = (MPIDI_RMA_dtype_info *) MPIU_Malloc(sizeof(MPIDI_RMA_dtype_info)); if (! req->dev.dtype_info) { MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem" ); } req->dev.dataloop = MPIU_Malloc(get_pkt->dataloop_size); if (! req->dev.dataloop) { MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**nomem" ); } /* if we received all of the dtype_info and dataloop, copy it now and call the handler, otherwise set the iov and let the channel copy it */ if (data_len >= sizeof(MPIDI_RMA_dtype_info) + get_pkt->dataloop_size) { /* copy all of dtype_info and dataloop */ memcpy(req->dev.dtype_info, data_buf, sizeof(MPIDI_RMA_dtype_info)); memcpy(req->dev.dataloop, data_buf + sizeof(MPIDI_RMA_dtype_info), get_pkt->dataloop_size); *buflen = sizeof(MPIDI_CH3_Pkt_t) + sizeof(MPIDI_RMA_dtype_info) + get_pkt->dataloop_size; /* All dtype data has been received, call req handler */ mpi_errno = MPIDI_CH3_ReqHandler_GetRespDerivedDTComplete(vc, req, &complete); MPIU_ERR_CHKANDJUMP1(mpi_errno, mpi_errno, MPI_ERR_OTHER, "**ch3|postrecv", "**ch3|postrecv %s", "MPIDI_CH3_PKT_GET"); if (complete) *rreqp = NULL; } else { req->dev.iov[0].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)req->dev.dtype_info; req->dev.iov[0].MPID_IOV_LEN = sizeof(MPIDI_RMA_dtype_info); req->dev.iov[1].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)req->dev.dataloop; req->dev.iov[1].MPID_IOV_LEN = get_pkt->dataloop_size; req->dev.iov_count = 2; *buflen = sizeof(MPIDI_CH3_Pkt_t); *rreqp = req; } } fn_fail: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3_PKTHANDLER_GET); return mpi_errno;}#undef FUNCNAME#define FUNCNAME MPIDI_CH3_PktHandler_GetResp#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)int MPIDI_CH3_PktHandler_GetResp( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt, MPIDI_msg_sz_t *buflen, MPID_Request **rreqp ){ MPIDI_CH3_Pkt_get_resp_t * get_resp_pkt = &pkt->get_resp; MPID_Request *req; int complete; char *data_buf = NULL; MPIDI_msg_sz_t data_len; int mpi_errno = MPI_SUCCESS; int type_size; MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3_PKTHANDLER_GETRESP);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -