static int mca_oob_ud_recv_copy (mca_oob_ud_req_t *dst, mca_oob_ud_req_t *src)
{
    int rc, i;

    dst->req_rem_data_len = src->req_rem_data_len;

    rc = mca_oob_ud_recv_alloc (dst);

    if (ORTE_SUCCESS == rc) {
        unsigned char *dptr = src->req_uiov[0].iov_base;

        for (i = 0 ; i < dst->req_count ; ++i) {
            memcpy (dst->req_uiov[i].iov_base, dptr, dst->req_uiov[i].iov_len);
            dptr += dst->req_uiov[i].iov_len;
        }
    }

    mca_oob_ud_req_complete (dst, (ORTE_SUCCESS == rc) ? dst->req_rem_data_len : rc);

    /* free io vector data */
    free (src->req_uiov[0].iov_base);
    free (src->req_uiov);
    src->req_uiov = NULL;

    OBJ_RELEASE(src);

    return rc;
}
int mca_oob_ud_recv_match_send (mca_oob_ud_port_t *port, mca_oob_ud_peer_t *peer, mca_oob_ud_msg_hdr_t *msg_hdr,
                                mca_oob_ud_req_t **reqp)
{
    char *data = (msg_hdr->msg_data.req.data_follows ? (char *)(msg_hdr + 1) : NULL);
    mca_oob_ud_req_t *req;
    int rc, i;

    *reqp = NULL;

    OPAL_OUTPUT_VERBOSE((10, mca_oob_base_output, "%s oob:ud:recv_incoming_send matching incoming "
                         "send from peer %s with tag %d", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
                         ORTE_NAME_PRINT(&msg_hdr->msg_origin), msg_hdr->msg_data.req.tag));

    rc = mca_oob_ud_get_recv_req (msg_hdr->msg_origin, msg_hdr->msg_data.req.tag, &req);
    if (ORTE_SUCCESS != rc) {
        return rc;
    }

    req->req_rem_ctx      = msg_hdr->msg_rem_ctx;
    req->req_port         = port;
    req->req_mtu          = min(port->mtu, msg_hdr->msg_data.req.mtu);
    req->req_target       = msg_hdr->ra.name;
    req->req_rem_data_len = msg_hdr->msg_data.req.data_len;

    do {
        rc = mca_oob_ud_recv_alloc (req);
        if (ORTE_SUCCESS != rc) {
            opal_output (0, "%s oob:ud:recv_start malloc failed!", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME));
            if (MCA_OOB_UD_REQ_UNEX == req->type) {
                free (req->req_uiov);
                OBJ_RELEASE(req);
            }
            req = NULL;
            break;
        }

        req->req_peer = peer;
        OBJ_RETAIN(req->req_peer);

        if (NULL == data) {
            req->state = MCA_OOB_UD_REQ_ACTIVE;
            break;
        }

        OPAL_OUTPUT_VERBOSE((10, mca_oob_base_output, "%s oob:ud:recv_incoming_send send was eager",
                             ORTE_NAME_PRINT(ORTE_PROC_MY_NAME)));

        req->req_is_eager = true;

        for (i = 0 ; i < req->req_count; ++i) {
            memcpy (req->req_uiov[i].iov_base, data, req->req_uiov[i].iov_len);
            data += req->req_uiov[i].iov_len;
        }

        req->state = MCA_OOB_UD_REQ_COMPLETE;
    } while (0);

    *reqp = req;

    return rc;
}
Exemple #3
0
static int mca_oob_ud_send_self (orte_rml_send_t *msg)
{
    unsigned int srco, dsto;
    mca_oob_ud_req_t *req;
    int srci, dsti;
    int rc, size;

    MCA_OOB_UD_IOV_SIZE(msg, size);

    opal_output_verbose(10, orte_oob_base_framework.framework_output,
                         "%s mca_oob_ud_send_self: sending %d bytes to myself",
                         ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), size);

    rc = mca_oob_ud_get_recv_req (*ORTE_PROC_MY_NAME, msg->tag, &req, (msg->iov != NULL) ? true : false);
    if (ORTE_SUCCESS != rc) {
        return rc;
    }

    req->req_rem_data_len = size;
    req->req_is_eager     = true;

    rc = mca_oob_ud_recv_alloc (req);
    if (ORTE_SUCCESS != rc) {
        ORTE_ERROR_LOG(rc);
        if (MCA_OOB_UD_REQ_IOV == req->req_data_type) {
            free (req->req_data.iov.uiov);
        }
        OBJ_RELEASE(req);
        return rc;
    }

    srci = dsti = 0;
    srco = dsto = 0;

    if (msg->iov != NULL) {
        do {
            req->req_data_type = MCA_OOB_UD_REQ_IOV;
            size_t copy = min(msg->iov[srci].iov_len - srco,
                              req->req_data.iov.uiov[dsti].iov_len - dsto);

            memmove ((unsigned char *) req->req_data.iov.uiov[dsti].iov_base + dsto,
                     (unsigned char *) msg->iov[srci].iov_base + srco, copy);

            srco += copy;
            if (srco == msg->iov[srci].iov_len) {
                srci++;
                srco = 0;
            }

            dsto += copy;
            if (dsto == req->req_data.iov.uiov[dsti].iov_len) {
                dsti++;
                dsto = 0;
            }
        } while (srci < req->req_data.iov.count && dsti < msg->count);
    } else {
        req->req_data_type = MCA_OOB_UD_REQ_BUF;

        opal_buffer_t *buffer;
        buffer = OBJ_NEW(opal_buffer_t);

        if (OPAL_SUCCESS != (rc = opal_dss.copy_payload(buffer, msg->buffer))) {
            ORTE_ERROR_LOG(rc);
            OBJ_RELEASE(buffer);
            return rc;
        }
        if (OPAL_SUCCESS != (rc = opal_dss.unload(buffer, (void **)&req->req_data.buf.p, &req->req_data.buf.size)))
        {
            ORTE_ERROR_LOG(rc);
            OBJ_RELEASE(buffer);
            free(req->req_data.buf.p);
            return rc;
        }
        OBJ_RELEASE(buffer);
    }

    req->state = MCA_OOB_UD_REQ_COMPLETE;

    opal_output_verbose(10, orte_oob_base_framework.framework_output,
                         "%s mca_oob_ud_send_self: complete. calling callbacks",
                         ORTE_NAME_PRINT(ORTE_PROC_MY_NAME));

    /* queue up recv callback */
    mca_oob_ud_event_queue_completed (req);

    req->rml_msg->status = ORTE_SUCCESS;

    ORTE_RML_SEND_COMPLETE(req->rml_msg);

    return size;
}