root/opal/mca/btl/vader/btl_vader_sendi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mca_btl_vader_sendi

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2011 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2009 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2007 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2006-2007 Voltaire. All rights reserved.
  14  * Copyright (c) 2009      Cisco Systems, Inc.  All rights reserved.
  15  * Copyright (c) 2010-2015 Los Alamos National Security, LLC. All rights
  16  *                         reserved.
  17  * Copyright (c) 2015      Mellanox Technologies. All rights reserved.
  18  *
  19  * $COPYRIGHT$
  20  *
  21  * Additional copyrights may follow
  22  *
  23  * $HEADER$
  24  */
  25 
  26 #include "opal_config.h"
  27 
  28 #include "btl_vader.h"
  29 #include "btl_vader_frag.h"
  30 #include "btl_vader_fifo.h"
  31 
  32 #include "btl_vader_fbox.h"
  33 
  34 /**
  35  * Initiate an inline send to the peer.
  36  *
  37  * @param btl (IN)      BTL module
  38  * @param peer (IN)     BTL peer addressing
  39  */
  40 int mca_btl_vader_sendi (struct mca_btl_base_module_t *btl,
  41                          struct mca_btl_base_endpoint_t *endpoint,
  42                          struct opal_convertor_t *convertor,
  43                          void *header, size_t header_size,
  44                          size_t payload_size, uint8_t order,
  45                          uint32_t flags, mca_btl_base_tag_t tag,
  46                          mca_btl_base_descriptor_t **descriptor)
  47 {
  48     mca_btl_vader_frag_t *frag;
  49     void *data_ptr = NULL;
  50     size_t length;
  51 
  52     /* don't attempt sendi if there are pending fragments on the endpoint */
  53     if (OPAL_UNLIKELY(opal_list_get_size (&endpoint->pending_frags))) {
  54         if (descriptor) {
  55             *descriptor = NULL;
  56         }
  57 
  58         return OPAL_ERR_OUT_OF_RESOURCE;
  59     }
  60 
  61     if (payload_size) {
  62         opal_convertor_get_current_pointer (convertor, &data_ptr);
  63     }
  64 
  65     if (!(payload_size && opal_convertor_need_buffers (convertor)) &&
  66         mca_btl_vader_fbox_sendi (endpoint, tag, header, header_size, data_ptr, payload_size)) {
  67         return OPAL_SUCCESS;
  68     }
  69 
  70     length = header_size + payload_size;
  71 
  72     /* allocate a fragment, giving up if we can't get one */
  73     frag = (mca_btl_vader_frag_t *) mca_btl_vader_alloc (btl, endpoint, order, length,
  74                                                          flags | MCA_BTL_DES_FLAGS_BTL_OWNERSHIP);
  75     if (OPAL_UNLIKELY(NULL == frag)) {
  76         if (descriptor) {
  77             *descriptor = NULL;
  78         }
  79 
  80         return OPAL_ERR_OUT_OF_RESOURCE;
  81     }
  82 
  83     /* fill in fragment fields */
  84     frag->hdr->len = length;
  85     frag->hdr->tag = tag;
  86 
  87     /* write the match header (with MPI comm/tag/etc. info) */
  88     memcpy (frag->segments[0].seg_addr.pval, header, header_size);
  89 
  90     /* write the message data if there is any */
  91     /* we can't use single-copy semantics here since as caller will consider the send
  92        complete when we return */
  93     if (payload_size) {
  94         uint32_t iov_count = 1;
  95         struct iovec iov;
  96 
  97         /* pack the data into the supplied buffer */
  98         iov.iov_base = (IOVBASE_TYPE *)((uintptr_t)frag->segments[0].seg_addr.pval + header_size);
  99         iov.iov_len  = length = payload_size;
 100 
 101         (void) opal_convertor_pack (convertor, &iov, &iov_count, &length);
 102 
 103         assert (length == payload_size);
 104     }
 105 
 106     /* write the fragment pointer to peer's the FIFO. the progress function will return the fragment */
 107     if (!vader_fifo_write_ep (frag->hdr, endpoint)) {
 108         if (descriptor) {
 109             *descriptor = &frag->base;
 110         } else {
 111             mca_btl_vader_free (btl, &frag->base);
 112         }
 113         return OPAL_ERR_OUT_OF_RESOURCE;
 114     }
 115 
 116     return OPAL_SUCCESS;
 117 }

/* [<][>][^][v][top][bottom][index][help] */