Blame src/mpid/ch4/src/ch4r_request.h

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