From f707ba2dd3675f9f6bc4cb576b3e60b568ce70f6 Mon Sep 17 00:00:00 2001 From: Brian Barrett Date: Tue, 9 Aug 2005 22:40:42 +0000 Subject: [PATCH] * Add memory dispatching code for OPAL. This allows anyone to register callbacks to be triggered when memory is about to leave the current process. The system is designed to allow a variety of interfaces, hopefully including whole-sale replacement of the memory manager, ld preload tricks, and hooks into the system memory manager. Since some of these may or may not be available at runtime and we won't know until runtime, there is a query funtion to look for availability of such a setup. * Added ptmalloc2 memory manager replacement code. Not turned on by default, can be enabled with --with-memory-manager=ptmalloc2. Only tested on Linux, not even compiled elsewhere. Do not use on OS X, or you will never see your process again. * Added AM_CONDITIONAL for threads test to support ptmalloc2's build system This commit was SVN r6790. --- acinclude.m4 | 1 + config/ompi_config_threads.m4 | 3 + config/ompi_setup_memory.m4 | 92 +++++++++++++++++++ configure.ac | 8 ++ include/ompi_config_bottom.h | 6 +- opal/Makefile.am | 1 + opal/memory/Makefile.am | 8 +- opal/memory/memory.c | 29 ++++-- opal/memory/memory.h | 4 +- opal/memory/memory_internal.h | 1 + opal/memory/ptmalloc2/Makefile.am | 64 +++++++++++++ opal/memory/ptmalloc2/arena.c | 7 ++ opal/memory/ptmalloc2/malloc.c | 60 +++++++++++- opal/memory/ptmalloc2/malloc.h | 3 + .../{COPYRIGHT => ptmalloc2-COPYRIGHT} | 0 opal/runtime/opal_finalize.c | 4 + opal/runtime/opal_init.c | 5 +- test/Makefile.am | 2 +- test/memory/Makefile.am | 29 ++++++ test/memory/opal_memory_basic.c | 62 +++++++++++++ 20 files changed, 375 insertions(+), 14 deletions(-) create mode 100644 config/ompi_setup_memory.m4 create mode 100644 opal/memory/ptmalloc2/Makefile.am rename opal/memory/ptmalloc2/{COPYRIGHT => ptmalloc2-COPYRIGHT} (100%) create mode 100644 test/memory/Makefile.am create mode 100644 test/memory/opal_memory_basic.c diff --git a/acinclude.m4 b/acinclude.m4 index 43c1b6f7d2..0969e80af6 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -75,6 +75,7 @@ m4_include(config/ompi_setup_cxx.m4) m4_include(config/ompi_setup_f77.m4) m4_include(config/ompi_setup_f90.m4) m4_include(config/ompi_setup_libevent.m4) +m4_include(config/ompi_setup_memory.m4) m4_include(config/ompi_check_pthread_pids.m4) m4_include(config/ompi_config_pthreads.m4) diff --git a/config/ompi_config_threads.m4 b/config/ompi_config_threads.m4 index a48e6da33a..ac48191c1e 100644 --- a/config/ompi_config_threads.m4 +++ b/config/ompi_config_threads.m4 @@ -172,6 +172,9 @@ EOF AC_MSG_ERROR(["*** Can not continue."]) fi +AM_CONDITIONAL(OMPI_HAVE_POSIX_THREADS, test "$thread_type" = "posix") +AM_CONDITIONAL(OMPI_HAVE_SOLARIS_THREADS, test "$thread_type" = "solaris") + # # Now configure the whole MPI and progress thread gorp # diff --git a/config/ompi_setup_memory.m4 b/config/ompi_setup_memory.m4 new file mode 100644 index 0000000000..61ffa795eb --- /dev/null +++ b/config/ompi_setup_memory.m4 @@ -0,0 +1,92 @@ +dnl +dnl Copyright (c) 2004-2005 The Trustees of Indiana University. +dnl All rights reserved. +dnl Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +dnl All rights reserved. +dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +dnl University of Stuttgart. All rights reserved. +dnl Copyright (c) 2004-2005 The Regents of the University of California. +dnl All rights reserved. +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ +dnl + +AC_DEFUN([OMPI_PTMALLOC_SETUP],[ +# +# Call the top-level OMPI threads setup stuff +# +OLD_CPPFLAGS="$CPPFLAGS" +OLD_LDFLAGS="$LDFLAGS" +OLD_LIBS="$LIBS" + +CPPFLAGS="$CPPFLAGS $THREADCPPFLAGS" +LDFLAGS="$LDFLAGS $THREADLDFLAGS" +LIBS="$LIBS $THREADLIBS" + +if test "`echo $host | grep apple-darwin`" != "" ; then + AC_MSG_WARN([*** Using ptmalloc with OS X will result in failure.]) + AC_MSG_ERROR([*** Aborting to save you the effort]) +fi + +# +# See if we have sbrk prototyped +# +AC_CHECK_DECL([sbrk], [have_decl_sbrk=1], [have_decl_sbrk=0]) +AC_DEFINE_UNQUOTED(OMPI_HAVE_DECL_SBRK, $have_decl_sbrk, + [Whether we have a declaration for sbrk() or not]) + +CPPFLAGS="$OLD_CPPFLAGS" +LDFLAGS="$OLD_LDFLAGS" +LIBS="$OLD_LIBS" +])dnl + + +AC_DEFUN([OMPI_DARWIN_MALLOC_SETUP],[ +case "$host" in + *apple-darwin*) + WRAPPER_EXTRA_LDFLAGS="-Wl,-u -Wl,_ompi_darwin_malloc_linker_hack -Wl,-multiply_defined,suppress -Wl,-force_flat_namespace -Wl,-flat_namespace $WRAPPER_EXTRA_LDFLAGS" + LDFLAGS="-Wl,-multiply_defined,suppress $LDFLAGS" + ;; + *) + AC_MSG_ERROR([Trying to use Darwin malloc while not on a Darwin system.]) + ;; +esac +])dnl + +AC_DEFUN([OMPI_MEMORY_SETUP],[ + +AC_ARG_WITH(memory-manager, + AC_HELP_STRING([--with-memory-manager=TYPE], + [Use TYPE for intercepting memory management calls to control memory pinning (TYPE is one of ptmalloc2,none)]), + [WANT_MEMORY="$withval"], [WANT_MEMORY="none"]) + +AC_MSG_CHECKING([for memory management type]) +if test "$WANT_MEMORY" = "darwin" ; then + AC_MSG_RESULT([Darwin / Mac OS X]) + OMPI_DARWIN_MALLOC_SETUP + OMPI_WANT_DARWIN7MALLOC=1 + OMPI_WANT_PTMALLOC2=0 + AC_MSG_ERROR([Darwin memory manager not currently supported]) +elif test "$WANT_MEMORY" = "ptmalloc2" ; then + AC_MSG_RESULT([ptmalloc2]) + OMPI_PTMALLOC_SETUP + OMPI_WANT_DARWIN7MALLOC=0 + OMPI_WANT_PTMALLOC2=1 +else + AC_MSG_RESULT([none]) + OMPI_WANT_DARWIN7MALLOC=0 + OMPI_WANT_PTMALLOC2=0 +fi + +AC_DEFINE_UNQUOTED([OMPI_WANT_PTMALLOC2], $OMPI_WANT_PTMALLOC2, + [Do we want ptmalloc2 support]) +AM_CONDITIONAL(OMPI_WANT_PTMALLOC2, test "$OMPI_WANT_PTMALLOC2" = "1") + +AC_DEFINE_UNQUOTED([OMPI_WANT_DARWIN7MALLOC], $OMPI_WANT_DARWIN7MALLOC, + [Do we want darwin7malloc support]) +AM_CONDITIONAL(OMPI_WANT_DARWIN7MALLOC, test "$OMPI_WANT_DARWIN7MALLOC" = "1") + +])dnl diff --git a/configure.ac b/configure.ac index 77452c5642..122e12301c 100644 --- a/configure.ac +++ b/configure.ac @@ -1338,6 +1338,11 @@ OMPI_CASE_SENSITIVE_FS_SETUP # AIX: FIONBIO in sys/ioctl.h # glibc: memcpy +# +# memory manager hooks +# +OMPI_MEMORY_SETUP + # checkpoint results AC_CACHE_SAVE @@ -1609,6 +1614,8 @@ AC_CONFIG_FILES([ opal/event/Makefile opal/event/compat/Makefile opal/event/compat/sys/Makefile + opal/memory/Makefile + opal/memory/ptmalloc2/Makefile opal/runtime/Makefile opal/threads/Makefile opal/util/Makefile @@ -1680,6 +1687,7 @@ AC_CONFIG_FILES([ test/mca/rds/Makefile test/mca/rmaps/Makefile test/mca/schema/Makefile + test/memory/Makefile test/runtime/Makefile test/support/Makefile test/threads/Makefile diff --git a/include/ompi_config_bottom.h b/include/ompi_config_bottom.h index 7737e40fac..99f06a8304 100644 --- a/include/ompi_config_bottom.h +++ b/include/ompi_config_bottom.h @@ -243,8 +243,12 @@ typedef long long bool; * include , which includes , but after * setting OMPI_BUILDING to 0 For 3, it's the same as 1 -- just include * first. + * + * Give code that needs to include ompi_config.h but really can't have + * this stuff enabled (like the memory manager code) a way to turn us + * off */ -#if OMPI_ENABLE_MEM_DEBUG +#if OMPI_ENABLE_MEM_DEBUG && !defined(OMPI_DISABLE_ENABLE_MEM_DEBUG) /* It is safe to include opal/util/malloc.h here because a) it will only happen when we are building OMPI and therefore have a full OMPI diff --git a/opal/Makefile.am b/opal/Makefile.am index 16206fe0eb..8a1edf21f2 100644 --- a/opal/Makefile.am +++ b/opal/Makefile.am @@ -37,6 +37,7 @@ libopal_la_LIBADD = \ class/libclass.la \ event/libevent.la \ mca/base/libmca_base.la \ + memory/libopalmemory.la \ runtime/libruntime.la \ threads/libthreads.la \ util/libopalutil.la diff --git a/opal/memory/Makefile.am b/opal/memory/Makefile.am index 5ad66c27c7..2476bc07ae 100644 --- a/opal/memory/Makefile.am +++ b/opal/memory/Makefile.am @@ -18,16 +18,22 @@ include $(top_srcdir)/config/Makefile.options noinst_LTLIBRARIES = libopalmemory.la +SUBDIRS = ptmalloc2 + # Source code files headers = \ memory.h \ memory_internal.h -libopalutil_la_SOURCES = \ +libopalmemory_la_SOURCES = \ $(headers) \ memory.c +if OMPI_WANT_PTMALLOC2 +libopalmemory_la_LIBADD = ptmalloc2/libptmalloc2.la +endif + # Conditionally install the header files if WANT_INSTALL_HEADERS diff --git a/opal/memory/memory.c b/opal/memory/memory.c index 6b77317ce9..1f29990dac 100644 --- a/opal/memory/memory.c +++ b/opal/memory/memory.c @@ -20,6 +20,7 @@ #include "opal/memory/memory.h" #include "opal/memory/memory_internal.h" #include "opal/class/opal_list.h" +#include "opal/class/opal_object.h" /* @@ -27,24 +28,27 @@ */ struct callback_list_item_t { opal_list_item_t super; - opal_mem_free_unpin_fn_t cbfunc; + opal_mem_free_unpin_fn_t *cbfunc; void *cbdata; }; typedef struct callback_list_item_t callback_list_item_t; -static OBJ_CLASS_INSTANCE(callback_list_item_t opal_list_item_t, NULL, NULL); +static OBJ_CLASS_INSTANCE(callback_list_item_t, opal_list_item_t, NULL, NULL); /* * local data */ static opal_list_t callback_list; static opal_atomic_lock_t callback_lock; -static bool have_free_support; +static bool have_free_support = false; + int opal_mem_free_init(void) { - OBJ_DECLARATION(&callback_list, opal_list_t); + OBJ_CONSTRUCT(&callback_list, opal_list_t); opal_atomic_init(&callback_lock, OPAL_ATOMIC_UNLOCKED); + + return OMPI_SUCCESS; } @@ -57,6 +61,17 @@ opal_mem_free_finalize(void) OBJ_RELEASE(item); } OBJ_DESTRUCT(&callback_list); + + return OMPI_SUCCESS; +} + + +/* called from memory manager / memory-manager specific hooks */ +void +opal_mem_free_set_free_support(bool support) +{ + printf("someone set mem_free support to %d\n", (int) support); + have_free_support = support; } @@ -88,7 +103,7 @@ opal_mem_free_is_supported(void) int -opal_mem_free_register_handler(opal_memory_unpin_t *func, void *cbdata) +opal_mem_free_register_handler(opal_mem_free_unpin_fn_t *func, void *cbdata) { opal_list_item_t *item; callback_list_item_t *cbitem; @@ -119,7 +134,7 @@ opal_mem_free_register_handler(opal_memory_unpin_t *func, void *cbdata) cbitem->cbfunc = func; cbitem->cbdata = cbdata; - opal_list_appemd(&callback_list, (opal_list_item_t*) cbitem); + opal_list_append(&callback_list, (opal_list_item_t*) cbitem); done: opal_atomic_unlock(&callback_lock); @@ -129,7 +144,7 @@ opal_mem_free_register_handler(opal_memory_unpin_t *func, void *cbdata) int -opal_mem_free_unregister_handler(opal_memory_unpin_t *func) +opal_mem_free_unregister_handler(opal_mem_free_unpin_fn_t *func) { opal_list_item_t *item; callback_list_item_t *cbitem; diff --git a/opal/memory/memory.h b/opal/memory/memory.h index 56ae63b9f1..1b0c3df4dd 100644 --- a/opal/memory/memory.h +++ b/opal/memory/memory.h @@ -88,7 +88,7 @@ bool opal_mem_free_is_supported(void); * @retval OMPI_ERR_NOT_SUPPORTED There are no hooks available for * receiving callbacks when memory is to be released */ -int opal_mem_free_register_handler(opal_memory_unpin_t *func, void *cbdata); +int opal_mem_free_register_handler(opal_mem_free_unpin_fn_t *func, void *cbdata); /** @@ -101,6 +101,6 @@ int opal_mem_free_register_handler(opal_memory_unpin_t *func, void *cbdata); * @retval OMPI_SUCCESS The function was successfully deregistered * @retval OMPI_ERR_NOT_FOUND The function was not previously registered */ -int opal_mem_free_unregister_handler(opal_memory_unpin_t *func); +int opal_mem_free_unregister_handler(opal_mem_free_unpin_fn_t *func); #endif /* OPAL_MEMORY_MEMORY_H */ diff --git a/opal/memory/memory_internal.h b/opal/memory/memory_internal.h index db4800f942..3738bf83bf 100644 --- a/opal/memory/memory_internal.h +++ b/opal/memory/memory_internal.h @@ -17,6 +17,7 @@ #ifndef OPAL_MEMORY_MEMORY_INTERNAL_H #define OPAL_MEMORY_MEMORY_INTERNAL_H +void opal_mem_free_set_free_support(bool support); void opal_mem_free_release_hook(void *buf, size_t length); #endif /* OPAL_MEMORY_MEMORY_INTERNAL_H */ diff --git a/opal/memory/ptmalloc2/Makefile.am b/opal/memory/ptmalloc2/Makefile.am new file mode 100644 index 0000000000..ec5c561e96 --- /dev/null +++ b/opal/memory/ptmalloc2/Makefile.am @@ -0,0 +1,64 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University. +# All rights reserved. +# Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +# All rights reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +include $(top_srcdir)/config/Makefile.options + +AM_CPPFLAGS = -DMALLOC_DEBUG=0 + +if OMPI_HAVE_POSIX_THREADS +AM_CPPFLAGS += -DUSE_TSD_DATA_HACK \ + -Isysdeps/pthread +endif +if OMPI_HAVE_SOLARIS_THREADS +AM_CPPFLAGS += -Isysdeps/solaris +endif +# this must come *after* the threads -Is +AM_CPPFLAGS += -Isysdeps/generic + +# ptmalloc requires us to include the copyright notice in the +# software. So install it in the same place that we install ROMIO's +# copyright notices. + +docdir = $(datadir)/openmpi/doc +doc_DATA = ptmalloc2-COPYRIGHT + +if OMPI_WANT_PTMALLOC2 +noinst_LTLIBRARIES = libptmalloc2.la +endif + +libptmalloc2_la_SOURCES = \ + malloc.c \ + malloc-stats.c \ + malloc.h \ + thread-m.h \ + thread-st.h + +# these are included directly and shouldn't be built solo +EXTRA_libptmalloc2_la_SOURCES = \ + arena.c \ + hooks.c + +EXTRA_DIST = \ + ChangeLog \ + README \ + ChangeLog \ + lran2.h \ + t-test.h \ + t-test1.c \ + t-test2.c \ + tst-mallocstate.c \ + sysdeps \ + $(doc_DATA) diff --git a/opal/memory/ptmalloc2/arena.c b/opal/memory/ptmalloc2/arena.c index 66aa52c27f..698709a4ec 100644 --- a/opal/memory/ptmalloc2/arena.c +++ b/opal/memory/ptmalloc2/arena.c @@ -464,6 +464,13 @@ ptmalloc_init __MALLOC_P((void)) } if(__malloc_initialize_hook != NULL) (*__malloc_initialize_hook)(); + +/********************** BEGIN OMPI CHANGES *****************************/ + /* don't use __hook for this, as someone might want to use those + features */ + opal_mem_free_set_free_support(true); +/********************* BEGIN OMPI CHANGES ******************************/ + __malloc_initialized = 1; } diff --git a/opal/memory/ptmalloc2/malloc.c b/opal/memory/ptmalloc2/malloc.c index ce91eecf75..b462b1a52c 100644 --- a/opal/memory/ptmalloc2/malloc.c +++ b/opal/memory/ptmalloc2/malloc.c @@ -1,3 +1,61 @@ +/********************** BEGIN OMPI CHANGES *****************************/ +#define OMPI_DISABLE_ENABLE_MEM_DEBUG 1 +#include "ompi_config.h" + +#include +#include +#include +#include + +#include "opal/memory/memory_internal.h" + +/* + * Not all systems have sbrk() declared, since it's technically not a + * POSIX function. + */ +#if !OMPI_HAVE_DECL_SBRK +void *sbrk(); +#endif + +static void* +opal_mem_free_ptmalloc2_sbrk(int inc) +{ + if (inc < 0) { + long oldp = (long) sbrk(0); + opal_mem_free_release_hook((void*) (oldp + inc), -inc); + } + + return sbrk(inc); +} + +static int +opal_mem_free_ptmalloc2_munmap(void *start, size_t length) +{ + opal_mem_free_release_hook(start, length); + return munmap(start, length); +} + +#define MORECORE opal_mem_free_ptmalloc2_sbrk +#define munmap(a,b) opal_mem_free_ptmalloc2_munmap(a,b) +/* easier to just not use mremap - having it makes tracking more + difficult */ +#define HAVE_MREMAP 0 +/* set the threshold for switching from sbrk heap to mmap higher than + normal so that there are more things in the heap. mmap segments + are never reused, so this keeps the number of calls to munmap and + sbrk down significantly */ +#define DEFAULT_MMAP_THRESHOLD (2*1024*1024) + +/* make some non-GCC compilers happy */ +#ifndef __GNUC__ +#define __const const +#endif + +/********************* BEGIN OMPI CHANGES ******************************/ + + + + /* Malloc implementation for multiple threads without lock contention. Copyright (C) 1996-2002, 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -852,7 +910,7 @@ Void_t* public_mALLOc(); #ifdef libc_hidden_proto libc_hidden_proto (public_mALLOc) #endif - + static void here(void); /* free(Void_t* p) Releases the chunk of memory pointed to by p, that had been previously diff --git a/opal/memory/ptmalloc2/malloc.h b/opal/memory/ptmalloc2/malloc.h index 1d486dc7b8..6d714d4bca 100644 --- a/opal/memory/ptmalloc2/malloc.h +++ b/opal/memory/ptmalloc2/malloc.h @@ -69,6 +69,9 @@ # if defined __cplusplus && (__GNUC__ >= 3 || __GNUC_MINOR__ >= 8) # define __THROW throw () # else +#ifdef __THROW +# undef __THROW +#endif # define __THROW # endif # define __MALLOC_P(args) args __THROW diff --git a/opal/memory/ptmalloc2/COPYRIGHT b/opal/memory/ptmalloc2/ptmalloc2-COPYRIGHT similarity index 100% rename from opal/memory/ptmalloc2/COPYRIGHT rename to opal/memory/ptmalloc2/ptmalloc2-COPYRIGHT diff --git a/opal/runtime/opal_finalize.c b/opal/runtime/opal_finalize.c index 55007a52e8..dc1fbf1dfd 100644 --- a/opal/runtime/opal_finalize.c +++ b/opal/runtime/opal_finalize.c @@ -22,6 +22,7 @@ #include "opal/class/opal_object.h" #include "opal/util/output.h" #include "opal/util/malloc.h" +#include "opal/memory/memory.h" #include "mca/base/base.h" #include "runtime/opal.h" @@ -41,6 +42,9 @@ int opal_finalize(void) /* finalize the output system */ opal_output_finalize(); + + /* finalize the memory manager / tracker */ + opal_mem_free_finalize(); /* finalize the class/object system */ opal_class_finalize(); diff --git a/opal/runtime/opal_init.c b/opal/runtime/opal_init.c index 2db01a71c0..11409c50e0 100644 --- a/opal/runtime/opal_init.c +++ b/opal/runtime/opal_init.c @@ -21,6 +21,7 @@ #include "include/orte_constants.h" #include "opal/util/malloc.h" #include "opal/util/output.h" +#include "opal/memory/memory.h" #include "mca/base/base.h" #include "runtime/opal.h" @@ -35,10 +36,12 @@ */ int opal_init(void) { - /* initialize the memory allocator */ opal_malloc_init(); + /* initialize the memory manager / tracker */ + opal_mem_free_init(); + /* initialize the output system */ opal_output_init(); diff --git a/test/Makefile.am b/test/Makefile.am index 338abeba41..922f749a74 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -17,4 +17,4 @@ include $(top_srcdir)/test/support/Makefile.options # support needs to be first for dependencies -SUBDIRS = support asm class dps mca runtime threads util +SUBDIRS = support asm class dps mca memory runtime threads util diff --git a/test/memory/Makefile.am b/test/memory/Makefile.am new file mode 100644 index 0000000000..18960b378b --- /dev/null +++ b/test/memory/Makefile.am @@ -0,0 +1,29 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University. +# All rights reserved. +# Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +# All rights reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +include $(top_srcdir)/test/support/Makefile.options + +check_PROGRAMS = \ + opal_memory_basic + +TESTS = \ + $(check_PROGRAMS) + +opal_memory_basic_SOURCES = opal_memory_basic.c +opal_memory_basic_LDADD = \ + $(top_builddir)/opal/libopal.la \ + $(top_builddir)/test/support/libsupport.a +opal_memory_basic_DEPENDENCIES = $(opal_memory_basic_LDADD) diff --git a/test/memory/opal_memory_basic.c b/test/memory/opal_memory_basic.c new file mode 100644 index 0000000000..318fa0ab8f --- /dev/null +++ b/test/memory/opal_memory_basic.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University. + * All rights reserved. + * Copyright (c) 2004-2005 The Trustees of the University of Tennessee. + * All rights reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "ompi_config.h" + +#include +#include + +#include "ompi/include/constants.h" +#include "opal/runtime/opal.h" +#include "opal/memory/memory.h" + +int ret = 1; +int size = 10 * 1024 * 1024; + +static void +callback(void *buf, size_t length, void *cbdata) +{ + printf("\tcallback with %lx, %d\n", (unsigned long) buf, (int) length); + ret = 0; +} + +int +main(int argc, char *argv[]) +{ + void * foo; + int retval; + + opal_init(); + + if (!opal_mem_free_is_supported()) { + printf("no memory registration supported. skipping\n"); + return 77; + } + + retval = opal_mem_free_register_handler(callback, NULL); + if (retval != OMPI_SUCCESS) return retval; + + /* make some big malloc that should trip an unmap */ + foo = malloc(size); + free(foo); + + retval = opal_mem_free_unregister_handler(callback); + if (retval != OMPI_SUCCESS) return retval; + + opal_finalize(); + + return ret; +}