root/ompi/mpi/cxx/comm.cc

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

DEFINITIONS

This source file includes following definitions.
  1. Create_errhandler
  2. do_create_keyval

   1 // -*- c++ -*-
   2 //
   3 // Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   4 //                         University Research and Technology
   5 //                         Corporation.  All rights reserved.
   6 // Copyright (c) 2004-2005 The University of Tennessee and The University
   7 //                         of Tennessee Research Foundation.  All rights
   8 //                         reserved.
   9 // Copyright (c) 2004-2005 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) 2007-2008 Cisco Systems, Inc.  All rights reserved.
  14 // Copyright (c) 2016      Los Alamos National Security, LLC. All rights
  15 //                         reserved.
  16 // $COPYRIGHT$
  17 //
  18 // Additional copyrights may follow
  19 //
  20 // $HEADER$
  21 //
  22 
  23 // do not include ompi_config.h because it kills the free/malloc defines
  24 #include "mpi.h"
  25 #include "ompi/constants.h"
  26 #include "ompi/mpi/cxx/mpicxx.h"
  27 #include "cxx_glue.h"
  28 
  29 
  30 //
  31 // These functions are all not inlined because they need to use locks to
  32 // protect the handle maps and it would be bad to have those in headers
  33 // because that would require that we always install the lock headers.
  34 // Instead we take the function call hit (we're locking - who cares about
  35 // a function call.  And these aren't exactly the performance critical
  36 // functions) and make everyone's life easier.
  37 //
  38 
  39 
  40 // construction
  41 MPI::Comm::Comm()
  42 {
  43 }
  44 
  45 // copy
  46 MPI::Comm::Comm(const Comm_Null& data) : Comm_Null(data)
  47 {
  48 }
  49 
  50 // This function needs some internal OMPI types, so it's not inlined
  51 MPI::Errhandler
  52 MPI::Comm::Create_errhandler(MPI::Comm::_MPI2CPP_ERRHANDLERFN_* function)
  53 {
  54     return ompi_cxx_errhandler_create_comm ((ompi_cxx_dummy_fn_t *) function);
  55 }
  56 
  57 
  58 //JGS I took the const out because it causes problems when trying to
  59 //call this function with the predefined NULL_COPY_FN etc.
  60 int
  61 MPI::Comm::do_create_keyval(MPI_Comm_copy_attr_function* c_copy_fn,
  62                             MPI_Comm_delete_attr_function* c_delete_fn,
  63                             Copy_attr_function* cxx_copy_fn,
  64                             Delete_attr_function* cxx_delete_fn,
  65                             void* extra_state, int &keyval)
  66 {
  67     int ret, count = 0;
  68     keyval_intercept_data_t *cxx_extra_state;
  69 
  70     // If both the callbacks are C, then do the simple thing -- no
  71     // need for all the C++ machinery.
  72     if (NULL != c_copy_fn && NULL != c_delete_fn) {
  73         ret = ompi_cxx_attr_create_keyval_comm (c_copy_fn, c_delete_fn, &keyval,
  74                                                 extra_state, 0, NULL);
  75         if (MPI_SUCCESS != ret) {
  76             return ompi_cxx_errhandler_invoke_comm(MPI_COMM_WORLD, ret,
  77                                           "MPI::Comm::Create_keyval");
  78         }
  79     }
  80 
  81     // If either callback is C++, then we have to use the C++
  82     // callbacks for both, because we have to generate a new
  83     // extra_state.  And since we only get one extra_state (i.e., we
  84     // don't get one extra_state for the copy callback and another
  85     // extra_state for the delete callback), we have to use the C++
  86     // callbacks for both (and therefore translate the C++-special
  87     // extra_state into the user's original extra_state).  Ensure to
  88     // malloc() the struct here (vs new) so that it can be free()'ed
  89     // by the C attribute base.
  90     cxx_extra_state = (keyval_intercept_data_t*)
  91         malloc(sizeof(keyval_intercept_data_t));
  92     if (NULL == cxx_extra_state) {
  93         return ompi_cxx_errhandler_invoke_comm (MPI_COMM_WORLD, MPI_ERR_NO_MEM,
  94                                                 "MPI::Comm::Create_keyval");
  95     }
  96     cxx_extra_state->c_copy_fn = c_copy_fn;
  97     cxx_extra_state->cxx_copy_fn = cxx_copy_fn;
  98     cxx_extra_state->c_delete_fn = c_delete_fn;
  99     cxx_extra_state->cxx_delete_fn = cxx_delete_fn;
 100     cxx_extra_state->extra_state = extra_state;
 101 
 102     // Error check.  Must have exactly 2 non-NULL function pointers.
 103     if (NULL != c_copy_fn) {
 104         ++count;
 105     }
 106     if (NULL != c_delete_fn) {
 107         ++count;
 108     }
 109     if (NULL != cxx_copy_fn) {
 110         ++count;
 111     }
 112     if (NULL != cxx_delete_fn) {
 113         ++count;
 114     }
 115     if (2 != count) {
 116         free(cxx_extra_state);
 117         return ompi_cxx_errhandler_invoke_comm (MPI_COMM_WORLD, MPI_ERR_ARG,
 118                                                 "MPI::Comm::Create_keyval");
 119     }
 120 
 121     // We do not call MPI_Comm_create_keyval() here because we need to
 122     // pass in the cxx_extra_state to the backend keyval creation so
 123     // that when the keyval is destroyed (i.e., when its refcount goes
 124     // to 0), the cxx_extra_state is free()'ed.
 125     ret = ompi_cxx_attr_create_keyval_comm ((MPI_Comm_copy_attr_function *) ompi_mpi_cxx_comm_copy_attr_intercept,
 126                                             ompi_mpi_cxx_comm_delete_attr_intercept,
 127                                             &keyval, cxx_extra_state, 0, cxx_extra_state);
 128     if (OMPI_SUCCESS != ret) {
 129         return ompi_cxx_errhandler_invoke_comm (MPI_COMM_WORLD, ret,
 130                                                 "MPI::Comm::Create_keyval");
 131     }
 132 
 133     return MPI_SUCCESS;
 134 }
 135 

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