1
1
openmpi/ompi/mpi/cxx/file.cc
Jeff Squyres 26d8fe70c3 Fixes trac:1029: add in support for MPI_CONVERSION_FN_NULL.
This commit brings over all the work from the /tmp-public/datarep
branch.  See commits r16855, r16859, r16860 for the highlights of what
was done.

This commit was SVN r16891.

The following SVN revisions from the original message are invalid or
inconsistent and therefore were not cross-referenced:
  r16855
  r16859
  r16860

The following Trac tickets were found above:
  Ticket 1029 --> https://svn.open-mpi.org/trac/ompi/ticket/1029
2007-12-07 13:09:07 +00:00

231 строка
7.8 KiB
C++

// -*- c++ -*-
//
// Copyright (c) 2006 Los Alamos National Security, LLC. All rights
// reserved.
// Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
// $COPYRIGHT$
//
// Additional copyrights may follow
//
// $HEADER$
//
// Do not include ompi_config.h before mpi.h because it causes
// malloc/free problems due to setting OMPI_BUILDING to 1
#include "mpi.h"
#include "ompi/constants.h"
#include "ompi/mpi/cxx/mpicxx.h"
#include "opal/threads/mutex.h"
#include "opal/class/opal_list.h"
#include "ompi/file/file.h"
#include "ompi/errhandler/errhandler.h"
#include "ompi/runtime/mpiruntime.h"
void
MPI::File::Close()
{
MPI_File save = mpi_file;
(void) MPI_File_close(&mpi_file);
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
MPI::File::mpi_file_map.erase(save);
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
}
void
MPI::File::Set_errhandler(const MPI::Errhandler& errhandler)
{
my_errhandler = (MPI::Errhandler *)&errhandler;
OPAL_THREAD_LOCK(MPI::mpi_map_mutex);
MPI::File::mpi_file_map[mpi_file] = this;
OPAL_THREAD_UNLOCK(MPI::mpi_map_mutex);
(void)MPI_File_set_errhandler(mpi_file, errhandler);
}
//
// Infrastructure for MPI_REGISTER_DATAREP
//
// Similar to what we have to do in the F77 bindings: call the C
// MPI_Register_datarep function with "intercept" callback functions
// that conform to the C bindings. In these intercepts, convert the
// arguments to C++ calling convertions, and then invoke the actual
// C++ callbacks.
// Data structure passed to the intercepts (see below). It is an OPAL
// list_item_t so that we can clean this memory up during
// MPI_FINALIZE.
typedef struct intercept_extra_state {
opal_list_item_t base;
MPI::Datarep_conversion_function *read_fn_cxx;
MPI::Datarep_conversion_function *write_fn_cxx;
MPI::Datarep_extent_function *extent_fn_cxx;
void *extra_state_cxx;
} intercept_extra_state_t;
static void intercept_extra_state_constructor(intercept_extra_state_t *obj)
{
obj->read_fn_cxx = NULL;
obj->write_fn_cxx = NULL;
obj->extent_fn_cxx = NULL;
obj->extra_state_cxx = NULL;
}
OBJ_CLASS_DECLARATION(intercept_extra_state_t);
OBJ_CLASS_INSTANCE(intercept_extra_state_t,
opal_list_item_t,
intercept_extra_state_constructor, NULL);
// Intercept function for read conversions
static int read_intercept_fn(void *userbuf, MPI_Datatype type_c, int count_c,
void *filebuf, MPI_Offset position_c,
void *extra_state)
{
MPI::Datatype type_cxx(type_c);
MPI::Offset position_cxx(position_c);
intercept_extra_state_t *intercept_data =
(intercept_extra_state_t*) extra_state;
intercept_data->read_fn_cxx(userbuf, type_cxx, count_c, filebuf,
position_cxx, intercept_data->extra_state_cxx);
return MPI_SUCCESS;
}
// Intercept function for write conversions
static int write_intercept_fn(void *userbuf, MPI_Datatype type_c, int count_c,
void *filebuf, MPI_Offset position_c,
void *extra_state)
{
MPI::Datatype type_cxx(type_c);
MPI::Offset position_cxx(position_c);
intercept_extra_state_t *intercept_data =
(intercept_extra_state_t*) extra_state;
intercept_data->write_fn_cxx(userbuf, type_cxx, count_c, filebuf,
position_cxx, intercept_data->extra_state_cxx);
return MPI_SUCCESS;
}
// Intercept function for extent calculations
static int extent_intercept_fn(MPI_Datatype type_c, MPI_Aint *file_extent_c,
void *extra_state)
{
MPI::Datatype type_cxx(type_c);
MPI::Aint file_extent_cxx(*file_extent_c);
intercept_extra_state_t *intercept_data =
(intercept_extra_state_t*) extra_state;
intercept_data->extent_fn_cxx(type_cxx, file_extent_cxx,
intercept_data->extra_state_cxx);
*file_extent_c = file_extent_cxx;
return MPI_SUCCESS;
}
// C++ bindings for MPI::Register_datarep
void
MPI::Register_datarep(const char* datarep,
Datarep_conversion_function* read_fn_cxx,
Datarep_conversion_function* write_fn_cxx,
Datarep_extent_function* extent_fn_cxx,
void* extra_state_cxx)
{
intercept_extra_state_t *intercept;
intercept = OBJ_NEW(intercept_extra_state_t);
if (NULL == intercept) {
OMPI_ERRHANDLER_INVOKE(MPI_FILE_NULL, OMPI_ERR_OUT_OF_RESOURCE,
"MPI::Register_datarep");
return;
}
opal_list_append(&ompi_registered_datareps, &(intercept->base));
intercept->read_fn_cxx = read_fn_cxx;
intercept->write_fn_cxx = write_fn_cxx;
intercept->extent_fn_cxx = extent_fn_cxx;
intercept->extra_state_cxx = extra_state_cxx;
(void)MPI_Register_datarep(const_cast<char*>(datarep), read_intercept_fn,
write_intercept_fn,
extent_intercept_fn, intercept);
}
void
MPI::Register_datarep(const char* datarep,
MPI_Datarep_conversion_function* read_fn_c,
Datarep_conversion_function* write_fn_cxx,
Datarep_extent_function* extent_fn_cxx,
void* extra_state_cxx)
{
intercept_extra_state_t *intercept;
intercept = OBJ_NEW(intercept_extra_state_t);
if (NULL == intercept) {
OMPI_ERRHANDLER_INVOKE(MPI_FILE_NULL, OMPI_ERR_OUT_OF_RESOURCE,
"MPI::Register_datarep");
return;
}
opal_list_append(&ompi_registered_datareps, &(intercept->base));
intercept->write_fn_cxx = write_fn_cxx;
intercept->extent_fn_cxx = extent_fn_cxx;
intercept->extra_state_cxx = extra_state_cxx;
(void)MPI_Register_datarep(const_cast<char*>(datarep), read_fn_c,
write_intercept_fn,
extent_intercept_fn, intercept);
}
void
MPI::Register_datarep(const char* datarep,
Datarep_conversion_function* read_fn_cxx,
MPI_Datarep_conversion_function* write_fn_c,
Datarep_extent_function* extent_fn_cxx,
void* extra_state_cxx)
{
intercept_extra_state_t *intercept;
intercept = OBJ_NEW(intercept_extra_state_t);
if (NULL == intercept) {
OMPI_ERRHANDLER_INVOKE(MPI_FILE_NULL, OMPI_ERR_OUT_OF_RESOURCE,
"MPI::Register_datarep");
return;
}
opal_list_append(&ompi_registered_datareps, &(intercept->base));
intercept->read_fn_cxx = read_fn_cxx;
intercept->extent_fn_cxx = extent_fn_cxx;
intercept->extra_state_cxx = extra_state_cxx;
(void)MPI_Register_datarep(const_cast<char*>(datarep), read_intercept_fn,
write_fn_c,
extent_intercept_fn, intercept);
}
void
MPI::Register_datarep(const char* datarep,
MPI_Datarep_conversion_function* read_fn_c,
MPI_Datarep_conversion_function* write_fn_c,
Datarep_extent_function* extent_fn_cxx,
void* extra_state_cxx)
{
intercept_extra_state_t *intercept;
intercept = OBJ_NEW(intercept_extra_state_t);
if (NULL == intercept) {
OMPI_ERRHANDLER_INVOKE(MPI_FILE_NULL, OMPI_ERR_OUT_OF_RESOURCE,
"MPI::Register_datarep");
return;
}
opal_list_append(&ompi_registered_datareps, &(intercept->base));
intercept->extent_fn_cxx = extent_fn_cxx;
intercept->extra_state_cxx = extra_state_cxx;
(void)MPI_Register_datarep(const_cast<char*>(datarep), read_fn_c,
write_fn_c,
extent_intercept_fn, intercept);
}