1
1

* 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.
Этот коммит содержится в:
Brian Barrett 2005-08-09 22:40:42 +00:00
родитель ef1abb71d3
Коммит f707ba2dd3
20 изменённых файлов: 375 добавлений и 14 удалений

Просмотреть файл

@ -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)

Просмотреть файл

@ -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
#

92
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

Просмотреть файл

@ -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

Просмотреть файл

@ -243,8 +243,12 @@ typedef long long bool;
* include <mpi.h>, which includes <ompi_config.h>, but after
* setting OMPI_BUILDING to 0 For 3, it's the same as 1 -- just include
* <ompi_config.h> 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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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;

Просмотреть файл

@ -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 */

Просмотреть файл

@ -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 */

64
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)

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -1,3 +1,61 @@
/********************** BEGIN OMPI CHANGES *****************************/
#define OMPI_DISABLE_ENABLE_MEM_DEBUG 1
#include "ompi_config.h"
#include <unistd.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#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

Просмотреть файл

@ -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

Просмотреть файл

@ -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();

Просмотреть файл

@ -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();

Просмотреть файл

@ -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

29
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)

62
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 <stdlib.h>
#include <stdio.h>
#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;
}