1
1
openmpi/src/file/file.c

298 строки
7.2 KiB
C
Исходник Обычный вид История

/*
* $HEADER$
*/
#include "ompi_config.h"
#include "file/file.h"
#include "class/ompi_list.h"
#include "mpi/runtime/params.h"
#include "mca/io/base/base.h"
/*
* Table for Fortran <-> C file handle conversion
*/
ompi_pointer_array_t ompi_file_f_to_c_table;
/*
* MPI_FILE_NULL
*/
ompi_file_t ompi_mpi_file_null;
/*
* Local functions
*/
static void file_constructor(ompi_file_t *obj);
static void file_destructor(ompi_file_t *obj);
/*
* Class instance for ompi_file_t
*/
OBJ_CLASS_INSTANCE(ompi_file_t,
ompi_object_t,
file_constructor,
file_destructor);
/*
* Initialize file handling bookeeping
*/
int ompi_file_init(void)
{
/* Setup file array */
OBJ_CONSTRUCT(&ompi_file_f_to_c_table, ompi_pointer_array_t);
/* Setup MPI_FILE_NULL. Note that it will have the default error
handler of MPI_ERRORS_RETURN, per MPI-2:9.7 (p265). */
OBJ_CONSTRUCT(&ompi_mpi_file_null, ompi_file_t);
ompi_mpi_file_null.f_comm = &ompi_mpi_comm_null;
OBJ_RETAIN(ompi_mpi_file_null.f_comm);
ompi_mpi_file_null.f_f_to_c_index = 0;
ompi_pointer_array_set_item(&ompi_file_f_to_c_table, 0,
&ompi_mpi_file_null);
/* All done */
return OMPI_SUCCESS;
}
/*
* Back end to MPI_FILE_OPEN
*/
int ompi_file_open(ompi_communicator_t *comm, char *filename,
int amode, ompi_info_t *info, ompi_file_t **fh)
{
int ret;
ompi_file_t *file;
/* JMS: This is problematic -- need this to be as large as ROMIO
needs to to be, or we need an additional pointer to hang stuff
off :-( */
file = OBJ_NEW(ompi_file_t);
if (NULL == file) {
return OMPI_ERR_OUT_OF_RESOURCE;
}
/* Save the params */
file->f_comm = comm;
OBJ_RETAIN(comm);
if (MPI_INFO_NULL != info) {
if (OMPI_SUCCESS != (ret = ompi_info_dup(info, &file->f_info))) {
OBJ_RELEASE(file);
return ret;
}
} else {
file->f_info = MPI_INFO_NULL;
OBJ_RETAIN(MPI_INFO_NULL);
}
file->f_amode = amode;
file->f_filename = strdup(filename);
if (NULL == file->f_filename) {
OBJ_RELEASE(file);
return OMPI_ERR_OUT_OF_RESOURCE;
}
/* Select a module and actually open the file */
if (OMPI_SUCCESS != (ret = mca_io_base_file_select(file, NULL))) {
OBJ_RELEASE(file);
return ret;
}
/* All done */
*fh = file;
return OMPI_SUCCESS;
}
/*
* Back end to MPI_FILE_CLOSE.
*/
int ompi_file_close(ompi_file_t **file)
{
(*file)->f_flags |= OMPI_FILE_ISCLOSED;
OBJ_RELEASE(*file);
*file = MPI_FILE_NULL;
return OMPI_SUCCESS;
}
/*
* Shut down the MPI_File bookkeeping
*/
int ompi_file_finalize(void)
{
size_t i, max;
size_t num_unnamed;
ompi_file_t *file;
/* Release MPI_FILE_NULL. Do this so that we don't get a bogus leak
report on it. Plus, it's statically allocated, so we don't want
to call OBJ_RELEASE on it. */
OBJ_DESTRUCT(&ompi_mpi_file_null);
ompi_pointer_array_set_item(&ompi_file_f_to_c_table, 0, NULL);
/* Iterate through all the file handles and destroy them. Note
that this also takes care of destroying MPI_FILE_NULL. */
max = ompi_pointer_array_get_size(&ompi_file_f_to_c_table);
for (num_unnamed = i = 0; i < max; ++i) {
file = (ompi_file_t *)ompi_pointer_array_get_item(&ompi_file_f_to_c_table, i);
/* If the file was closed but still exists because the user
told us to never free handles, then do an OBJ_RELEASE it
and all is well. Then get the value again and see if it's
actually been freed. */
if (NULL != file && ompi_debug_no_free_handles &&
0 == (file->f_flags & OMPI_FILE_ISCLOSED)) {
OBJ_RELEASE(file);
file = (ompi_file_t *)ompi_pointer_array_get_item(&ompi_file_f_to_c_table, i);
}
if (NULL != file) {
/* If the user wanted warnings about MPI object leaks,
print out a message */
if (ompi_debug_show_handle_leaks) {
++num_unnamed;
}
OBJ_RELEASE(file);
}
/* Don't bother setting each element back down to NULL; it
would just take a lot of thread locks / unlocks and since
we're destroying everything, it isn't worth it */
}
if (num_unnamed > 0) {
ompi_output(0, "WANRING: %d unnamed MPI_File handles still allocated at MPI_FINALIZE", num_unnamed);
}
OBJ_DESTRUCT(&ompi_file_f_to_c_table);
/* All done */
return OMPI_SUCCESS;
}
/*
* Constructor
*/
static void file_constructor(ompi_file_t *file)
{
/* Initialize the MPI_FILE_OPEN params */
file->f_comm = NULL;
file->f_filename = NULL;
file->f_amode = 0;
file->f_info = NULL;
/* Initialize flags */
file->f_flags = 0;
/* Initialize the fortran <--> C translation index */
file->f_f_to_c_index = ompi_pointer_array_add(&ompi_file_f_to_c_table,
file);
/* Initialize the error handler. Per MPI-2:9.7 (p265), the
default error handler on file handles is the error handler on
MPI_FILE_NULL, which starts out as MPI_ERRORS_RETURN (but can
be changed by invoking MPI_FILE_SET_ERRHANDLER on
MPI_FILE_NULL). */
file->errhandler_type = OMPI_ERRHANDLER_TYPE_FILE;
if (file != &ompi_mpi_file_null) {
file->error_handler = ompi_mpi_file_null.error_handler;
} else {
file->error_handler = &ompi_mpi_errors_return;
}
OBJ_RETAIN(file->error_handler);
/* Initialize the module */
file->f_io_version = MCA_IO_BASE_V_NONE;
memset(&(file->f_io_selected_module), 0,
sizeof(file->f_io_selected_module));
file->f_io_selected_data = NULL;
/* If the user doesn't want us to ever free it, then add an extra
RETAIN here */
if (ompi_debug_no_free_handles) {
OBJ_RETAIN(&(file->super));
}
}
/*
* Destructor
*/
static void file_destructor(ompi_file_t *file)
{
/* Finalize the module */
switch (file->f_io_version) {
case MCA_IO_BASE_V_1_0_0:
file->f_io_selected_module.v1_0_0.io_module_file_close(file);
break;
default:
/* Should never get here */
break;
}
/* Finalize the data members */
if (NULL != file->f_comm) {
OBJ_RELEASE(file->f_comm);
#if OMPI_ENABLE_DEBUG
file->f_comm = NULL;
#endif
}
if (NULL != file->f_filename) {
free(file->f_filename);
#if OMPI_ENABLE_DEBUG
file->f_filename = NULL;
#endif
}
if (NULL != file->error_handler) {
OBJ_RELEASE(file->error_handler);
#if OMPI_ENABLE_DEBUG
file->error_handler = NULL;
#endif
}
if (NULL != file->f_info) {
OBJ_RELEASE(file->f_info);
#if OMPI_ENABLE_DEBUG
file->f_info = NULL;
#endif
}
/* Reset the f_to_c table entry */
if (MPI_UNDEFINED != file->f_f_to_c_index &&
NULL != ompi_pointer_array_get_item(&ompi_file_f_to_c_table,
file->f_f_to_c_index)) {
ompi_pointer_array_set_item(&ompi_file_f_to_c_table,
file->f_f_to_c_index, NULL);
}
}