opal: add a destructor/fini function to opal
This commit is related to an RFC from June 2014. Disscussion can be found at: http://www.open-mpi.org/community/lists/devel/2014/07/15140.php The finalize function is set using either the linker option -fini or __attribute__((destructor)) depending on compiler support. I have confirmed that this hybrid approach works with all the major compilers. The attribute is supported by gcc, clang, llvm, xlc, and icc. The fini function will support pgi. If a compiler/linker combination does not support either the destructor or fini function a message will be printed on re-init indicating it is not supported (an improvement over the current behavior-- SEGV). I moved the following to the destructor function: - Class system finalize. This solves a bug when MPI_T_finalize is called before MPI_Init. The only downside to this change is we will leave the footprint of the opal class system after MPI_Finalize. This footprint should be relatively small. This is an alternative to #517 but the two PRs are not mutually-exclusive (with some modifications). This commit should also be safe for 1.8.x as it does not change internal or external ABI (#517 changes internal ABI). Signed-off-by: Nathan Hjelm <hjelmn@lanl.gov>
Этот коммит содержится в:
родитель
f8158a5ec1
Коммит
38589c46c0
@ -608,4 +608,5 @@ AC_DEFUN([OPAL_CHECK_ATTRIBUTES], [
|
||||
[Whether your compiler has __attribute__ weak alias or not])
|
||||
AC_DEFINE_UNQUOTED(OPAL_HAVE_ATTRIBUTE_DESTRUCTOR, [$opal_cv___attribute__destructor],
|
||||
[Whether your compiler has __attribute__ destructor or not])
|
||||
AM_CONDITIONAL(HAVE_ATTRIBUTE_DESTRUCTOR, [test x$opal_cv___attribute__destructor = x1])
|
||||
])
|
||||
|
14
configure.ac
14
configure.ac
@ -799,6 +799,20 @@ m4_ifdef([project_ompi], [OMPI_FIND_MPI_AINT_COUNT_OFFSET])
|
||||
# checkpoint results
|
||||
AC_CACHE_SAVE
|
||||
|
||||
##################################
|
||||
# Linker characteristics
|
||||
##################################
|
||||
|
||||
AC_MSG_CHECKING([the linker for support for the -fini option])
|
||||
LDFLAGS_save=$LDFLAGS
|
||||
LDFLAGS="$LDFLAGS_save -Wl,-fini -Wl,finalize"
|
||||
AC_TRY_LINK([void finalize (void) {}], [], [AC_MSG_RESULT([yes])
|
||||
opal_ld_fini=1], [AC_MSG_RESULT([no])
|
||||
opal_ld_fini=0])
|
||||
AM_CONDITIONAL(HAVE_LD_FINI, [test x$opal_ld_fini = x1])
|
||||
AC_DEFINE_UNQUOTED(OPAL_HAVE_LD_FINI, [$opal_ld_fini],
|
||||
[Whether linker has support for the -fini option])
|
||||
LDFLAGS=$LDFLAGS_save
|
||||
|
||||
##################################
|
||||
# Libraries
|
||||
|
@ -53,8 +53,19 @@ lib@OPAL_LIB_PREFIX@open_pal_la_LIBADD = \
|
||||
util/libopalutil.la \
|
||||
$(MCA_opal_FRAMEWORK_LIBS)
|
||||
lib@OPAL_LIB_PREFIX@open_pal_la_DEPENDENCIES = $(lib@OPAL_LIB_PREFIX@open_pal_la_LIBADD)
|
||||
|
||||
if HAVE_ATTRIBUTE_DESTRUCTOR
|
||||
|
||||
lib@OPAL_LIB_PREFIX@open_pal_la_LDFLAGS = -version-info $(libopen_pal_so_version)
|
||||
|
||||
else
|
||||
if HAVE_LD_FINI
|
||||
|
||||
lib@OPAL_LIB_PREFIX@open_pal_la_LDFLAGS = -version-info $(libopen_pal_so_version) -Wl,-fini,opal_cleanup
|
||||
|
||||
endif
|
||||
endif
|
||||
|
||||
# included subdirectory Makefile.am's and appended-to variables
|
||||
headers =
|
||||
noinst_LTLIBRARIES =
|
||||
|
@ -57,6 +57,18 @@
|
||||
|
||||
extern int opal_initialized;
|
||||
extern int opal_util_initialized;
|
||||
extern bool opal_init_called;
|
||||
|
||||
static void __opal_attribute_destructor__ opal_cleanup (void)
|
||||
{
|
||||
if (!opal_initialized) {
|
||||
/* nothing to do */
|
||||
return;
|
||||
}
|
||||
|
||||
/* finalize the class/object system */
|
||||
opal_class_finalize();
|
||||
}
|
||||
|
||||
int
|
||||
opal_finalize_util(void)
|
||||
@ -101,8 +113,9 @@ opal_finalize_util(void)
|
||||
|
||||
opal_datatype_finalize();
|
||||
|
||||
/* finalize the class/object system */
|
||||
opal_class_finalize();
|
||||
#if !(OPAL_HAVE_LD_FINI || OPAL_HAVE_ATTRIBUTE_DESTRUCTOR)
|
||||
opal_cleanup ();
|
||||
#endif
|
||||
|
||||
free (opal_process_info.nodename);
|
||||
opal_process_info.nodename = NULL;
|
||||
|
@ -74,6 +74,7 @@
|
||||
const char opal_version_string[] = OPAL_IDENT_STRING;
|
||||
|
||||
int opal_initialized = 0;
|
||||
bool opal_init_called = false;
|
||||
int opal_util_initialized = 0;
|
||||
/* We have to put a guess in here in case hwloc is not available. If
|
||||
hwloc is available, this value will be overwritten when the
|
||||
@ -266,6 +267,18 @@ opal_init_util(int* pargc, char*** pargv)
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
#if !(OPAL_HAVE_LD_FINI || OPAL_HAVE_ATTRIBUTE_DESTRUCTOR)
|
||||
if (opal_init_called) {
|
||||
/* can't use show_help here */
|
||||
fprintf (stderr, "opal_init_util: attempted to initialize after finalize without compiler "
|
||||
"support for either __attribute__(destructor) or linker support for -fini -- process "
|
||||
"will likely abort\n");
|
||||
return OPAL_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
opal_init_called = true;
|
||||
|
||||
/* set the nodename right away so anyone who needs it has it. Note
|
||||
* that we don't bother with fqdn and prefix issues here - we let
|
||||
* the RTE later replace this with a modified name if the user
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user