/* -*- Mode: C; c-basic-offset:4 ; -*- */ /* * (C) 2006 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. * * Portions of this code were written by Intel Corporation. * Copyright (C) 2011-2016 Intel Corporation. Intel provides this material * to Argonne National Laboratory subject to Software Grant and Corporate * Contributor License Agreement dated February 8, 2012. */ #ifndef CH4R_REQUEST_H_INCLUDED #define CH4R_REQUEST_H_INCLUDED #include "ch4_types.h" #include "ch4r_buf.h" #undef FUNCNAME #define FUNCNAME MPIDI_CH4I_am_request_create #undef FCNAME #define FCNAME MPL_QUOTE(FUNCNAME) static inline MPIR_Request *MPIDI_CH4I_am_request_create(MPIR_Request_kind_t kind, int ref_count) { MPIR_Request *req; int i; MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPIDI_CH4I_AM_REQUEST_CREATE); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPIDI_CH4I_AM_REQUEST_CREATE); req = MPIR_Request_create(kind); if (req == NULL) goto fn_fail; /* as long as ref_count is a constant, any compiler should be able * to unroll the below loop. when threading is not enabled, the * compiler should be able to combine the below individual * increments to a single increment of "ref_count - 1". * * FIXME: when threading is enabled, the ref_count increase is an * atomic operation, so it might be more inefficient. we should * use a new API to increase the ref_count value instead of the * for loop. */ for (i = 0; i < ref_count - 1; i++) MPIR_Request_add_ref(req); MPIDI_NM_am_request_init(req); CH4_COMPILE_TIME_ASSERT(sizeof(MPIDI_CH4U_req_ext_t) <= MPIDI_CH4I_BUF_POOL_SZ); MPIDI_CH4U_REQUEST(req, req) = (MPIDI_CH4U_req_ext_t *) MPIDI_CH4R_get_buf(MPIDI_CH4_Global.buf_pool); MPIR_Assert(MPIDI_CH4U_REQUEST(req, req)); MPIDI_CH4U_REQUEST(req, req->status) = 0; fn_exit: MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPIDI_CH4I_AM_REQUEST_CREATE); return req; fn_fail: goto fn_exit; } #undef FUNCNAME #define FUNCNAME MPIDI_CH4I_am_request_init #undef FCNAME #define FCNAME MPL_QUOTE(FUNCNAME) MPL_STATIC_INLINE_PREFIX MPIR_Request *MPIDI_CH4I_am_request_init(MPIR_Request * req, MPIR_Request_kind_t kind, int ref_increment) { int i; MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPIDI_CH4I_AM_REQUEST_INIT); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPIDI_CH4I_AM_REQUEST_INIT); MPIR_Assert(req != NULL); for (i = 0; i < ref_increment - 1; i++) MPIR_Request_add_ref(req); MPIDI_NM_am_request_init(req); CH4_COMPILE_TIME_ASSERT(sizeof(MPIDI_CH4U_req_ext_t) <= MPIDI_CH4I_BUF_POOL_SZ); MPIDI_CH4U_REQUEST(req, req) = (MPIDI_CH4U_req_ext_t *) MPIDI_CH4R_get_buf(MPIDI_CH4_Global.buf_pool); MPIR_Assert(MPIDI_CH4U_REQUEST(req, req)); MPIDI_CH4U_REQUEST(req, req->status) = 0; fn_exit: MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPIDI_CH4I_AM_REQUEST_INIT); return req; fn_fail: goto fn_exit; } #undef FUNCNAME #define FUNCNAME MPIDI_CH4I_am_request_copy #undef FCNAME #define FCNAME MPL_QUOTE(FUNCNAME) MPL_STATIC_INLINE_PREFIX void MPIDI_CH4I_am_request_copy(MPIR_Request * dest, MPIR_Request * src) { MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPIDI_CH4I_AM_REQUEST_COPY); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPIDI_CH4I_AM_REQUEST_COPY); MPIR_Assert(dest != NULL && src != NULL); MPIDI_NM_am_request_init(dest); MPIDI_CH4U_REQUEST(dest, req) = MPIDI_CH4U_REQUEST(src, req);; MPIDI_CH4U_REQUEST(dest, req->rreq.request) = (uint64_t) dest; MPIDI_CH4U_REQUEST(dest, datatype) = MPIDI_CH4U_REQUEST(src, datatype); MPIDI_CH4U_REQUEST(dest, buffer) = MPIDI_CH4U_REQUEST(src, buffer); MPIDI_CH4U_REQUEST(dest, count) = MPIDI_CH4U_REQUEST(src, count); MPIDI_CH4U_REQUEST(dest, rank) = MPIDI_CH4U_REQUEST(src, rank); MPIDI_CH4U_REQUEST(dest, tag) = MPIDI_CH4U_REQUEST(src, tag); MPIDI_CH4U_REQUEST(dest, context_id) = MPIDI_CH4U_REQUEST(src, context_id); MPIDI_CH4U_REQUEST(dest, req->status) = MPIDI_CH4U_REQUEST(src, req->status); fn_exit: MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPIDI_CH4I_AM_REQUEST_COPY); return; fn_fail: goto fn_exit; } /* This function should be called any time an anysource request is matched so * the upper layer will have a chance to arbitrate who wins the race between * the netmod and the shmod. This will cancel the request of the other side and * take care of copying any relevant data. */ static inline int MPIDI_CH4R_anysource_matched(MPIR_Request * rreq, int caller, int *continue_matching) { int mpi_errno = MPI_SUCCESS; MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPIDI_CH4R_ANYSOURCE_MATCHED); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPIDI_CH4R_ANYSOURCE_MATCHED); MPIR_Assert(MPIDI_CH4R_NETMOD == caller || MPIDI_CH4R_SHM == caller); if (MPIDI_CH4R_NETMOD == caller) { #ifndef MPIDI_CH4_DIRECT_NETMOD mpi_errno = MPIDI_SHM_mpi_cancel_recv(rreq); /* If the netmod is cancelling the request, then shared memory will * just copy the status from the shared memory side because the netmod * will always win the race condition here. */ if (MPIR_STATUS_GET_CANCEL_BIT(rreq->status)) { /* If the request is cancelled, copy the status object from the * partner request */ rreq->status = MPIDI_CH4I_REQUEST_ANYSOURCE_PARTNER(rreq)->status; } #endif *continue_matching = 0; } else if (MPIDI_CH4R_SHM == caller) { mpi_errno = MPIDI_NM_mpi_cancel_recv(rreq); /* If the netmod has already matched this request, shared memory will * lose and should stop matching this request */ *continue_matching = !MPIR_STATUS_GET_CANCEL_BIT(rreq->status); } MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPIDI_CH4R_ANYSOURCE_MATCHED); return mpi_errno; } #endif /* CH4R_REQUEST_H_INCLUDED */