root/ompi/mca/mtl/portals4/mtl_portals4_recv_short.c

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

DEFINITIONS

This source file includes following definitions.
  1. ompi_mtl_portals4_recv_block_progress
  2. ompi_mtl_portals4_recv_short_block_alloc
  3. ompi_mtl_portals4_recv_short_block_free
  4. ompi_mtl_portals4_activate_block
  5. ompi_mtl_portals4_recv_short_init
  6. ompi_mtl_portals4_recv_short_fini
  7. ompi_mtl_portals4_recv_short_link

   1 /*
   2  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   3  *                         University Research and Technology
   4  *                         Corporation.  All rights reserved.
   5  * Copyright (c) 2004-2005 The University of Tennessee and The University
   6  *                         of Tennessee Research Foundation.  All rights
   7  *                         reserved.
   8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
   9  *                         University of Stuttgart.  All rights reserved.
  10  * Copyright (c) 2004-2005 The Regents of the University of California.
  11  *                         All rights reserved.
  12  * Copyright (c) 2010      Sandia National Laboratories.  All rights reserved.
  13  * $COPYRIGHT$
  14  *
  15  * Additional copyrights may follow
  16  *
  17  * $HEADER$
  18  */
  19 
  20 
  21 #include "ompi_config.h"
  22 
  23 #include "ompi/constants.h"
  24 
  25 #include "mtl_portals4.h"
  26 #include "mtl_portals4_recv_short.h"
  27 
  28 
  29 OBJ_CLASS_INSTANCE(ompi_mtl_portals4_recv_short_block_t,
  30                    opal_list_item_t,
  31                    NULL, NULL);
  32 
  33 static inline int ompi_mtl_portals4_activate_block(ompi_mtl_portals4_recv_short_block_t *block);
  34 static int ompi_mtl_portals4_recv_short_block_free(ompi_mtl_portals4_recv_short_block_t *block);
  35 
  36 static int
  37 ompi_mtl_portals4_recv_block_progress(ptl_event_t *ev,
  38                                      ompi_mtl_portals4_base_request_t* ptl_base_request)
  39 {
  40     int ret = OMPI_SUCCESS;
  41     ompi_mtl_portals4_recv_short_request_t *ptl_request =
  42         (ompi_mtl_portals4_recv_short_request_t*) ptl_base_request;
  43     ompi_mtl_portals4_recv_short_block_t *block = ptl_request->block;
  44 
  45     switch (ev->type) {
  46         case PTL_EVENT_AUTO_FREE:
  47             OPAL_THREAD_LOCK(&ompi_mtl_portals4.short_block_mutex);
  48             switch (block->status) {
  49                 case BLOCK_STATUS_ACTIVATED: /* May be encountered with multi threading */
  50                     block->status = BLOCK_STATUS_WAITING_UNLINK;
  51                     ompi_mtl_portals4.active_recv_short_blocks--;
  52                     OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
  53                     OPAL_OUTPUT_VERBOSE((10, ompi_mtl_base_framework.framework_output,
  54                                         "mtl:portals4 PTL_EVENT_AUTO_FREE received before PTL_EVENT_AUTO_UNLINK"));
  55                     break;
  56 
  57                 case BLOCK_STATUS_WAITING_FREE: /* Normal case */
  58                     if (OPAL_UNLIKELY(block->release_on_free)) {
  59                         opal_list_remove_item(&ompi_mtl_portals4.recv_short_blocks,
  60                                               &block->base);
  61                         OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
  62                         ret = ompi_mtl_portals4_recv_short_block_free(block);
  63                     } else {
  64                         OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
  65                         ret = ompi_mtl_portals4_activate_block(block);
  66                     }
  67                     break;
  68 
  69                 default:
  70                     OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
  71                     opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
  72                                         "%s:%d: Bad status (%d) when receiving PTL_EVENT_AUTO_FREE",
  73                                         __FILE__, __LINE__, block->status);
  74                     break;
  75             }
  76 
  77             break;
  78 
  79         case PTL_EVENT_AUTO_UNLINK:
  80             block->me_h = PTL_INVALID_HANDLE;
  81             OPAL_THREAD_LOCK(&ompi_mtl_portals4.short_block_mutex);
  82             switch (block->status) {
  83                 case BLOCK_STATUS_ACTIVATED: /* Normal case */
  84                     block->status = BLOCK_STATUS_WAITING_FREE;
  85                     ompi_mtl_portals4.active_recv_short_blocks--;
  86                     OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
  87                     break;
  88 
  89                 case BLOCK_STATUS_WAITING_UNLINK: /* May be encountered with multi threading */
  90                     if (OPAL_UNLIKELY(block->release_on_free)) {
  91                         opal_list_remove_item(&ompi_mtl_portals4.recv_short_blocks,
  92                                               &block->base);
  93                         OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
  94                         ret = ompi_mtl_portals4_recv_short_block_free(block);
  95                     } else {
  96                         OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
  97                         OPAL_OUTPUT_VERBOSE((10, ompi_mtl_base_framework.framework_output,
  98                                         "mtl:portals4 PTL_EVENT_AUTO_UNLINK received after PTL_EVENT_AUTO_FREE"));
  99                         ret = ompi_mtl_portals4_activate_block(block);
 100                     }
 101                     break;
 102 
 103                 default:
 104                     OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
 105                     opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
 106                                         "%s:%d: Bad status (%d) when receiving PTL_EVENT_AUTO_UNLINK",
 107                                         __FILE__, __LINE__, block->status);
 108                     break;
 109             }
 110 
 111             break;
 112 
 113         case PTL_EVENT_LINK:
 114             OPAL_THREAD_LOCK(&ompi_mtl_portals4.short_block_mutex);
 115             switch (block->status) {
 116                 case BLOCK_STATUS_WAITING_LINK:
 117                     block->status = BLOCK_STATUS_ACTIVATED;
 118                     ompi_mtl_portals4.active_recv_short_blocks++;
 119                     OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
 120                     break;
 121 
 122                 default:
 123                     OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
 124                     opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
 125                                         "%s:%d: Bad status (%d) when receiving PTL_EVENT_LINK",
 126                                         __FILE__, __LINE__, block->status);
 127                     break;
 128             }
 129 
 130             break;
 131 
 132         default:
 133             OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_framework.framework_output,
 134                                  "Other EVENT %d, hdr_data = %lx", ev->type, (long unsigned) ev->hdr_data));
 135             break;
 136     }
 137 
 138     return ret;
 139 }
 140 
 141 
 142 static ompi_mtl_portals4_recv_short_block_t*
 143 ompi_mtl_portals4_recv_short_block_alloc(bool release_on_free)
 144 {
 145     ompi_mtl_portals4_recv_short_block_t *block;
 146 
 147     block = OBJ_NEW(ompi_mtl_portals4_recv_short_block_t);
 148     block->start = malloc(ompi_mtl_portals4.recv_short_size);
 149     block->status = BLOCK_STATUS_INACTIVE;
 150     if (block->start == NULL) return NULL;
 151 
 152     block->me_h = PTL_INVALID_HANDLE;
 153     block->request.block = block;
 154     block->request.super.type = portals4_req_recv_short;
 155     block->request.super.event_callback = ompi_mtl_portals4_recv_block_progress;
 156     block->release_on_free = release_on_free;
 157 
 158     return block;
 159 }
 160 
 161 
 162 static int
 163 ompi_mtl_portals4_recv_short_block_free(ompi_mtl_portals4_recv_short_block_t *block)
 164 {
 165     if (PTL_INVALID_HANDLE != block->me_h) {
 166         PtlMEUnlink(block->me_h);
 167         block->me_h = PTL_INVALID_HANDLE;
 168     }
 169 
 170     if (NULL != block->start) {
 171         free(block->start);
 172         block->start = NULL;
 173     }
 174 
 175     OBJ_RELEASE(block);
 176 
 177     return OMPI_SUCCESS;
 178 }
 179 
 180 
 181 static inline int
 182 ompi_mtl_portals4_activate_block(ompi_mtl_portals4_recv_short_block_t *block)
 183 {
 184     ptl_match_bits_t match_bits = MTL_PORTALS4_SHORT_MSG;
 185     ptl_match_bits_t ignore_bits;
 186     ptl_me_t me;
 187     int ret;
 188 
 189     ignore_bits = MTL_PORTALS4_CONTEXT_MASK | MTL_PORTALS4_SOURCE_MASK | MTL_PORTALS4_TAG_MASK;
 190 
 191     me.start = block->start;
 192     me.length = ompi_mtl_portals4.recv_short_size;
 193     me.ct_handle = PTL_CT_NONE;
 194     me.min_free = ompi_mtl_portals4.short_limit;
 195     me.uid = ompi_mtl_portals4.uid;
 196     me.options =
 197         PTL_ME_OP_PUT |
 198         PTL_ME_EVENT_COMM_DISABLE |
 199         PTL_ME_MANAGE_LOCAL |
 200         PTL_ME_MAY_ALIGN;
 201     if (ompi_mtl_portals4.use_logical) {
 202         me.match_id.rank = PTL_RANK_ANY;
 203     } else {
 204         me.match_id.phys.nid = PTL_NID_ANY;
 205         me.match_id.phys.pid = PTL_PID_ANY;
 206     }
 207     me.match_bits = match_bits;
 208     me.ignore_bits = ignore_bits;
 209 
 210     OPAL_THREAD_LOCK(&ompi_mtl_portals4.short_block_mutex);
 211     block->status = BLOCK_STATUS_WAITING_LINK;
 212     OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
 213 
 214     ret = PtlMEAppend(ompi_mtl_portals4.ni_h,
 215                       ompi_mtl_portals4.recv_idx,
 216                       &me,
 217                       PTL_OVERFLOW_LIST,
 218                       &block->request,
 219                       &block->me_h);
 220     if (OPAL_LIKELY(ret == PTL_OK)) {
 221         ret = OMPI_SUCCESS;
 222     } else {
 223         ret = ompi_mtl_portals4_get_error(ret);
 224     }
 225 
 226     return ret;
 227 }
 228 
 229 
 230 int
 231 ompi_mtl_portals4_recv_short_init(void)
 232 {
 233     int ret = OMPI_SUCCESS;
 234     uint32_t i;
 235 
 236     OBJ_CONSTRUCT(&ompi_mtl_portals4.short_block_mutex, opal_mutex_t);
 237     OBJ_CONSTRUCT(&(ompi_mtl_portals4.recv_short_blocks), opal_list_t);
 238 
 239     /* create the recv blocks */
 240     for (i = 0 ; i < ompi_mtl_portals4.recv_short_num ; ++i) {
 241         ompi_mtl_portals4_recv_short_block_t *block =
 242             ompi_mtl_portals4_recv_short_block_alloc(false);
 243         if (OPAL_UNLIKELY(NULL == block)) {
 244             return OMPI_ERR_OUT_OF_RESOURCE;
 245         }
 246         opal_list_append(&ompi_mtl_portals4.recv_short_blocks,
 247                          &block->base);
 248         ret = ompi_mtl_portals4_activate_block(block);
 249     }
 250 
 251     return ret;
 252 }
 253 
 254 
 255 int
 256 ompi_mtl_portals4_recv_short_fini(void)
 257 {
 258     opal_list_item_t *item;
 259     int ret = OMPI_SUCCESS;
 260 
 261     OPAL_THREAD_LOCK(&ompi_mtl_portals4.short_block_mutex);
 262     while (NULL !=  (item = opal_list_remove_first(&ompi_mtl_portals4.recv_short_blocks))) {
 263         ompi_mtl_portals4_recv_short_block_t *block =
 264             (ompi_mtl_portals4_recv_short_block_t*) item;
 265         ret = ompi_mtl_portals4_recv_short_block_free(block);
 266         ompi_mtl_portals4.active_recv_short_blocks--;
 267     }
 268     OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
 269 
 270     return ret;
 271 }
 272 
 273 
 274 int
 275 ompi_mtl_portals4_recv_short_link(int count)
 276 {
 277     int ret = OMPI_SUCCESS;
 278     int active = ompi_mtl_portals4.active_recv_short_blocks;
 279     int i;
 280 
 281     if (active < count) {
 282         for (i = 0 ; i < (count - active) ; ++i) {
 283             ompi_mtl_portals4_recv_short_block_t *block =
 284                 ompi_mtl_portals4_recv_short_block_alloc(true);
 285             if (NULL == block) {
 286                 return OMPI_ERR_OUT_OF_RESOURCE;
 287             }
 288             OPAL_THREAD_LOCK(&ompi_mtl_portals4.short_block_mutex);
 289             opal_list_append(&ompi_mtl_portals4.recv_short_blocks,
 290                          &block->base);
 291             OPAL_OUTPUT_VERBOSE((10, ompi_mtl_base_framework.framework_output,
 292              "recv_short_link: total=%d active=%d",
 293              (int) opal_list_get_size(&ompi_mtl_portals4.recv_short_blocks), ompi_mtl_portals4.active_recv_short_blocks));
 294             OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
 295             ret = ompi_mtl_portals4_activate_block(block);
 296         }
 297     }
 298 
 299     return ret;
 300 }

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