root/ompi/mpi/cxx/win.cc

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

DEFINITIONS

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

   1 // -*- c++ -*-
   2 //
   3 // Copyright (c) 2006-2016 Los Alamos National Security, LLC.  All rights
   4 //                         reserved.
   5 // Copyright (c) 2007-2008 Sun Microsystems, Inc.  All rights reserved.
   6 // Copyright (c) 2007-2009 Cisco Systems, Inc.  All rights reserved.
   7 // $COPYRIGHT$
   8 //
   9 // Additional copyrights may follow
  10 //
  11 // $HEADER$
  12 //
  13 
  14 // do not include ompi_config.h because it kills the free/malloc defines
  15 #include "mpi.h"
  16 #include "ompi/constants.h"
  17 #include "ompi/mpi/cxx/mpicxx.h"
  18 #include "cxx_glue.h"
  19 
  20 void
  21 MPI::Win::Free()
  22 {
  23     (void) MPI_Win_free(&mpi_win);
  24 }
  25 
  26 
  27 // This function needs some internal OMPI types, so it's not inlined
  28 MPI::Errhandler
  29 MPI::Win::Create_errhandler(MPI::Win::Errhandler_function* function)
  30 {
  31     return ompi_cxx_errhandler_create_win ((ompi_cxx_dummy_fn_t *) function);
  32 }
  33 
  34 
  35 int
  36 MPI::Win::do_create_keyval(MPI_Win_copy_attr_function* c_copy_fn,
  37                                 MPI_Win_delete_attr_function* c_delete_fn,
  38                                 Copy_attr_function* cxx_copy_fn,
  39                                 Delete_attr_function* cxx_delete_fn,
  40                                 void* extra_state, int &keyval)
  41 {
  42     int ret, count = 0;
  43     keyval_intercept_data_t *cxx_extra_state;
  44 
  45     // If both the callbacks are C, then do the simple thing -- no
  46     // need for all the C++ machinery.
  47     if (NULL != c_copy_fn && NULL != c_delete_fn) {
  48         ret = ompi_cxx_attr_create_keyval_win (c_copy_fn, c_delete_fn, &keyval,
  49                                                extra_state, 0, NULL);
  50         if (MPI_SUCCESS != ret) {
  51             return ompi_cxx_errhandler_invoke_comm (MPI_COMM_WORLD, ret,
  52                                                     "MPI::Win::Create_keyval");
  53         }
  54     }
  55 
  56     // If either callback is C++, then we have to use the C++
  57     // callbacks for both, because we have to generate a new
  58     // extra_state.  And since we only get one extra_state (i.e., we
  59     // don't get one extra_state for the copy callback and another
  60     // extra_state for the delete callback), we have to use the C++
  61     // callbacks for both (and therefore translate the C++-special
  62     // extra_state into the user's original extra_state).
  63     cxx_extra_state = (keyval_intercept_data_t*)
  64         malloc(sizeof(keyval_intercept_data_t));
  65     if (NULL == cxx_extra_state) {
  66         return ompi_cxx_errhandler_invoke_comm (MPI_COMM_WORLD, MPI_ERR_NO_MEM,
  67                                                 "MPI::Win::Create_keyval");
  68     }
  69     cxx_extra_state->c_copy_fn = c_copy_fn;
  70     cxx_extra_state->cxx_copy_fn = cxx_copy_fn;
  71     cxx_extra_state->c_delete_fn = c_delete_fn;
  72     cxx_extra_state->cxx_delete_fn = cxx_delete_fn;
  73     cxx_extra_state->extra_state = extra_state;
  74 
  75     // Error check.  Must have exactly 2 non-NULL function pointers.
  76     if (NULL != c_copy_fn) {
  77         ++count;
  78     }
  79     if (NULL != c_delete_fn) {
  80         ++count;
  81     }
  82     if (NULL != cxx_copy_fn) {
  83         ++count;
  84     }
  85     if (NULL != cxx_delete_fn) {
  86         ++count;
  87     }
  88     if (2 != count) {
  89         free(cxx_extra_state);
  90         return ompi_cxx_errhandler_invoke_comm (MPI_COMM_WORLD, MPI_ERR_ARG,
  91                                                 "MPI::Win::Create_keyval");
  92     }
  93 
  94     // We do not call MPI_Win_create_keyval() here because we need to
  95     // pass in a special destructor to the backend keyval creation
  96     // that gets invoked when the keyval's reference count goes to 0
  97     // and is finally destroyed (i.e., clean up some caching/lookup
  98     // data here in the C++ bindings layer).  This destructor is
  99     // *only* used in the C++ bindings, so it's not set by the C
 100     // MPI_Comm_create_keyval().  Hence, we do all the work here (and
 101     // ensure to set the destructor atomicly when the keyval is
 102     // created).
 103 
 104     ret = ompi_cxx_attr_create_keyval_win ((MPI_Win_copy_attr_function *) ompi_mpi_cxx_win_copy_attr_intercept,
 105                                            ompi_mpi_cxx_win_delete_attr_intercept, &keyval,
 106                                            cxx_extra_state, 0, NULL);
 107     if (OMPI_SUCCESS != ret) {
 108         return ompi_cxx_errhandler_invoke_comm (MPI_COMM_WORLD, ret,
 109                                                 "MPI::Win::Create_keyval");
 110     }
 111 
 112     return MPI_SUCCESS;
 113 }

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