root/opal/mca/btl/uct/btl_uct_device_context.h

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. mca_btl_uct_context_trylock
  2. mca_btl_uct_context_lock
  3. mca_btl_uct_context_unlock
  4. mca_btl_uct_get_context_index
  5. mca_btl_uct_module_get_tl_context_specific
  6. mca_btl_uct_module_get_rdma_context
  7. mca_btl_uct_module_get_rdma_context_specific
  8. mca_btl_uct_module_get_am_context
  9. mca_btl_uct_device_handle_completions
  10. mca_btl_uct_context_progress

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2014-2018 Los Alamos National Security, LLC. All rights
   4  *                         reserved.
   5  * $COPYRIGHT$
   6  *
   7  * Additional copyrights may follow
   8  *
   9  * $HEADER$
  10  */
  11 
  12 #if !defined(BTL_UCT_DEVICE_CONTEXT_H)
  13 #define BTL_UCT_DEVICE_CONTEXT_H
  14 
  15 #include "btl_uct.h"
  16 #include "btl_uct_rdma.h"
  17 #include "btl_uct_frag.h"
  18 
  19 /**
  20  * @brief Create a new device context for the given transport
  21  *
  22  * @param[in] module     btl uct module
  23  * @param[in] tl         btl uct tl pointer
  24  * @param[in] context_id identifier for this context (0..MCA_BTL_UCT_MAX_WORKERS-1)
  25  */
  26 mca_btl_uct_device_context_t *mca_btl_uct_context_create (mca_btl_uct_module_t *module, mca_btl_uct_tl_t *tl, int context_id, bool enable_progress);
  27 
  28 /**
  29  * @brief Destroy a device context and release all resources
  30  *
  31  * @param[in] context   btl uct device context
  32  *
  33  * This call frees a device context and all assoicated resources. It is not
  34  * valid to use the device context after this returns.
  35  */
  36 void mca_btl_uct_context_destroy (mca_btl_uct_device_context_t *context);
  37 
  38 static inline bool mca_btl_uct_context_trylock (mca_btl_uct_device_context_t *context)
  39 {
  40     return OPAL_THREAD_TRYLOCK(&context->mutex);
  41 }
  42 
  43 static inline void mca_btl_uct_context_lock (mca_btl_uct_device_context_t *context)
  44 {
  45     OPAL_THREAD_LOCK (&context->mutex);
  46 }
  47 
  48 static inline void mca_btl_uct_context_unlock (mca_btl_uct_device_context_t *context)
  49 {
  50     OPAL_THREAD_UNLOCK (&context->mutex);
  51 }
  52 
  53 #define MCA_BTL_UCT_CONTEXT_SERIALIZE(context,code)     \
  54     do {                                                \
  55         mca_btl_uct_context_lock (context);             \
  56         code;                                           \
  57         mca_btl_uct_context_unlock(context);            \
  58     } while (0);
  59 
  60 static inline int mca_btl_uct_get_context_index (void)
  61 {
  62     static opal_atomic_uint32_t next_uct_index = 0;
  63     int context_id;
  64 
  65 #if OPAL_C_HAVE__THREAD_LOCAL
  66     if (mca_btl_uct_component.bind_threads_to_contexts) {
  67         static _Thread_local int uct_index = -1;
  68 
  69         context_id = uct_index;
  70         if (OPAL_UNLIKELY(-1 == context_id)) {
  71             context_id = uct_index = opal_atomic_fetch_add_32 ((opal_atomic_int32_t *) &next_uct_index, 1) %
  72                 mca_btl_uct_component.num_contexts_per_module;
  73         }
  74     } else {
  75 #endif
  76         /* avoid using atomics in this. i doubt it improves performance to ensure atomicity on the next
  77          * index in this case. */
  78         context_id = next_uct_index++ % mca_btl_uct_component.num_contexts_per_module;
  79 #if OPAL_C_HAVE__THREAD_LOCAL
  80     }
  81 #endif
  82 
  83     return context_id;
  84 }
  85 
  86 static inline mca_btl_uct_device_context_t *
  87 mca_btl_uct_module_get_tl_context_specific (mca_btl_uct_module_t *module, mca_btl_uct_tl_t *tl, int context_id)
  88 {
  89     mca_btl_uct_device_context_t *context = tl->uct_dev_contexts[context_id];
  90 
  91     if (OPAL_UNLIKELY(NULL == context)) {
  92         OPAL_THREAD_LOCK(&module->lock);
  93         context = tl->uct_dev_contexts[context_id];
  94         if (OPAL_UNLIKELY(NULL == context)) {
  95             context = tl->uct_dev_contexts[context_id] = mca_btl_uct_context_create (module, tl, context_id, true);
  96         }
  97         OPAL_THREAD_UNLOCK(&module->lock);
  98     }
  99 
 100     return context;
 101 }
 102 
 103 static inline mca_btl_uct_device_context_t *mca_btl_uct_module_get_rdma_context (mca_btl_uct_module_t *module)
 104 {
 105     return mca_btl_uct_module_get_tl_context_specific (module, module->rdma_tl, mca_btl_uct_get_context_index ());
 106 }
 107 
 108 static inline mca_btl_uct_device_context_t *mca_btl_uct_module_get_rdma_context_specific (mca_btl_uct_module_t *module, int context_id)
 109 {
 110     return mca_btl_uct_module_get_tl_context_specific (module, module->rdma_tl, context_id);
 111 }
 112 
 113 static inline mca_btl_uct_device_context_t *mca_btl_uct_module_get_am_context (mca_btl_uct_module_t *module)
 114 {
 115     return mca_btl_uct_module_get_tl_context_specific (module, module->am_tl, mca_btl_uct_get_context_index ());
 116 }
 117 
 118 static inline void mca_btl_uct_device_handle_completions (mca_btl_uct_device_context_t *dev_context)
 119 {
 120     mca_btl_uct_uct_completion_t *comp;
 121 
 122     while (NULL != (comp = (mca_btl_uct_uct_completion_t *) opal_fifo_pop (&dev_context->completion_fifo))) {
 123         int rc = UCS_OK == comp->status ? OPAL_SUCCESS : OPAL_ERROR;
 124 
 125         if (comp->frag) {
 126             /* reset the count */
 127             comp->uct_comp.count = 1;
 128             mca_btl_uct_frag_complete (comp->frag, rc);
 129 
 130             continue;
 131         }
 132 
 133         /* we may be calling the callback before remote completion. this is in violation of the
 134          * btl interface specification but should not hurt in non-ob1 use cases. if this ever
 135          * becomes a problem we can look at possible solutions. */
 136         comp->cbfunc (comp->btl, comp->endpoint, comp->local_address, comp->local_handle,
 137                       comp->cbcontext, comp->cbdata, rc);
 138         mca_btl_uct_uct_completion_release (comp);
 139     }
 140 }
 141 
 142 static inline int mca_btl_uct_context_progress (mca_btl_uct_device_context_t *context)
 143 {
 144     int ret = 0;
 145 
 146     if (!context->uct_worker) {
 147         return 0;
 148     }
 149 
 150     if (!mca_btl_uct_context_trylock (context)) {
 151         ret = uct_worker_progress (context->uct_worker);
 152         mca_btl_uct_context_unlock (context);
 153 
 154         mca_btl_uct_device_handle_completions (context);
 155     }
 156 
 157     return ret;
 158 }
 159 
 160 #endif /* BTL_UCT_DEVICE_CONTEXT_H */

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